diff --git a/util/SqliteMigrations/HelperScripts/2024-03-22_00_EnableOrgsCollectionEnhancements.sql b/util/SqliteMigrations/HelperScripts/2024-03-22_00_EnableOrgsCollectionEnhancements.sql
new file mode 100644
index 0000000000..ad468694c5
--- /dev/null
+++ b/util/SqliteMigrations/HelperScripts/2024-03-22_00_EnableOrgsCollectionEnhancements.sql
@@ -0,0 +1,151 @@
+-- Step 1: AccessAll migration for Groups
+ -- Create a temporary table to store the groups with AccessAll = 1
+ CREATE TEMPORARY TABLE IF NOT EXISTS "TempGroupsAccessAll" AS
+ SELECT "G"."Id" AS "GroupId",
+ "G"."OrganizationId"
+ FROM "Group" "G"
+ INNER JOIN "Organization" "O" ON "G"."OrganizationId" = "O"."Id"
+ WHERE "O"."FlexibleCollections" = 0 AND "G"."AccessAll" = 1;
+
+-- Step 2: AccessAll migration for OrganizationUsers
+ -- Create a temporary table to store the OrganizationUsers with AccessAll = 1
+ CREATE TEMPORARY TABLE IF NOT EXISTS "TempUsersAccessAll" AS
+ SELECT "OU"."Id" AS "OrganizationUserId",
+ "OU"."OrganizationId"
+ FROM "OrganizationUser" "OU"
+ INNER JOIN "Organization" "O" ON "OU"."OrganizationId" = "O"."Id"
+ WHERE "O"."FlexibleCollections" = 0 AND "OU"."AccessAll" = 1;
+
+-- Step 3: For all OrganizationUsers with Manager role or 'EditAssignedCollections' permission update their existing CollectionUsers rows and insert new rows with [Manage] = 1
+-- and finally update all OrganizationUsers with Manager role to User role
+ -- Create a temporary table to store the OrganizationUsers with Manager role or 'EditAssignedCollections' permission
+ CREATE TEMPORARY TABLE IF NOT EXISTS "TempUserManagers" AS
+ SELECT "OU"."Id" AS "OrganizationUserId",
+ CASE WHEN "OU"."Type" = 3 THEN 1 ELSE 0 END AS "IsManager"
+ FROM "OrganizationUser" "OU"
+ INNER JOIN "Organization" "O" ON "OU"."OrganizationId" = "O"."Id"
+ WHERE "O"."FlexibleCollections" = 0 AND
+ ("OU"."Type" = 3 OR
+ ("OU"."Type" = 4 AND
+ "OU"."Permissions" IS NOT NULL AND
+ JSON_VALID("OU"."Permissions") AND JSON_EXTRACT(ou."Permissions", '$.editAssignedCollections') = 'true'));
+
+-- Step 1
+ -- Update existing rows in "CollectionGroups"
+ UPDATE "CollectionGroups"
+ SET
+ "ReadOnly" = 0,
+ "HidePasswords" = 0,
+ "Manage" = 0
+ WHERE EXISTS (
+ SELECT 1
+ FROM "Collection" "C"
+ INNER JOIN "TempGroupsAccessAll" "TG" ON "CollectionGroups"."GroupId" = "TG"."GroupId"
+ WHERE "CollectionGroups"."CollectionId" = "C"."Id" AND C."OrganizationId" = "TG"."OrganizationId"
+ );
+
+ -- Insert new rows into "CollectionGroups"
+ INSERT INTO "CollectionGroups" ("CollectionId", "GroupId", "ReadOnly", "HidePasswords", "Manage")
+ SELECT "C"."Id", "TG"."GroupId", 0, 0, 0
+ FROM "Collection" "C"
+ INNER JOIN "TempGroupsAccessAll" "TG" ON "C"."OrganizationId" = "TG"."OrganizationId"
+ LEFT JOIN "CollectionGroups" "CG" ON "CG"."CollectionId" = "C"."Id" AND "CG"."GroupId" = "TG"."GroupId"
+ WHERE "CG"."CollectionId" IS NULL;
+
+ -- Update "Group" to clear "AccessAll" flag and update "RevisionDate"
+ UPDATE "Group"
+ SET "AccessAll" = 0, "RevisionDate" = CURRENT_TIMESTAMP
+ WHERE "Id" IN (SELECT "GroupId" FROM "TempGroupsAccessAll");
+
+-- Step 2
+ -- Update existing rows in "CollectionUsers"
+ UPDATE "CollectionUsers"
+ SET
+ "ReadOnly" = 0,
+ "HidePasswords" = 0,
+ "Manage" = 0
+ WHERE "CollectionId" IN (
+ SELECT "C"."Id"
+ FROM "Collection" "C"
+ INNER JOIN "TempUsersAccessAll" "TU" ON "C"."OrganizationId" = "TU"."OrganizationId"
+ );
+
+ -- Insert new rows into "CollectionUsers"
+ INSERT INTO "CollectionUsers" ("CollectionId", "OrganizationUserId", "ReadOnly", "HidePasswords", "Manage")
+ SELECT "C"."Id", "TU"."OrganizationUserId", 0, 0, 0
+ FROM "Collection" "C"
+ INNER JOIN "TempUsersAccessAll" "TU" ON "C"."OrganizationId" = "TU"."OrganizationId"
+ LEFT JOIN "CollectionUsers" "target"
+ ON "target"."CollectionId" = "C"."Id" AND "target"."OrganizationUserId" = "TU"."OrganizationUserId"
+ WHERE "target"."CollectionId" IS NULL;
+
+ -- Update "OrganizationUser" to clear "AccessAll" flag
+ UPDATE "OrganizationUser"
+ SET "AccessAll" = 0, "RevisionDate" = CURRENT_TIMESTAMP
+ WHERE "Id" IN (SELECT "OrganizationUserId" FROM "TempUsersAccessAll");
+
+-- Step 3
+ -- Update "CollectionUsers" with "Manage" = 1 using the temporary table
+ UPDATE "CollectionUsers"
+ SET
+ "ReadOnly" = 0,
+ "HidePasswords" = 0,
+ "Manage" = 1
+ WHERE "OrganizationUserId" IN (SELECT "OrganizationUserId" FROM "TempUserManagers");
+
+ -- Insert rows to "CollectionUsers" with "Manage" = 1 using the temporary table
+ -- This is for orgUsers who are Managers / EditAssignedCollections but have access via a group
+ -- We cannot give the whole group Manage permissions so we have to give them a direct assignment
+ INSERT INTO "CollectionUsers" ("CollectionId", "OrganizationUserId", "ReadOnly", "HidePasswords", "Manage")
+ SELECT DISTINCT "CG"."CollectionId", "TUM"."OrganizationUserId", 0, 0, 1
+ FROM "CollectionGroups" "CG"
+ INNER JOIN "GroupUser" "GU" ON "CG"."GroupId" = "GU"."GroupId"
+ INNER JOIN "TempUserManagers" "TUM" ON "GU"."OrganizationUserId" = "TUM"."OrganizationUserId"
+ WHERE NOT EXISTS (
+ SELECT 1 FROM "CollectionUsers" "CU"
+ WHERE "CU"."CollectionId" = "CG"."CollectionId" AND "CU"."OrganizationUserId" = "TUM"."OrganizationUserId"
+ );
+
+ -- Update "OrganizationUser" to migrate all OrganizationUsers with Manager role to User role
+ UPDATE "OrganizationUser"
+ SET "Type" = 2, "RevisionDate" = CURRENT_TIMESTAMP -- User
+ WHERE "Id" IN (SELECT "OrganizationUserId" FROM "TempUserManagers" WHERE "IsManager" = 1);
+
+-- Step 4
+ -- Update "User" "AccountRevisionDate" for each unique "OrganizationUserId"
+ UPDATE "User"
+ SET "AccountRevisionDate" = CURRENT_TIMESTAMP
+ WHERE "Id" IN (
+ SELECT DISTINCT "OU"."UserId"
+ FROM "OrganizationUser" "OU"
+ INNER JOIN (
+ -- Step 1
+ SELECT "GU"."OrganizationUserId"
+ FROM "GroupUser" "GU"
+ INNER JOIN "TempGroupsAccessAll" "TG" ON "GU"."GroupId" = "TG"."GroupId"
+
+ UNION
+
+ -- Step 2
+ SELECT "OrganizationUserId"
+ FROM "TempUsersAccessAll"
+
+ UNION
+
+ -- Step 3
+ SELECT "OrganizationUserId"
+ FROM "TempUserManagers"
+ ) AS "CombinedOrgUsers" ON "OU"."Id" = "CombinedOrgUsers"."OrganizationUserId"
+ );
+
+-- Step 5
+ -- Set "FlexibleCollections" = 1 for all organizations that have not yet been migrated.
+ UPDATE "Organization"
+ SET "FlexibleCollections" = 1
+ WHERE "FlexibleCollections" = 0;
+
+
+-- Step 6: Drop the temporary tables
+DROP TABLE IF EXISTS "TempGroupsAccessAll";
+DROP TABLE IF EXISTS "TempUsersAccessAll";
+DROP TABLE IF EXISTS "TempUserManagers";
diff --git a/util/SqliteMigrations/Migrations/20240322155524_EnableOrgsCollectionEnhancements.Designer.cs b/util/SqliteMigrations/Migrations/20240322155524_EnableOrgsCollectionEnhancements.Designer.cs
new file mode 100644
index 0000000000..6559f6fc6e
--- /dev/null
+++ b/util/SqliteMigrations/Migrations/20240322155524_EnableOrgsCollectionEnhancements.Designer.cs
@@ -0,0 +1,2578 @@
+//
+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.SqliteMigrations.Migrations
+{
+ [DbContext(typeof(DatabaseContext))]
+ [Migration("20240322155524_EnableOrgsCollectionEnhancements")]
+ partial class EnableOrgsCollectionEnhancements
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder.HasAnnotation("ProductVersion", "7.0.16");
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Organization", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("AllowAdminAccessToAllCollectionItems")
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(true);
+
+ b.Property("BillingEmail")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessAddress1")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessAddress2")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessAddress3")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessCountry")
+ .HasMaxLength(2)
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessName")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessTaxNumber")
+ .HasMaxLength(30)
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Enabled")
+ .HasColumnType("INTEGER");
+
+ b.Property("ExpirationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("FlexibleCollections")
+ .HasColumnType("INTEGER");
+
+ b.Property("Gateway")
+ .HasColumnType("INTEGER");
+
+ b.Property("GatewayCustomerId")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("GatewaySubscriptionId")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("Identifier")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("LicenseKey")
+ .HasMaxLength(100)
+ .HasColumnType("TEXT");
+
+ b.Property("LimitCollectionCreationDeletion")
+ .HasColumnType("INTEGER")
+ .HasDefaultValue(true);
+
+ b.Property("MaxAutoscaleSeats")
+ .HasColumnType("INTEGER");
+
+ b.Property("MaxAutoscaleSmSeats")
+ .HasColumnType("INTEGER");
+
+ b.Property("MaxAutoscaleSmServiceAccounts")
+ .HasColumnType("INTEGER");
+
+ b.Property("MaxCollections")
+ .HasColumnType("INTEGER");
+
+ b.Property("MaxStorageGb")
+ .HasColumnType("INTEGER");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("OwnersNotifiedOfAutoscaling")
+ .HasColumnType("TEXT");
+
+ b.Property("Plan")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("PlanType")
+ .HasColumnType("INTEGER");
+
+ b.Property("PrivateKey")
+ .HasColumnType("TEXT");
+
+ b.Property("PublicKey")
+ .HasColumnType("TEXT");
+
+ b.Property("ReferenceData")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Seats")
+ .HasColumnType("INTEGER");
+
+ b.Property("SelfHost")
+ .HasColumnType("INTEGER");
+
+ b.Property("SmSeats")
+ .HasColumnType("INTEGER");
+
+ b.Property("SmServiceAccounts")
+ .HasColumnType("INTEGER");
+
+ b.Property("Status")
+ .HasColumnType("INTEGER");
+
+ b.Property("Storage")
+ .HasColumnType("INTEGER");
+
+ b.Property("TwoFactorProviders")
+ .HasColumnType("TEXT");
+
+ b.Property("Use2fa")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseApi")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseCustomPermissions")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseDirectory")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseEvents")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseGroups")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseKeyConnector")
+ .HasColumnType("INTEGER");
+
+ b.Property("UsePasswordManager")
+ .HasColumnType("INTEGER");
+
+ b.Property("UsePolicies")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseResetPassword")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseScim")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseSecretsManager")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseSso")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseTotp")
+ .HasColumnType("INTEGER");
+
+ b.Property("UsersGetPremium")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Id", "Enabled")
+ .HasAnnotation("Npgsql:IndexInclude", new[] { "UseTotp" });
+
+ b.ToTable("Organization", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Policy", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Data")
+ .HasColumnType("TEXT");
+
+ b.Property("Enabled")
+ .HasColumnType("INTEGER");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId")
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.HasIndex("OrganizationId", "Type")
+ .IsUnique()
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.ToTable("Policy", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider.Provider", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("BillingEmail")
+ .HasColumnType("TEXT");
+
+ b.Property("BillingPhone")
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessAddress1")
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessAddress2")
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessAddress3")
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessCountry")
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessName")
+ .HasColumnType("TEXT");
+
+ b.Property("BusinessTaxNumber")
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Enabled")
+ .HasColumnType("INTEGER");
+
+ b.Property("Gateway")
+ .HasColumnType("INTEGER");
+
+ b.Property("GatewayCustomerId")
+ .HasColumnType("TEXT");
+
+ b.Property("GatewaySubscriptionId")
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Status")
+ .HasColumnType("INTEGER");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.Property("UseEvents")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.ToTable("Provider", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider.ProviderOrganization", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderId")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Settings")
+ .HasColumnType("TEXT");
+
+ 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("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Email")
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .HasColumnType("TEXT");
+
+ b.Property("Permissions")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderId")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Status")
+ .HasColumnType("INTEGER");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ 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("TEXT");
+
+ b.Property("AccessCode")
+ .HasMaxLength(25)
+ .HasColumnType("TEXT");
+
+ b.Property("Approved")
+ .HasColumnType("INTEGER");
+
+ b.Property("AuthenticationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .HasColumnType("TEXT");
+
+ b.Property("MasterPasswordHash")
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("PublicKey")
+ .HasColumnType("TEXT");
+
+ b.Property("RequestDeviceIdentifier")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("RequestDeviceType")
+ .HasColumnType("INTEGER");
+
+ b.Property("RequestIpAddress")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("ResponseDate")
+ .HasColumnType("TEXT");
+
+ b.Property("ResponseDeviceId")
+ .HasColumnType("TEXT");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ 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("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("GranteeId")
+ .HasColumnType("TEXT");
+
+ b.Property("GrantorId")
+ .HasColumnType("TEXT");
+
+ b.Property("KeyEncrypted")
+ .HasColumnType("TEXT");
+
+ b.Property("LastNotificationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("RecoveryInitiatedDate")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Status")
+ .HasColumnType("INTEGER");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.Property("WaitTimeDays")
+ .HasColumnType("INTEGER");
+
+ 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("INTEGER");
+
+ b.Property("ClientId")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("TEXT");
+
+ b.Property("ConsumedDate")
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Data")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.Property("Description")
+ .HasMaxLength(200)
+ .HasColumnType("TEXT");
+
+ b.Property("ExpirationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Key")
+ .IsRequired()
+ .HasMaxLength(200)
+ .HasColumnType("TEXT");
+
+ b.Property("SessionId")
+ .HasMaxLength(100)
+ .HasColumnType("TEXT");
+
+ b.Property("SubjectId")
+ .HasMaxLength(200)
+ .HasColumnType("TEXT");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id")
+ .HasName("PK_Grant")
+ .HasAnnotation("SqlServer:Clustered", true);
+
+ b.HasIndex("ExpirationDate")
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.HasIndex("Key")
+ .IsUnique();
+
+ b.ToTable("Grant", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Auth.Models.SsoConfig", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Data")
+ .HasColumnType("TEXT");
+
+ b.Property("Enabled")
+ .HasColumnType("INTEGER");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ 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("INTEGER");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("ExternalId")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId")
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("OrganizationId", "ExternalId")
+ .IsUnique()
+ .HasAnnotation("Npgsql:IndexInclude", new[] { "UserId" })
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.HasIndex("OrganizationId", "UserId")
+ .IsUnique()
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.ToTable("SsoUser", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Auth.Models.WebAuthnCredential", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("AaGuid")
+ .HasColumnType("TEXT");
+
+ b.Property("Counter")
+ .HasColumnType("INTEGER");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("CredentialId")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("EncryptedPrivateKey")
+ .HasMaxLength(2000)
+ .HasColumnType("TEXT");
+
+ b.Property("EncryptedPublicKey")
+ .HasMaxLength(2000)
+ .HasColumnType("TEXT");
+
+ b.Property("EncryptedUserKey")
+ .HasMaxLength(2000)
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("PublicKey")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.Property("SupportsPrf")
+ .HasColumnType("INTEGER");
+
+ b.Property("Type")
+ .HasMaxLength(20)
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("WebAuthnCredential", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Billing.Models.ProviderPlan", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("AllocatedSeats")
+ .HasColumnType("INTEGER");
+
+ b.Property("PlanType")
+ .HasColumnType("INTEGER");
+
+ b.Property("ProviderId")
+ .HasColumnType("TEXT");
+
+ b.Property("PurchasedSeats")
+ .HasColumnType("INTEGER");
+
+ b.Property("SeatMinimum")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ProviderId");
+
+ b.HasIndex("Id", "PlanType")
+ .IsUnique();
+
+ b.ToTable("ProviderPlan", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Collection", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("ExternalId")
+ .HasMaxLength(300)
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("Collection", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.CollectionCipher", b =>
+ {
+ b.Property("CollectionId")
+ .HasColumnType("TEXT");
+
+ b.Property("CipherId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("CollectionId", "CipherId");
+
+ b.HasIndex("CipherId");
+
+ b.ToTable("CollectionCipher", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.CollectionGroup", b =>
+ {
+ b.Property("CollectionId")
+ .HasColumnType("TEXT");
+
+ b.Property("GroupId")
+ .HasColumnType("TEXT");
+
+ b.Property("HidePasswords")
+ .HasColumnType("INTEGER");
+
+ b.Property("Manage")
+ .HasColumnType("INTEGER");
+
+ b.Property("ReadOnly")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("CollectionId", "GroupId");
+
+ b.HasIndex("GroupId");
+
+ b.ToTable("CollectionGroups");
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.CollectionUser", b =>
+ {
+ b.Property("CollectionId")
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationUserId")
+ .HasColumnType("TEXT");
+
+ b.Property("HidePasswords")
+ .HasColumnType("INTEGER");
+
+ b.Property("Manage")
+ .HasColumnType("INTEGER");
+
+ b.Property("ReadOnly")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("CollectionId", "OrganizationUserId");
+
+ b.HasIndex("OrganizationUserId");
+
+ b.ToTable("CollectionUsers");
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Device", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("EncryptedPrivateKey")
+ .HasColumnType("TEXT");
+
+ b.Property("EncryptedPublicKey")
+ .HasColumnType("TEXT");
+
+ b.Property("EncryptedUserKey")
+ .HasColumnType("TEXT");
+
+ b.Property("Identifier")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("PushToken")
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Identifier")
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.HasIndex("UserId")
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.HasIndex("UserId", "Identifier")
+ .IsUnique()
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.ToTable("Device", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Event", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("ActingUserId")
+ .HasColumnType("TEXT");
+
+ b.Property("CipherId")
+ .HasColumnType("TEXT");
+
+ b.Property("CollectionId")
+ .HasColumnType("TEXT");
+
+ b.Property("Date")
+ .HasColumnType("TEXT");
+
+ b.Property("DeviceType")
+ .HasColumnType("INTEGER");
+
+ b.Property("DomainName")
+ .HasColumnType("TEXT");
+
+ b.Property("GroupId")
+ .HasColumnType("TEXT");
+
+ b.Property("InstallationId")
+ .HasColumnType("TEXT");
+
+ b.Property("IpAddress")
+ .HasMaxLength(50)
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationUserId")
+ .HasColumnType("TEXT");
+
+ b.Property("PolicyId")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderId")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderOrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderUserId")
+ .HasColumnType("TEXT");
+
+ b.Property("SecretId")
+ .HasColumnType("TEXT");
+
+ b.Property("ServiceAccountId")
+ .HasColumnType("TEXT");
+
+ b.Property("SystemUser")
+ .HasColumnType("INTEGER");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("Date", "OrganizationId", "ActingUserId", "CipherId")
+ .HasAnnotation("SqlServer:Clustered", false);
+
+ b.ToTable("Event", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Group", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("AccessAll")
+ .HasColumnType("INTEGER");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("ExternalId")
+ .HasMaxLength(300)
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasMaxLength(100)
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("Group", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.GroupUser", b =>
+ {
+ b.Property("GroupId")
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationUserId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("GroupId", "OrganizationUserId");
+
+ b.HasIndex("OrganizationUserId");
+
+ b.ToTable("GroupUser", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Installation", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("Enabled")
+ .HasColumnType("INTEGER");
+
+ b.Property("Key")
+ .HasMaxLength(150)
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.ToTable("Installation", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationApiKey", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("ApiKey")
+ .HasMaxLength(30)
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("RevisionDate")
+ .HasColumnType("TEXT");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("OrganizationApiKey", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationConnection", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("Config")
+ .HasColumnType("TEXT");
+
+ b.Property("Enabled")
+ .HasColumnType("INTEGER");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("Type")
+ .HasColumnType("INTEGER");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("OrganizationConnection", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationDomain", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("CreationDate")
+ .HasColumnType("TEXT");
+
+ b.Property("DomainName")
+ .HasMaxLength(255)
+ .HasColumnType("TEXT");
+
+ b.Property("JobRunCount")
+ .HasColumnType("INTEGER");
+
+ b.Property("LastCheckedDate")
+ .HasColumnType("TEXT");
+
+ b.Property("NextRunDate")
+ .HasColumnType("TEXT");
+
+ b.Property("OrganizationId")
+ .HasColumnType("TEXT");
+
+ b.Property("Txt")
+ .HasColumnType("TEXT");
+
+ b.Property("VerifiedDate")
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("OrganizationDomain", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationSponsorship", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("FriendlyName")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property("LastSyncDate")
+ .HasColumnType("TEXT");
+
+ b.Property("OfferedToEmail")
+ .HasMaxLength(256)
+ .HasColumnType("TEXT");
+
+ b.Property