diff --git a/.github/renovate.json b/.github/renovate.json
index 22d5b782914c..714baad8e159 100644
--- a/.github/renovate.json
+++ b/.github/renovate.json
@@ -63,8 +63,7 @@
"Azure.Storage.Blobs",
"Azure.Storage.Queues",
"Fido2.AspNet",
- "IdentityServer4",
- "IdentityServer4.AccessTokenValidation",
+ "Duende.IdentityServer",
"Microsoft.Azure.Cosmos",
"Microsoft.Azure.Cosmos.Table",
"Microsoft.Extensions.Caching.StackExchangeRedis",
diff --git a/src/Core/Auth/Entities/Grant.cs b/src/Core/Auth/Entities/Grant.cs
index 96b2e9e65698..7b2522fc7145 100644
--- a/src/Core/Auth/Entities/Grant.cs
+++ b/src/Core/Auth/Entities/Grant.cs
@@ -1,23 +1,25 @@
-using System.ComponentModel.DataAnnotations;
+#nullable enable
+using System.ComponentModel.DataAnnotations;
namespace Bit.Core.Auth.Entities;
public class Grant
{
+ public int Id { get; set; }
[MaxLength(200)]
- public string Key { get; set; }
+ public string Key { get; set; } = null!;
[MaxLength(50)]
- public string Type { get; set; }
+ public string Type { get; set; } = null!;
[MaxLength(200)]
- public string SubjectId { get; set; }
+ public string? SubjectId { get; set; }
[MaxLength(100)]
- public string SessionId { get; set; }
+ public string? SessionId { get; set; }
[MaxLength(200)]
- public string ClientId { get; set; }
+ public string ClientId { get; set; } = null!;
[MaxLength(200)]
- public string Description { get; set; }
- public DateTime CreationDate { get; set; }
+ public string? Description { get; set; }
+ public DateTime CreationDate { get; set; } = DateTime.UtcNow;
public DateTime? ExpirationDate { get; set; }
public DateTime? ConsumedDate { get; set; }
- public string Data { get; set; }
+ public string Data { get; set; } = null!;
}
diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj
index cdf7d9e1ebef..46406200eff6 100644
--- a/src/Core/Core.csproj
+++ b/src/Core/Core.csproj
@@ -47,7 +47,7 @@
-
+
diff --git a/src/Infrastructure.EntityFramework/Auth/Configurations/GrantEntityTypeConfiguration.cs b/src/Infrastructure.EntityFramework/Auth/Configurations/GrantEntityTypeConfiguration.cs
new file mode 100644
index 000000000000..06c5eac0a1f0
--- /dev/null
+++ b/src/Infrastructure.EntityFramework/Auth/Configurations/GrantEntityTypeConfiguration.cs
@@ -0,0 +1,21 @@
+using Bit.Infrastructure.EntityFramework.Auth.Models;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace Bit.Infrastructure.EntityFramework.Auth.Configurations;
+
+public class GrantEntityTypeConfiguration : IEntityTypeConfiguration
+{
+ public void Configure(EntityTypeBuilder builder)
+ {
+ builder
+ .HasKey(s => s.Id)
+ .IsClustered();
+
+ builder
+ .HasIndex(s => s.Key)
+ .IsUnique(true);
+
+ builder.ToTable(nameof(Grant));
+ }
+}
diff --git a/src/Infrastructure.EntityFramework/Auth/Repositories/GrantRepository.cs b/src/Infrastructure.EntityFramework/Auth/Repositories/GrantRepository.cs
index 3026ad0eb91f..671e36c40e0e 100644
--- a/src/Infrastructure.EntityFramework/Auth/Repositories/GrantRepository.cs
+++ b/src/Infrastructure.EntityFramework/Auth/Repositories/GrantRepository.cs
@@ -81,6 +81,7 @@ public async Task SaveAsync(Core.Auth.Entities.Grant obj)
select g).FirstOrDefaultAsync();
if (existingGrant != null)
{
+ obj.Id = existingGrant.Id;
dbContext.Entry(existingGrant).CurrentValues.SetValues(obj);
}
else
diff --git a/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs b/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs
index 2a47545179c9..758612a44c3d 100644
--- a/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs
+++ b/src/Infrastructure.EntityFramework/Repositories/DatabaseContext.cs
@@ -81,7 +81,6 @@ protected override void OnModelCreating(ModelBuilder builder)
var eEmergencyAccess = builder.Entity();
var eEvent = builder.Entity();
var eFolder = builder.Entity();
- var eGrant = builder.Entity();
var eGroup = builder.Entity();
var eGroupUser = builder.Entity();
var eInstallation = builder.Entity();
@@ -134,7 +133,6 @@ protected override void OnModelCreating(ModelBuilder builder)
eCollectionCipher.HasKey(cc => new { cc.CollectionId, cc.CipherId });
eCollectionUser.HasKey(cu => new { cu.CollectionId, cu.OrganizationUserId });
eCollectionGroup.HasKey(cg => new { cg.CollectionId, cg.GroupId });
- eGrant.HasKey(x => x.Key);
eGroupUser.HasKey(gu => new { gu.GroupId, gu.OrganizationUserId });
var dataProtector = this.GetService().CreateProtector(
@@ -161,7 +159,6 @@ protected override void OnModelCreating(ModelBuilder builder)
eEmergencyAccess.ToTable(nameof(EmergencyAccess));
eEvent.ToTable(nameof(Event));
eFolder.ToTable(nameof(Folder));
- eGrant.ToTable(nameof(Grant));
eGroup.ToTable(nameof(Group));
eGroupUser.ToTable(nameof(GroupUser));
eInstallation.ToTable(nameof(Installation));
diff --git a/src/Sql/Auth/dbo/Tables/Grant.sql b/src/Sql/Auth/dbo/Tables/Grant.sql
index 02eda444bcd4..55d1b9b34a29 100644
--- a/src/Sql/Auth/dbo/Tables/Grant.sql
+++ b/src/Sql/Auth/dbo/Tables/Grant.sql
@@ -1,27 +1,25 @@
-CREATE TABLE [dbo].[Grant] (
- [Key] NVARCHAR (200) NOT NULL,
- [Type] NVARCHAR (50) NOT NULL,
- [SubjectId] NVARCHAR (200) NULL,
- [SessionId] NVARCHAR (100) NULL,
- [ClientId] NVARCHAR (200) NOT NULL,
- [Description] NVARCHAR (200) NULL,
- [CreationDate] DATETIME2 (7) NOT NULL,
- [ExpirationDate] DATETIME2 (7) NULL,
- [ConsumedDate] DATETIME2 (7) NULL,
- [Data] NVARCHAR (MAX) NOT NULL,
- CONSTRAINT [PK_Grant] PRIMARY KEY CLUSTERED ([Key] ASC)
+CREATE TABLE [dbo].[Grant]
+(
+ [Id] INT NOT NULL IDENTITY,
+ [Key] NVARCHAR (200) NOT NULL,
+ [Type] NVARCHAR (50) NOT NULL,
+ [SubjectId] NVARCHAR (200) NULL,
+ [SessionId] NVARCHAR (100) NULL,
+ [ClientId] NVARCHAR (200) NOT NULL,
+ [Description] NVARCHAR (200) NULL,
+ [CreationDate] DATETIME2 (7) NOT NULL,
+ [ExpirationDate] DATETIME2 (7) NULL,
+ [ConsumedDate] DATETIME2 (7) NULL,
+ [Data] NVARCHAR (MAX) NOT NULL,
+ CONSTRAINT [PK_Grant] PRIMARY KEY CLUSTERED ([Id] ASC)
);
-GO
-CREATE NONCLUSTERED INDEX [IX_Grant_SubjectId_ClientId_Type]
- ON [dbo].[Grant]([SubjectId] ASC, [ClientId] ASC, [Type] ASC);
-
-GO
-CREATE NONCLUSTERED INDEX [IX_Grant_SubjectId_SessionId_Type]
- ON [dbo].[Grant]([SubjectId] ASC, [SessionId] ASC, [Type] ASC);
-
GO
CREATE NONCLUSTERED INDEX [IX_Grant_ExpirationDate]
ON [dbo].[Grant]([ExpirationDate] ASC);
+GO
+
+CREATE UNIQUE INDEX [IX_Grant_Key]
+ ON [dbo].[Grant]([Key]);
diff --git a/test/Identity.IntegrationTest/openid-configuration.json b/test/Identity.IntegrationTest/openid-configuration.json
index e593a9300724..c72a0b10c3ef 100644
--- a/test/Identity.IntegrationTest/openid-configuration.json
+++ b/test/Identity.IntegrationTest/openid-configuration.json
@@ -75,7 +75,19 @@
"HS384",
"HS512"
],
+ "prompt_values_supported": ["none", "login", "consent", "select_account"],
"authorization_response_iss_parameter_supported": true,
"backchannel_token_delivery_modes_supported": ["poll"],
- "backchannel_user_code_parameter_supported": true
+ "backchannel_user_code_parameter_supported": true,
+ "dpop_signing_alg_values_supported": [
+ "RS256",
+ "RS384",
+ "RS512",
+ "PS256",
+ "PS384",
+ "PS512",
+ "ES256",
+ "ES384",
+ "ES512"
+ ]
}
diff --git a/util/Migrator/DbScripts/2023-12-04_00_GrantIndexes.sql b/util/Migrator/DbScripts/2023-12-04_00_GrantIndexes.sql
new file mode 100644
index 000000000000..a7b44ec79970
--- /dev/null
+++ b/util/Migrator/DbScripts/2023-12-04_00_GrantIndexes.sql
@@ -0,0 +1,47 @@
+IF EXISTS(SELECT name
+FROM sys.indexes
+WHERE name = 'IX_Grant_SubjectId_ClientId_Type')
+ BEGIN
+ DROP INDEX [IX_Grant_SubjectId_ClientId_Type] ON [dbo].[Grant]
+END
+GO
+
+IF EXISTS(SELECT name
+FROM sys.indexes
+WHERE name = 'IX_Grant_SubjectId_SessionId_Type')
+ BEGIN
+ DROP INDEX [IX_Grant_SubjectId_SessionId_Type] ON [dbo].[Grant]
+END
+GO
+
+IF COL_LENGTH('[dbo].[Grant]', 'Id') IS NULL
+BEGIN
+ ALTER TABLE [dbo].[Grant]
+ ADD [Id] INT NOT NULL IDENTITY
+
+ ALTER TABLE [dbo].[Grant]
+ DROP CONSTRAINT [PK_Grant];
+
+ ALTER TABLE [dbo].[Grant]
+ ADD CONSTRAINT [PK_Grant] PRIMARY KEY CLUSTERED ([Id] ASC);
+
+ CREATE UNIQUE INDEX [IX_Grant_Key]
+ ON [dbo].[Grant]([Key]);
+END
+GO
+
+IF EXISTS(SELECT *
+FROM sys.views
+WHERE [Name] = 'GrantView')
+ BEGIN
+ DROP VIEW [dbo].[GrantView];
+END
+GO
+
+CREATE VIEW [dbo].[GrantView]
+AS
+ SELECT
+ *
+ FROM
+ [dbo].[Grant]
+GO
diff --git a/util/MySqlMigrations/Migrations/20231214162533_GrantIdWithIndexes.Designer.cs b/util/MySqlMigrations/Migrations/20231214162533_GrantIdWithIndexes.Designer.cs
new file mode 100644
index 000000000000..a2e7c13b07d6
--- /dev/null
+++ b/util/MySqlMigrations/Migrations/20231214162533_GrantIdWithIndexes.Designer.cs
@@ -0,0 +1,2334 @@
+//
+using System;
+using Bit.Infrastructure.EntityFramework.Repositories;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+
+#nullable disable
+
+namespace Bit.MySqlMigrations.Migrations
+{
+ [DbContext(typeof(DatabaseContext))]
+ [Migration("20231214162533_GrantIdWithIndexes")]
+ partial class GrantIdWithIndexes
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.14")
+ .HasAnnotation("Relational:MaxIdentifierLength", 64);
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Organization", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("AllowAdminAccessToAllCollectionItems")
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(true);
+
+ b.Property("BillingEmail")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("BusinessAddress1")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("BusinessAddress2")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("BusinessAddress3")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("BusinessCountry")
+ .HasMaxLength(2)
+ .HasColumnType("varchar(2)");
+
+ b.Property("BusinessName")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("BusinessTaxNumber")
+ .HasMaxLength(30)
+ .HasColumnType("varchar(30)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Enabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("ExpirationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Gateway")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("GatewayCustomerId")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("GatewaySubscriptionId")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("Identifier")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("LicenseKey")
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)");
+
+ b.Property("LimitCollectionCreationDeletion")
+ .HasColumnType("tinyint(1)")
+ .HasDefaultValue(true);
+
+ b.Property("MaxAutoscaleSeats")
+ .HasColumnType("int");
+
+ b.Property("MaxAutoscaleSmSeats")
+ .HasColumnType("int");
+
+ b.Property("MaxAutoscaleSmServiceAccounts")
+ .HasColumnType("int");
+
+ b.Property("MaxCollections")
+ .HasColumnType("smallint");
+
+ b.Property("MaxStorageGb")
+ .HasColumnType("smallint");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("OwnersNotifiedOfAutoscaling")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Plan")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("PlanType")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("PrivateKey")
+ .HasColumnType("longtext");
+
+ b.Property("PublicKey")
+ .HasColumnType("longtext");
+
+ b.Property("ReferenceData")
+ .HasColumnType("longtext");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Seats")
+ .HasColumnType("int");
+
+ b.Property("SecretsManagerBeta")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("SelfHost")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("SmSeats")
+ .HasColumnType("int");
+
+ b.Property("SmServiceAccounts")
+ .HasColumnType("int");
+
+ b.Property("Status")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("Storage")
+ .HasColumnType("bigint");
+
+ b.Property("TwoFactorProviders")
+ .HasColumnType("longtext");
+
+ b.Property("Use2fa")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseApi")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseCustomPermissions")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseDirectory")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseEvents")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseGroups")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseKeyConnector")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UsePasswordManager")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UsePolicies")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseResetPassword")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseScim")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseSecretsManager")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseSso")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UseTotp")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("UsersGetPremium")
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Organization", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Policy", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Data")
+ .HasColumnType("longtext");
+
+ b.Property("Enabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Type")
+ .HasColumnType("tinyint unsigned");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("Policy", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider.Provider", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("BillingEmail")
+ .HasColumnType("longtext");
+
+ b.Property("BillingPhone")
+ .HasColumnType("longtext");
+
+ b.Property("BusinessAddress1")
+ .HasColumnType("longtext");
+
+ b.Property("BusinessAddress2")
+ .HasColumnType("longtext");
+
+ b.Property("BusinessAddress3")
+ .HasColumnType("longtext");
+
+ b.Property("BusinessCountry")
+ .HasColumnType("longtext");
+
+ b.Property("BusinessName")
+ .HasColumnType("longtext");
+
+ b.Property("BusinessTaxNumber")
+ .HasColumnType("longtext");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Enabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Name")
+ .HasColumnType("longtext");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Status")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("Type")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("UseEvents")
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Provider", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider.ProviderOrganization", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Key")
+ .HasColumnType("longtext");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("ProviderId")
+ .HasColumnType("char(36)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Settings")
+ .HasColumnType("longtext");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.HasIndex("ProviderId");
+
+ b.ToTable("ProviderOrganization", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider.ProviderUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Email")
+ .HasColumnType("longtext");
+
+ b.Property("Key")
+ .HasColumnType("longtext");
+
+ b.Property("Permissions")
+ .HasColumnType("longtext");
+
+ b.Property("ProviderId")
+ .HasColumnType("char(36)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Status")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("Type")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProviderId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("ProviderUser", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Auth.Models.AuthRequest", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("AccessCode")
+ .HasMaxLength(25)
+ .HasColumnType("varchar(25)");
+
+ b.Property("Approved")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("AuthenticationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Key")
+ .HasColumnType("longtext");
+
+ b.Property("MasterPasswordHash")
+ .HasColumnType("longtext");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("PublicKey")
+ .HasColumnType("longtext");
+
+ b.Property("RequestDeviceIdentifier")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("RequestDeviceType")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("RequestIpAddress")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("ResponseDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ResponseDeviceId")
+ .HasColumnType("char(36)");
+
+ b.Property("Type")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.HasIndex("ResponseDeviceId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("AuthRequest", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Auth.Models.EmergencyAccess", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("GranteeId")
+ .HasColumnType("char(36)");
+
+ b.Property("GrantorId")
+ .HasColumnType("char(36)");
+
+ b.Property("KeyEncrypted")
+ .HasColumnType("longtext");
+
+ b.Property("LastNotificationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("RecoveryInitiatedDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Status")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("Type")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("WaitTimeDays")
+ .HasColumnType("int");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GranteeId");
+
+ b.HasIndex("GrantorId");
+
+ b.ToTable("EmergencyAccess", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Auth.Models.Grant", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int");
+
+ b.Property("ClientId")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("varchar(200)");
+
+ b.Property("ConsumedDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Data")
+ .IsRequired()
+ .HasColumnType("longtext");
+
+ b.Property("Description")
+ .HasMaxLength(200)
+ .HasColumnType("varchar(200)");
+
+ b.Property("ExpirationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("varchar(200)");
+
+ b.Property("SessionId")
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)");
+
+ b.Property("SubjectId")
+ .HasMaxLength(200)
+ .HasColumnType("varchar(200)");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.HasKey("Id")
+ .HasAnnotation("SqlServer:Clustered", true);
+
+ b.HasIndex("Key")
+ .IsUnique();
+
+ b.ToTable("Grant", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Auth.Models.SsoConfig", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Data")
+ .HasColumnType("longtext");
+
+ b.Property("Enabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("SsoConfig", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Auth.Models.SsoUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ExternalId")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("SsoUser", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Auth.Models.WebAuthnCredential", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("AaGuid")
+ .HasColumnType("char(36)");
+
+ b.Property("Counter")
+ .HasColumnType("int");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("CredentialId")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("EncryptedPrivateKey")
+ .HasMaxLength(2000)
+ .HasColumnType("varchar(2000)");
+
+ b.Property("EncryptedPublicKey")
+ .HasMaxLength(2000)
+ .HasColumnType("varchar(2000)");
+
+ b.Property("EncryptedUserKey")
+ .HasMaxLength(2000)
+ .HasColumnType("varchar(2000)");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("PublicKey")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("SupportsPrf")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Type")
+ .HasMaxLength(20)
+ .HasColumnType("varchar(20)");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("WebAuthnCredential", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Collection", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ExternalId")
+ .HasMaxLength(300)
+ .HasColumnType("varchar(300)");
+
+ b.Property("Name")
+ .HasColumnType("longtext");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("Collection", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.CollectionCipher", b =>
+ {
+ b.Property("CollectionId")
+ .HasColumnType("char(36)");
+
+ b.Property("CipherId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("CollectionId", "CipherId");
+
+ b.HasIndex("CipherId");
+
+ b.ToTable("CollectionCipher", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.CollectionGroup", b =>
+ {
+ b.Property("CollectionId")
+ .HasColumnType("char(36)");
+
+ b.Property("GroupId")
+ .HasColumnType("char(36)");
+
+ b.Property("HidePasswords")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Manage")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("ReadOnly")
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("CollectionId", "GroupId");
+
+ b.HasIndex("GroupId");
+
+ b.ToTable("CollectionGroups");
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.CollectionUser", b =>
+ {
+ b.Property("CollectionId")
+ .HasColumnType("char(36)");
+
+ b.Property("OrganizationUserId")
+ .HasColumnType("char(36)");
+
+ b.Property("HidePasswords")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Manage")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("ReadOnly")
+ .HasColumnType("tinyint(1)");
+
+ b.HasKey("CollectionId", "OrganizationUserId");
+
+ b.HasIndex("OrganizationUserId");
+
+ b.ToTable("CollectionUsers");
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Device", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("char(36)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("EncryptedPrivateKey")
+ .HasColumnType("longtext");
+
+ b.Property("EncryptedPublicKey")
+ .HasColumnType("longtext");
+
+ b.Property("EncryptedUserKey")
+ .HasColumnType("longtext");
+
+ b.Property("Identifier")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("PushToken")
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Type")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Device", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Event", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("ActingUserId")
+ .HasColumnType("char(36)");
+
+ b.Property("CipherId")
+ .HasColumnType("char(36)");
+
+ b.Property("CollectionId")
+ .HasColumnType("char(36)");
+
+ b.Property("Date")
+ .HasColumnType("datetime(6)");
+
+ b.Property("DeviceType")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("DomainName")
+ .HasColumnType("longtext");
+
+ b.Property("GroupId")
+ .HasColumnType("char(36)");
+
+ b.Property("InstallationId")
+ .HasColumnType("char(36)");
+
+ b.Property("IpAddress")
+ .HasMaxLength(50)
+ .HasColumnType("varchar(50)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("OrganizationUserId")
+ .HasColumnType("char(36)");
+
+ b.Property("PolicyId")
+ .HasColumnType("char(36)");
+
+ b.Property("ProviderId")
+ .HasColumnType("char(36)");
+
+ b.Property("ProviderOrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("ProviderUserId")
+ .HasColumnType("char(36)");
+
+ b.Property("SecretId")
+ .HasColumnType("char(36)");
+
+ b.Property("ServiceAccountId")
+ .HasColumnType("char(36)");
+
+ b.Property("SystemUser")
+ .HasColumnType("tinyint unsigned");
+
+ b.Property("Type")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Event", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Group", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("AccessAll")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("ExternalId")
+ .HasMaxLength(300)
+ .HasColumnType("varchar(300)");
+
+ b.Property("Name")
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("Group", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.GroupUser", b =>
+ {
+ b.Property("GroupId")
+ .HasColumnType("char(36)");
+
+ b.Property("OrganizationUserId")
+ .HasColumnType("char(36)");
+
+ b.HasKey("GroupId", "OrganizationUserId");
+
+ b.HasIndex("OrganizationUserId");
+
+ b.ToTable("GroupUser", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Installation", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("Enabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("Key")
+ .HasMaxLength(150)
+ .HasColumnType("varchar(150)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Installation", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationApiKey", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("ApiKey")
+ .HasMaxLength(30)
+ .HasColumnType("varchar(30)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("Type")
+ .HasColumnType("tinyint unsigned");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("OrganizationApiKey", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationConnection", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("Config")
+ .HasColumnType("longtext");
+
+ b.Property("Enabled")
+ .HasColumnType("tinyint(1)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("Type")
+ .HasColumnType("tinyint unsigned");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("OrganizationConnection", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationDomain", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("CreationDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("DomainName")
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)");
+
+ b.Property("JobRunCount")
+ .HasColumnType("int");
+
+ b.Property("LastCheckedDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("NextRunDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("char(36)");
+
+ b.Property("Txt")
+ .HasColumnType("longtext");
+
+ b.Property("VerifiedDate")
+ .HasColumnType("datetime(6)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("OrganizationDomain", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationSponsorship", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("char(36)");
+
+ b.Property("FriendlyName")
+ .HasMaxLength(256)
+ .HasColumnType("varchar(256)");
+
+ b.Property("LastSyncDate")
+ .HasColumnType("datetime(6)");
+
+ b.Property