diff --git a/util/PostgresMigrations/HelperScripts/2023-12-06_00_AccessAllCollectionGroups.psql b/util/PostgresMigrations/HelperScripts/2023-12-06_00_AccessAllCollectionGroups.psql
index 229c07cd24..c03220dd7a 100644
--- a/util/PostgresMigrations/HelperScripts/2023-12-06_00_AccessAllCollectionGroups.psql
+++ b/util/PostgresMigrations/HelperScripts/2023-12-06_00_AccessAllCollectionGroups.psql
@@ -1,10 +1,10 @@
--- Create a temporary table to store the groups with AccessAll = true
-CREATE TEMPORARY TABLE TempGroup AS
+-- Step 1: Create a temporary table to store the groups with AccessAll = 1
+CREATE TEMP TABLE IF NOT EXISTS TempGroup AS
SELECT "Id" AS "GroupId", "OrganizationId"
FROM "Group"
WHERE "AccessAll" = true;
--- Update existing rows in "CollectionGroups"
+-- Step 2: Update existing rows in "CollectionGroup"
UPDATE "CollectionGroups" CG
SET
"ReadOnly" = false,
@@ -12,16 +12,16 @@ SET
"Manage" = false
FROM "CollectionGroups" CGUpdate
INNER JOIN "Collection" C ON CGUpdate."CollectionId" = C."Id"
- INNER JOIN TempGroup TG ON CGUpdate."GroupId" = TG."GroupId"
+INNER JOIN TempGroup TG ON CGUpdate."GroupId" = TG."GroupId"
WHERE C."OrganizationId" = TG."OrganizationId";
--- Insert new rows into "CollectionGroups"
+-- Step 3: Insert new rows into "CollectionGroup"
INSERT INTO "CollectionGroups" ("CollectionId", "GroupId", "ReadOnly", "HidePasswords", "Manage")
SELECT C."Id", TG."GroupId", false, false, false
FROM "Collection" C
- INNER JOIN TempGroup TG ON C."OrganizationId" = TG."OrganizationId"
- LEFT JOIN "CollectionGroups" CG ON CG."CollectionId" = C."Id" AND CG."GroupId" = TG."GroupId"
+INNER JOIN TempGroup 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;
--- Drop the temporary table
+-- Step 4: Drop the temporary table
DROP TABLE IF EXISTS TempGroup;
diff --git a/util/PostgresMigrations/HelperScripts/2023-12-06_01_AccessAllCollectionUsers.psql b/util/PostgresMigrations/HelperScripts/2023-12-06_01_AccessAllCollectionUsers.psql
index 1ff57c0a77..210afcca10 100644
--- a/util/PostgresMigrations/HelperScripts/2023-12-06_01_AccessAllCollectionUsers.psql
+++ b/util/PostgresMigrations/HelperScripts/2023-12-06_01_AccessAllCollectionUsers.psql
@@ -1,51 +1,22 @@
--- Step 1: Insert into a temporary table with an additional column for batch processing, update 50 k at a time
-CREATE TEMPORARY TABLE "TempOrgUser" AS
-SELECT "Id" AS "OrganizationUserId", "OrganizationId", CAST(ROW_NUMBER() OVER(ORDER BY "Id") / 50000 AS INT) AS "Batch"
-FROM "OrganizationUser"
-WHERE "AccessAll" = true;
-
--- Step 2: Get the maximum batch number
-DO $$
-DECLARE
-MaxBatch INT;
- CurrentBatch INT := 0;
-BEGIN
-SELECT MAX("Batch") INTO MaxBatch FROM "TempOrgUser";
-
--- Step 3: Process each batch
-WHILE CurrentBatch <= MaxBatch LOOP
- -- Update existing rows in "CollectionUsers"
-UPDATE "CollectionUsers" AS target
+-- Update existing rows in CollectionUsers
+UPDATE "CollectionUsers"
SET
"ReadOnly" = false,
"HidePasswords" = false,
"Manage" = false
- FROM (
- SELECT "C"."Id" AS "CollectionId", "T"."OrganizationUserId"
- FROM "Collection" "C"
- INNER JOIN "TempOrgUser" "T" ON "C"."OrganizationId" = "T"."OrganizationId" AND "T"."Batch" = CurrentBatch
- ) AS source
-WHERE target."CollectionId" = source."CollectionId" AND target."OrganizationUserId" = source."OrganizationUserId";
+FROM "Collection" AS C
+INNER JOIN "CollectionUsers" AS CU ON CU."CollectionId" = C."Id"
+INNER JOIN "OrganizationUser" AS OU ON CU."CollectionId" = C."Id" AND C."OrganizationId" = OU."OrganizationId"
+WHERE OU."AccessAll" = true;
--- Insert new rows into "CollectionUsers"
+-- Insert new rows into CollectionUsers
INSERT INTO "CollectionUsers" ("CollectionId", "OrganizationUserId", "ReadOnly", "HidePasswords", "Manage")
-SELECT source."CollectionId", source."OrganizationUserId", false, false, false
-FROM (
- SELECT "C"."Id" AS "CollectionId", "T"."OrganizationUserId"
- FROM "Collection" "C"
- INNER JOIN "TempOrgUser" "T" ON "C"."OrganizationId" = "T"."OrganizationId" AND "T"."Batch" = CurrentBatch
- ) AS source
-WHERE NOT EXISTS (
+SELECT C."Id" AS "CollectionId", OU."Id" AS "OrganizationUserId", false, false, false
+FROM "Collection" AS C
+INNER JOIN "OrganizationUser" AS OU ON C."OrganizationId" = OU."OrganizationId"
+WHERE OU."AccessAll" = true
+ AND NOT EXISTS (
SELECT 1
- FROM "CollectionUsers" target
- WHERE target."CollectionId" = source."CollectionId" AND target."OrganizationUserId" = source."OrganizationUserId"
+ FROM "CollectionUsers" AS CU
+ WHERE CU."CollectionId" = C."Id" AND CU."OrganizationUserId" = OU."Id"
);
-
--- Move to the next batch
-CurrentBatch := CurrentBatch + 1;
-END LOOP;
-
-END $$;
-
--- Step 4: Drop the temporary table
-DROP TABLE "TempOrgUser";
diff --git a/util/PostgresMigrations/HelperScripts/2023-12-06_02_ManagersEditAssignedCollectionUsers.psql b/util/PostgresMigrations/HelperScripts/2023-12-06_02_ManagersEditAssignedCollectionUsers.psql
index f72a8bf23d..cbd972a12d 100644
--- a/util/PostgresMigrations/HelperScripts/2023-12-06_02_ManagersEditAssignedCollectionUsers.psql
+++ b/util/PostgresMigrations/HelperScripts/2023-12-06_02_ManagersEditAssignedCollectionUsers.psql
@@ -1,10 +1,24 @@
--- Update "CollectionUser" with "Manage" = 1 for all users with Manager role or 'EditAssignedCollections' permission
+-- Update `CollectionUsers` with `Manage` = 1 for all users with Manager role or 'EditAssignedCollections' permission
UPDATE "CollectionUsers" cu
-SET "ReadOnly" = false,
+SET
+ "ReadOnly" = false,
"HidePasswords" = false,
"Manage" = true
- FROM "OrganizationUser" ou
+FROM "OrganizationUser" ou
WHERE cu."OrganizationUserId" = ou."Id"
- AND (ou."Type" = 3 OR
+AND (ou."Type" = 3 OR
(ou."Permissions" IS NOT NULL AND
- (ou."Permissions"::text)::jsonb->>'editAssignedCollections' = 'true'));
+ ((ou."Permissions"::text)::jsonb->>'editAssignedCollections') = 'true'));
+
+-- Insert rows into CollectionUsers for Managers and users with 'EditAssignedCollections' permission assigned to groups with collection access
+INSERT INTO "CollectionUsers" ("CollectionId", "OrganizationUserId", "ReadOnly", "HidePasswords", "Manage")
+SELECT cg."CollectionId", ou."Id", false, false, true
+FROM "CollectionGroups" cg
+INNER JOIN "GroupUser" gu ON cg."GroupId" = gu."GroupId"
+INNER JOIN "OrganizationUser" ou ON gu."OrganizationUserId" = ou."Id"
+WHERE (ou."Type" = 3 OR
+ (ou."Permissions" IS NOT NULL AND
+ ((ou."Permissions"::text)::jsonb->>'editAssignedCollections') = 'true'))
+ AND NOT EXISTS (
+ SELECT 1 FROM "CollectionUsers" cu
+ WHERE cu."CollectionId" = cg."CollectionId" AND cu."OrganizationUserId" = ou."Id");
diff --git a/util/PostgresMigrations/Migrations/20231219154705_FCAccessAllCollectionGroups.Designer.cs b/util/PostgresMigrations/Migrations/20231219154705_FCAccessAllCollectionGroups.Designer.cs
new file mode 100644
index 0000000000..e2be7519fa
--- /dev/null
+++ b/util/PostgresMigrations/Migrations/20231219154705_FCAccessAllCollectionGroups.Designer.cs
@@ -0,0 +1,2333 @@
+//
+using System;
+using Bit.Infrastructure.EntityFramework.Repositories;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace Bit.PostgresMigrations.Migrations
+{
+ [DbContext(typeof(DatabaseContext))]
+ [Migration("20231219154705_FCAccessAllCollectionGroups")]
+ partial class FCAccessAllCollectionGroups
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("Npgsql:CollationDefinition:postgresIndetermanisticCollation", "en-u-ks-primary,en-u-ks-primary,icu,False")
+ .HasAnnotation("ProductVersion", "7.0.14")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Organization", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("AllowAdminAccessToAllCollectionItems")
+ .HasColumnType("boolean")
+ .HasDefaultValue(true);
+
+ b.Property("BillingEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("BusinessAddress1")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("BusinessAddress2")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("BusinessAddress3")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("BusinessCountry")
+ .HasMaxLength(2)
+ .HasColumnType("character varying(2)");
+
+ b.Property("BusinessName")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("BusinessTaxNumber")
+ .HasMaxLength(30)
+ .HasColumnType("character varying(30)");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("ExpirationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Gateway")
+ .HasColumnType("smallint");
+
+ b.Property("GatewayCustomerId")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("GatewaySubscriptionId")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("Identifier")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)")
+ .UseCollation("postgresIndetermanisticCollation");
+
+ b.Property("LicenseKey")
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)");
+
+ b.Property("LimitCollectionCreationDeletion")
+ .HasColumnType("boolean")
+ .HasDefaultValue(true);
+
+ b.Property("MaxAutoscaleSeats")
+ .HasColumnType("integer");
+
+ b.Property("MaxAutoscaleSmSeats")
+ .HasColumnType("integer");
+
+ b.Property("MaxAutoscaleSmServiceAccounts")
+ .HasColumnType("integer");
+
+ b.Property("MaxCollections")
+ .HasColumnType("smallint");
+
+ b.Property("MaxStorageGb")
+ .HasColumnType("smallint");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("OwnersNotifiedOfAutoscaling")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Plan")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("PlanType")
+ .HasColumnType("smallint");
+
+ b.Property("PrivateKey")
+ .HasColumnType("text");
+
+ b.Property("PublicKey")
+ .HasColumnType("text");
+
+ b.Property("ReferenceData")
+ .HasColumnType("text");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Seats")
+ .HasColumnType("integer");
+
+ b.Property("SecretsManagerBeta")
+ .HasColumnType("boolean");
+
+ b.Property("SelfHost")
+ .HasColumnType("boolean");
+
+ b.Property("SmSeats")
+ .HasColumnType("integer");
+
+ b.Property("SmServiceAccounts")
+ .HasColumnType("integer");
+
+ b.Property("Status")
+ .HasColumnType("smallint");
+
+ b.Property("Storage")
+ .HasColumnType("bigint");
+
+ b.Property("TwoFactorProviders")
+ .HasColumnType("text");
+
+ b.Property("Use2fa")
+ .HasColumnType("boolean");
+
+ b.Property("UseApi")
+ .HasColumnType("boolean");
+
+ b.Property("UseCustomPermissions")
+ .HasColumnType("boolean");
+
+ b.Property("UseDirectory")
+ .HasColumnType("boolean");
+
+ b.Property("UseEvents")
+ .HasColumnType("boolean");
+
+ b.Property("UseGroups")
+ .HasColumnType("boolean");
+
+ b.Property("UseKeyConnector")
+ .HasColumnType("boolean");
+
+ b.Property("UsePasswordManager")
+ .HasColumnType("boolean");
+
+ b.Property("UsePolicies")
+ .HasColumnType("boolean");
+
+ b.Property("UseResetPassword")
+ .HasColumnType("boolean");
+
+ b.Property("UseScim")
+ .HasColumnType("boolean");
+
+ b.Property("UseSecretsManager")
+ .HasColumnType("boolean");
+
+ b.Property("UseSso")
+ .HasColumnType("boolean");
+
+ b.Property("UseTotp")
+ .HasColumnType("boolean");
+
+ b.Property("UsersGetPremium")
+ .HasColumnType("boolean");
+
+ b.HasKey("Id");
+
+ b.ToTable("Organization", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Policy", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Data")
+ .HasColumnType("text");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Type")
+ .HasColumnType("smallint");
+
+ 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("uuid");
+
+ 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("timestamp with time zone");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("Name")
+ .HasColumnType("text");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Status")
+ .HasColumnType("smallint");
+
+ b.Property("Type")
+ .HasColumnType("smallint");
+
+ b.Property("UseEvents")
+ .HasColumnType("boolean");
+
+ b.HasKey("Id");
+
+ b.ToTable("Provider", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.AdminConsole.Models.Provider.ProviderOrganization", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Key")
+ .HasColumnType("text");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("ProviderId")
+ .HasColumnType("uuid");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ 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("uuid");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Email")
+ .HasColumnType("text");
+
+ b.Property("Key")
+ .HasColumnType("text");
+
+ b.Property("Permissions")
+ .HasColumnType("text");
+
+ b.Property("ProviderId")
+ .HasColumnType("uuid");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Status")
+ .HasColumnType("smallint");
+
+ b.Property("Type")
+ .HasColumnType("smallint");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ 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("uuid");
+
+ b.Property("AccessCode")
+ .HasMaxLength(25)
+ .HasColumnType("character varying(25)");
+
+ b.Property("Approved")
+ .HasColumnType("boolean");
+
+ b.Property("AuthenticationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Key")
+ .HasColumnType("text");
+
+ b.Property("MasterPasswordHash")
+ .HasColumnType("text");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("PublicKey")
+ .HasColumnType("text");
+
+ b.Property("RequestDeviceIdentifier")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("RequestDeviceType")
+ .HasColumnType("smallint");
+
+ b.Property("RequestIpAddress")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("ResponseDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ResponseDeviceId")
+ .HasColumnType("uuid");
+
+ b.Property("Type")
+ .HasColumnType("smallint");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ 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("uuid");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("GranteeId")
+ .HasColumnType("uuid");
+
+ b.Property("GrantorId")
+ .HasColumnType("uuid");
+
+ b.Property("KeyEncrypted")
+ .HasColumnType("text");
+
+ b.Property("LastNotificationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("RecoveryInitiatedDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Status")
+ .HasColumnType("smallint");
+
+ b.Property("Type")
+ .HasColumnType("smallint");
+
+ 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("Key")
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("ClientId")
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("ConsumedDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Data")
+ .HasColumnType("text");
+
+ b.Property("Description")
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("ExpirationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("SessionId")
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)");
+
+ b.Property("SubjectId")
+ .HasMaxLength(200)
+ .HasColumnType("character varying(200)");
+
+ b.Property("Type")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.HasKey("Key");
+
+ b.ToTable("Grant", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Auth.Models.SsoConfig", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Data")
+ .HasColumnType("text");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ 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");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ExternalId")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)")
+ .UseCollation("postgresIndetermanisticCollation");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ 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("uuid");
+
+ b.Property("AaGuid")
+ .HasColumnType("uuid");
+
+ b.Property("Counter")
+ .HasColumnType("integer");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CredentialId")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("EncryptedPrivateKey")
+ .HasMaxLength(2000)
+ .HasColumnType("character varying(2000)");
+
+ b.Property("EncryptedPublicKey")
+ .HasMaxLength(2000)
+ .HasColumnType("character varying(2000)");
+
+ b.Property("EncryptedUserKey")
+ .HasMaxLength(2000)
+ .HasColumnType("character varying(2000)");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("PublicKey")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("SupportsPrf")
+ .HasColumnType("boolean");
+
+ b.Property("Type")
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("WebAuthnCredential", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Collection", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ExternalId")
+ .HasMaxLength(300)
+ .HasColumnType("character varying(300)");
+
+ b.Property("Name")
+ .HasColumnType("text");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("Collection", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.CollectionCipher", b =>
+ {
+ b.Property("CollectionId")
+ .HasColumnType("uuid");
+
+ b.Property("CipherId")
+ .HasColumnType("uuid");
+
+ b.HasKey("CollectionId", "CipherId");
+
+ b.HasIndex("CipherId");
+
+ b.ToTable("CollectionCipher", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.CollectionGroup", b =>
+ {
+ b.Property("CollectionId")
+ .HasColumnType("uuid");
+
+ b.Property("GroupId")
+ .HasColumnType("uuid");
+
+ b.Property("HidePasswords")
+ .HasColumnType("boolean");
+
+ b.Property("Manage")
+ .HasColumnType("boolean");
+
+ b.Property("ReadOnly")
+ .HasColumnType("boolean");
+
+ b.HasKey("CollectionId", "GroupId");
+
+ b.HasIndex("GroupId");
+
+ b.ToTable("CollectionGroups");
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.CollectionUser", b =>
+ {
+ b.Property("CollectionId")
+ .HasColumnType("uuid");
+
+ b.Property("OrganizationUserId")
+ .HasColumnType("uuid");
+
+ b.Property("HidePasswords")
+ .HasColumnType("boolean");
+
+ b.Property("Manage")
+ .HasColumnType("boolean");
+
+ b.Property("ReadOnly")
+ .HasColumnType("boolean");
+
+ b.HasKey("CollectionId", "OrganizationUserId");
+
+ b.HasIndex("OrganizationUserId");
+
+ b.ToTable("CollectionUsers");
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Device", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("EncryptedPrivateKey")
+ .HasColumnType("text");
+
+ b.Property("EncryptedPublicKey")
+ .HasColumnType("text");
+
+ b.Property("EncryptedUserKey")
+ .HasColumnType("text");
+
+ b.Property("Identifier")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("Name")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("PushToken")
+ .HasMaxLength(255)
+ .HasColumnType("character varying(255)");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Type")
+ .HasColumnType("smallint");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("Device", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Event", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("ActingUserId")
+ .HasColumnType("uuid");
+
+ b.Property("CipherId")
+ .HasColumnType("uuid");
+
+ b.Property("CollectionId")
+ .HasColumnType("uuid");
+
+ b.Property("Date")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DeviceType")
+ .HasColumnType("smallint");
+
+ b.Property("DomainName")
+ .HasColumnType("text");
+
+ b.Property("GroupId")
+ .HasColumnType("uuid");
+
+ b.Property("InstallationId")
+ .HasColumnType("uuid");
+
+ b.Property("IpAddress")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("OrganizationUserId")
+ .HasColumnType("uuid");
+
+ b.Property("PolicyId")
+ .HasColumnType("uuid");
+
+ b.Property("ProviderId")
+ .HasColumnType("uuid");
+
+ b.Property("ProviderOrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("ProviderUserId")
+ .HasColumnType("uuid");
+
+ b.Property("SecretId")
+ .HasColumnType("uuid");
+
+ b.Property("ServiceAccountId")
+ .HasColumnType("uuid");
+
+ b.Property("SystemUser")
+ .HasColumnType("smallint");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.Property("UserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.ToTable("Event", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Group", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("AccessAll")
+ .HasColumnType("boolean");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("ExternalId")
+ .HasMaxLength(300)
+ .HasColumnType("character varying(300)");
+
+ b.Property("Name")
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("Group", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.GroupUser", b =>
+ {
+ b.Property("GroupId")
+ .HasColumnType("uuid");
+
+ b.Property("OrganizationUserId")
+ .HasColumnType("uuid");
+
+ b.HasKey("GroupId", "OrganizationUserId");
+
+ b.HasIndex("OrganizationUserId");
+
+ b.ToTable("GroupUser", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.Installation", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("Key")
+ .HasMaxLength(150)
+ .HasColumnType("character varying(150)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Installation", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationApiKey", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("ApiKey")
+ .HasMaxLength(30)
+ .HasColumnType("character varying(30)");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("RevisionDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Type")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("OrganizationApiKey", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationConnection", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("Config")
+ .HasColumnType("text");
+
+ b.Property("Enabled")
+ .HasColumnType("boolean");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("Type")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("OrganizationConnection", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationDomain", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("CreationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("DomainName")
+ .HasMaxLength(255)
+ .HasColumnType("character varying(255)");
+
+ b.Property("JobRunCount")
+ .HasColumnType("integer");
+
+ b.Property("LastCheckedDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("NextRunDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("OrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("Txt")
+ .HasColumnType("text");
+
+ b.Property("VerifiedDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("OrganizationId");
+
+ b.ToTable("OrganizationDomain", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationSponsorship", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("FriendlyName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("LastSyncDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("OfferedToEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("PlanSponsorshipType")
+ .HasColumnType("smallint");
+
+ b.Property("SponsoredOrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("SponsoringOrganizationId")
+ .HasColumnType("uuid");
+
+ b.Property("SponsoringOrganizationUserId")
+ .HasColumnType("uuid");
+
+ b.Property("ToDelete")
+ .HasColumnType("boolean");
+
+ b.Property("ValidUntil")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.HasIndex("SponsoredOrganizationId");
+
+ b.HasIndex("SponsoringOrganizationId");
+
+ b.ToTable("OrganizationSponsorship", (string)null);
+ });
+
+ modelBuilder.Entity("Bit.Infrastructure.EntityFramework.Models.OrganizationUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("AccessAll")
+ .HasColumnType("boolean");
+
+ b.Property