/* * Add HiddenPassword support to collections */ IF OBJECT_ID('[dbo].[Group_CreateWithCollections]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[Group_CreateWithCollections] END GO IF OBJECT_ID('[dbo].[Group_UpdateWithCollections]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[Group_UpdateWithCollections] END GO IF OBJECT_ID('[dbo].[CollectionUser_UpdateUsers]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[CollectionUser_UpdateUsers] END GO IF OBJECT_ID('[dbo].[OrganizationUser_CreateWithCollections]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[OrganizationUser_CreateWithCollections] END GO IF OBJECT_ID('[dbo].[OrganizationUser_UpdateWithCollections]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[OrganizationUser_UpdateWithCollections] END GO IF OBJECT_ID('[dbo].[Collection_CreateWithGroups]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[Collection_CreateWithGroups] END GO IF OBJECT_ID('[dbo].[Collection_UpdateWithGroups]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[Collection_UpdateWithGroups] END GO IF TYPE_ID('[dbo].[SelectionReadOnlyArray]') IS NOT NULL BEGIN DROP TYPE [dbo].[SelectionReadOnlyArray] END GO CREATE TYPE [dbo].[SelectionReadOnlyArray] AS TABLE ( [Id] UNIQUEIDENTIFIER NOT NULL, [ReadOnly] BIT NOT NULL, [HidePasswords] BIT NOT NULL); GO IF COL_LENGTH('[dbo].[CollectionGroup]', 'HidePasswords') IS NULL BEGIN ALTER TABLE [dbo].[CollectionGroup] ADD [HidePasswords] BIT NULL END GO UPDATE [dbo].[CollectionGroup] SET [HidePasswords] = 0 WHERE [HidePasswords] IS NULL GO ALTER TABLE [dbo].[CollectionGroup] ALTER COLUMN [HidePasswords] BIT NOT NULL GO IF COL_LENGTH('[dbo].[CollectionUser]', 'HidePasswords') IS NULL BEGIN ALTER TABLE [dbo].[CollectionUser] ADD [HidePasswords] BIT NULL END GO UPDATE [dbo].[CollectionUser] SET [HidePasswords] = 0 WHERE [HidePasswords] IS NULL GO ALTER TABLE [dbo].[CollectionUser] ALTER COLUMN [HidePasswords] BIT NOT NULL GO IF OBJECT_ID('[dbo].[UserCipherDetails]') IS NOT NULL BEGIN DROP FUNCTION [dbo].[UserCipherDetails] END GO CREATE FUNCTION [dbo].[UserCipherDetails](@UserId UNIQUEIDENTIFIER) RETURNS TABLE AS RETURN WITH [CTE] AS ( SELECT [Id], [OrganizationId], [AccessAll] FROM [OrganizationUser] WHERE [UserId] = @UserId AND [Status] = 2 -- Confirmed ) SELECT C.*, CASE WHEN OU.[AccessAll] = 1 OR G.[AccessAll] = 1 OR COALESCE(CU.[ReadOnly], CG.[ReadOnly], 0) = 0 THEN 1 ELSE 0 END [Edit], CASE WHEN OU.[AccessAll] = 1 OR G.[AccessAll] = 1 OR COALESCE(CU.[HidePasswords], CG.[HidePasswords], 0) = 0 THEN 1 ELSE 0 END [ViewPassword], CASE WHEN O.[UseTotp] = 1 THEN 1 ELSE 0 END [OrganizationUseTotp] FROM [dbo].[CipherDetails](@UserId) C INNER JOIN [CTE] OU ON C.[UserId] IS NULL AND C.[OrganizationId] IN (SELECT [OrganizationId] FROM [CTE]) INNER JOIN [dbo].[Organization] O ON O.[Id] = OU.[OrganizationId] AND O.[Id] = C.[OrganizationId] AND O.[Enabled] = 1 LEFT JOIN [dbo].[CollectionCipher] CC ON OU.[AccessAll] = 0 AND CC.[CipherId] = C.[Id] LEFT JOIN [dbo].[CollectionUser] CU ON CU.[CollectionId] = CC.[CollectionId] AND CU.[OrganizationUserId] = OU.[Id] LEFT JOIN [dbo].[GroupUser] GU ON CU.[CollectionId] IS NULL AND OU.[AccessAll] = 0 AND GU.[OrganizationUserId] = OU.[Id] LEFT JOIN [dbo].[Group] G ON G.[Id] = GU.[GroupId] LEFT JOIN [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = CC.[CollectionId] AND CG.[GroupId] = GU.[GroupId] WHERE OU.[AccessAll] = 1 OR CU.[CollectionId] IS NOT NULL OR G.[AccessAll] = 1 OR CG.[CollectionId] IS NOT NULL UNION ALL SELECT *, 1 [Edit], 1 [ViewPassword], 0 [OrganizationUseTotp] FROM [dbo].[CipherDetails](@UserId) WHERE [UserId] = @UserId GO IF OBJECT_ID('[dbo].[UserCollectionDetails]') IS NOT NULL BEGIN DROP FUNCTION [dbo].[UserCollectionDetails] END GO CREATE FUNCTION [dbo].[UserCollectionDetails](@UserId UNIQUEIDENTIFIER) RETURNS TABLE AS RETURN SELECT C.*, CASE WHEN OU.[AccessAll] = 1 OR G.[AccessAll] = 1 OR COALESCE(CU.[ReadOnly], CG.[ReadOnly], 0) = 0 THEN 0 ELSE 1 END [ReadOnly], CASE WHEN OU.[AccessAll] = 1 OR G.[AccessAll] = 1 OR COALESCE(CU.[HidePasswords], CG.[HidePasswords], 0) = 0 THEN 0 ELSE 1 END [HidePasswords] FROM [dbo].[CollectionView] C INNER JOIN [dbo].[OrganizationUser] OU ON C.[OrganizationId] = OU.[OrganizationId] INNER JOIN [dbo].[Organization] O ON O.[Id] = C.[OrganizationId] LEFT JOIN [dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[CollectionId] = C.[Id] AND CU.[OrganizationUserId] = [OU].[Id] LEFT JOIN [dbo].[GroupUser] GU ON CU.[CollectionId] IS NULL AND OU.[AccessAll] = 0 AND GU.[OrganizationUserId] = OU.[Id] LEFT JOIN [dbo].[Group] G ON G.[Id] = GU.[GroupId] LEFT JOIN [dbo].[CollectionGroup] CG ON G.[AccessAll] = 0 AND CG.[CollectionId] = C.[Id] AND CG.[GroupId] = GU.[GroupId] WHERE OU.[UserId] = @UserId AND OU.[Status] = 2 -- 2 = Confirmed AND O.[Enabled] = 1 AND ( OU.[AccessAll] = 1 OR CU.[CollectionId] IS NOT NULL OR G.[AccessAll] = 1 OR CG.[CollectionId] IS NOT NULL ) GO IF OBJECT_ID('[dbo].[Collection_ReadWithGroupsById]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[Collection_ReadWithGroupsById] END GO CREATE PROCEDURE [dbo].[Collection_ReadWithGroupsById] @Id UNIQUEIDENTIFIER AS BEGIN SET NOCOUNT ON EXEC [dbo].[Collection_ReadById] @Id SELECT [GroupId] [Id], [ReadOnly], [HidePasswords] FROM [dbo].[CollectionGroup] WHERE [CollectionId] = @Id END GO CREATE PROCEDURE [dbo].[Group_CreateWithCollections] @Id UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @Name NVARCHAR(100), @AccessAll BIT, @ExternalId NVARCHAR(300), @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @Collections AS [dbo].[SelectionReadOnlyArray] READONLY AS BEGIN SET NOCOUNT ON EXEC [dbo].[Group_Create] @Id, @OrganizationId, @Name, @AccessAll, @ExternalId, @CreationDate, @RevisionDate ;WITH [AvailableCollectionsCTE] AS( SELECT [Id] FROM [dbo].[Collection] WHERE [OrganizationId] = @OrganizationId ) INSERT INTO [dbo].[CollectionGroup] ( [CollectionId], [GroupId], [ReadOnly], [HidePasswords] ) SELECT [Id], @Id, [ReadOnly], [HidePasswords] FROM @Collections WHERE [Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId END GO IF OBJECT_ID('[dbo].[Group_ReadWithCollectionsById]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[Group_ReadWithCollectionsById] END GO CREATE PROCEDURE [dbo].[Group_ReadWithCollectionsById] @Id UNIQUEIDENTIFIER AS BEGIN SET NOCOUNT ON EXEC [dbo].[Group_ReadById] @Id SELECT [CollectionId] [Id], [ReadOnly], [HidePasswords] FROM [dbo].[CollectionGroup] WHERE [GroupId] = @Id END GO CREATE PROCEDURE [dbo].[Group_UpdateWithCollections] @Id UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @Name NVARCHAR(100), @AccessAll BIT, @ExternalId NVARCHAR(300), @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @Collections AS [dbo].[SelectionReadOnlyArray] READONLY AS BEGIN SET NOCOUNT ON EXEC [dbo].[Group_Update] @Id, @OrganizationId, @Name, @AccessAll, @ExternalId, @CreationDate, @RevisionDate ;WITH [AvailableCollectionsCTE] AS( SELECT Id FROM [dbo].[Collection] WHERE OrganizationId = @OrganizationId ) MERGE [dbo].[CollectionGroup] AS [Target] USING @Collections AS [Source] ON [Target].[CollectionId] = [Source].[Id] AND [Target].[GroupId] = @Id WHEN NOT MATCHED BY TARGET AND [Source].[Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) THEN INSERT VALUES ( [Source].[Id], @Id, [Source].[ReadOnly], [Source].[HidePasswords] ) WHEN MATCHED AND ( [Target].[ReadOnly] != [Source].[ReadOnly] OR [Target].[HidePasswords] != [Source].[HidePasswords] ) THEN UPDATE SET [Target].[ReadOnly] = [Source].[ReadOnly], [Target].[HidePasswords] = [Source].[HidePasswords] WHEN NOT MATCHED BY SOURCE AND [Target].[GroupId] = @Id THEN DELETE ; EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId END GO CREATE PROCEDURE [dbo].[CollectionUser_UpdateUsers] @CollectionId UNIQUEIDENTIFIER, @Users AS [dbo].[SelectionReadOnlyArray] READONLY AS BEGIN SET NOCOUNT ON DECLARE @OrgId UNIQUEIDENTIFIER = ( SELECT TOP 1 [OrganizationId] FROM [dbo].[Collection] WHERE [Id] = @CollectionId ) -- Update UPDATE [Target] SET [Target].[ReadOnly] = [Source].[ReadOnly], [Target].[HidePasswords] = [Source].[HidePasswords] FROM [dbo].[CollectionUser] [Target] INNER JOIN @Users [Source] ON [Source].[Id] = [Target].[OrganizationUserId] WHERE [Target].[CollectionId] = @CollectionId AND ( [Target].[ReadOnly] != [Source].[ReadOnly] OR [Target].[HidePasswords] != [Source].[HidePasswords] ) -- Insert INSERT INTO [dbo].[CollectionUser] SELECT @CollectionId, [Source].[Id], [Source].[ReadOnly], [Source].[HidePasswords] FROM @Users [Source] INNER JOIN [dbo].[OrganizationUser] OU ON [Source].[Id] = OU.[Id] AND OU.[OrganizationId] = @OrgId WHERE NOT EXISTS ( SELECT 1 FROM [dbo].[CollectionUser] WHERE [CollectionId] = @CollectionId AND [OrganizationUserId] = [Source].[Id] ) -- Delete DELETE CU FROM [dbo].[CollectionUser] CU WHERE CU.[CollectionId] = @CollectionId AND NOT EXISTS ( SELECT 1 FROM @Users WHERE [Id] = CU.[OrganizationUserId] ) EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @CollectionId, @OrgId END GO IF OBJECT_ID('[dbo].[CollectionUser_ReadByCollectionId]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[CollectionUser_ReadByCollectionId] END GO CREATE PROCEDURE [dbo].[CollectionUser_ReadByCollectionId] @CollectionId UNIQUEIDENTIFIER AS BEGIN SET NOCOUNT ON SELECT [OrganizationUserId] [Id], [ReadOnly], [HidePasswords] FROM [dbo].[CollectionUser] WHERE [CollectionId] = @CollectionId END GO CREATE PROCEDURE [dbo].[OrganizationUser_CreateWithCollections] @Id UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER, @Email NVARCHAR(50), @Key VARCHAR(MAX), @Status TINYINT, @Type TINYINT, @AccessAll BIT, @ExternalId NVARCHAR(300), @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @Collections AS [dbo].[SelectionReadOnlyArray] READONLY AS BEGIN SET NOCOUNT ON EXEC [dbo].[OrganizationUser_Create] @Id, @OrganizationId, @UserId, @Email, @Key, @Status, @Type, @AccessAll, @ExternalId, @CreationDate, @RevisionDate ;WITH [AvailableCollectionsCTE] AS( SELECT [Id] FROM [dbo].[Collection] WHERE [OrganizationId] = @OrganizationId ) INSERT INTO [dbo].[CollectionUser] ( [CollectionId], [OrganizationUserId], [ReadOnly], [HidePasswords] ) SELECT [Id], @Id, [ReadOnly], [HidePasswords] FROM @Collections WHERE [Id] IN (SELECT [Id] FROM [AvailableCollectionsCTE]) END GO IF OBJECT_ID('[dbo].[OrganizationUser_ReadWithCollectionsById]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[OrganizationUser_ReadWithCollectionsById] END GO CREATE PROCEDURE [dbo].[OrganizationUser_ReadWithCollectionsById] @Id UNIQUEIDENTIFIER AS BEGIN SET NOCOUNT ON EXEC [OrganizationUser_ReadById] @Id SELECT CU.[CollectionId] Id, CU.[ReadOnly], CU.[HidePasswords] FROM [dbo].[OrganizationUser] OU INNER JOIN [dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[OrganizationUserId] = [OU].[Id] WHERE [OrganizationUserId] = @Id END GO CREATE PROCEDURE [dbo].[OrganizationUser_UpdateWithCollections] @Id UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER, @Email NVARCHAR(50), @Key VARCHAR(MAX), @Status TINYINT, @Type TINYINT, @AccessAll BIT, @ExternalId NVARCHAR(300), @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @Collections AS [dbo].[SelectionReadOnlyArray] READONLY AS BEGIN SET NOCOUNT ON EXEC [dbo].[OrganizationUser_Update] @Id, @OrganizationId, @UserId, @Email, @Key, @Status, @Type, @AccessAll, @ExternalId, @CreationDate, @RevisionDate -- Update UPDATE [Target] SET [Target].[ReadOnly] = [Source].[ReadOnly], [Target].[HidePasswords] = [Source].[HidePasswords] FROM [dbo].[CollectionUser] AS [Target] INNER JOIN @Collections AS [Source] ON [Source].[Id] = [Target].[CollectionId] WHERE [Target].[OrganizationUserId] = @Id AND ( [Target].[ReadOnly] != [Source].[ReadOnly] OR [Target].[HidePasswords] != [Source].[HidePasswords] ) -- Insert INSERT INTO [dbo].[CollectionUser] SELECT [Source].[Id], @Id, [Source].[ReadOnly], [Source].[HidePasswords] FROM @Collections AS [Source] INNER JOIN [dbo].[Collection] C ON C.[Id] = [Source].[Id] AND C.[OrganizationId] = @OrganizationId WHERE NOT EXISTS ( SELECT 1 FROM [dbo].[CollectionUser] WHERE [CollectionId] = [Source].[Id] AND [OrganizationUserId] = @Id ) -- Delete DELETE CU FROM [dbo].[CollectionUser] CU WHERE CU.[OrganizationUserId] = @Id AND NOT EXISTS ( SELECT 1 FROM @Collections WHERE [Id] = CU.[CollectionId] ) END GO IF OBJECT_ID('[dbo].[OrganizationUserUserDetails_ReadWithCollectionsById]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[OrganizationUserUserDetails_ReadWithCollectionsById] END GO CREATE PROCEDURE [dbo].[OrganizationUserUserDetails_ReadWithCollectionsById] @Id UNIQUEIDENTIFIER AS BEGIN SET NOCOUNT ON EXEC [OrganizationUserUserDetails_ReadById] @Id SELECT CU.[CollectionId] Id, CU.[ReadOnly], CU.[HidePasswords] FROM [dbo].[OrganizationUser] OU INNER JOIN [dbo].[CollectionUser] CU ON OU.[AccessAll] = 0 AND CU.[OrganizationUserId] = [OU].[Id] WHERE [OrganizationUserId] = @Id END GO CREATE PROCEDURE [dbo].[Collection_CreateWithGroups] @Id UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @Name VARCHAR(MAX), @ExternalId NVARCHAR(300), @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @Groups AS [dbo].[SelectionReadOnlyArray] READONLY AS BEGIN SET NOCOUNT ON EXEC [dbo].[Collection_Create] @Id, @OrganizationId, @Name, @ExternalId, @CreationDate, @RevisionDate ;WITH [AvailableGroupsCTE] AS( SELECT [Id] FROM [dbo].[Group] WHERE [OrganizationId] = @OrganizationId ) INSERT INTO [dbo].[CollectionGroup] ( [CollectionId], [GroupId], [ReadOnly], [HidePasswords] ) SELECT @Id, [Id], [ReadOnly], [HidePasswords] FROM @Groups WHERE [Id] IN (SELECT [Id] FROM [AvailableGroupsCTE]) EXEC [dbo].[User_BumpAccountRevisionDateByOrganizationId] @OrganizationId END GO IF OBJECT_ID('[dbo].[Collection_ReadWithGroupsByIdUserId]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[Collection_ReadWithGroupsByIdUserId] END GO CREATE PROCEDURE [dbo].[Collection_ReadWithGroupsByIdUserId] @Id UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER AS BEGIN SET NOCOUNT ON EXEC [dbo].[Collection_ReadByIdUserId] @Id, @UserId SELECT [GroupId] [Id], [ReadOnly], [HidePasswords] FROM [dbo].[CollectionGroup] WHERE [CollectionId] = @Id END GO CREATE PROCEDURE [dbo].[Collection_UpdateWithGroups] @Id UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @Name VARCHAR(MAX), @ExternalId NVARCHAR(300), @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @Groups AS [dbo].[SelectionReadOnlyArray] READONLY AS BEGIN SET NOCOUNT ON EXEC [dbo].[Collection_Update] @Id, @OrganizationId, @Name, @ExternalId, @CreationDate, @RevisionDate ;WITH [AvailableGroupsCTE] AS( SELECT Id FROM [dbo].[Group] WHERE OrganizationId = @OrganizationId ) MERGE [dbo].[CollectionGroup] AS [Target] USING @Groups AS [Source] ON [Target].[CollectionId] = @Id AND [Target].[GroupId] = [Source].[Id] WHEN NOT MATCHED BY TARGET AND [Source].[Id] IN (SELECT [Id] FROM [AvailableGroupsCTE]) THEN INSERT VALUES ( @Id, [Source].[Id], [Source].[ReadOnly], [Source].[HidePasswords] ) WHEN MATCHED AND ( [Target].[ReadOnly] != [Source].[ReadOnly] OR [Target].[HidePasswords] != [Source].[HidePasswords] ) THEN UPDATE SET [Target].[ReadOnly] = [Source].[ReadOnly], [Target].[HidePasswords] = [Source].[HidePasswords] WHEN NOT MATCHED BY SOURCE AND [Target].[CollectionId] = @Id THEN DELETE ; EXEC [dbo].[User_BumpAccountRevisionDateByCollectionId] @Id, @OrganizationId END GO IF OBJECT_ID('[dbo].[CipherDetails_Update]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[CipherDetails_Update] END GO CREATE PROCEDURE [dbo].[CipherDetails_Update] @Id UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @Type TINYINT, @Data NVARCHAR(MAX), @Favorites NVARCHAR(MAX), -- not used @Folders NVARCHAR(MAX), -- not used @Attachments NVARCHAR(MAX), -- not used @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @FolderId UNIQUEIDENTIFIER, @Favorite BIT, @Edit BIT, -- not used @ViewPassword BIT, -- not used @OrganizationUseTotp BIT, -- not used @DeletedDate DATETIME2(2) AS BEGIN SET NOCOUNT ON DECLARE @UserIdKey VARCHAR(50) = CONCAT('"', @UserId, '"') DECLARE @UserIdPath VARCHAR(50) = CONCAT('$.', @UserIdKey) UPDATE [dbo].[Cipher] SET [UserId] = CASE WHEN @OrganizationId IS NULL THEN @UserId ELSE NULL END, [OrganizationId] = @OrganizationId, [Type] = @Type, [Data] = @Data, [Folders] = CASE WHEN @FolderId IS NOT NULL AND [Folders] IS NULL THEN CONCAT('{', @UserIdKey, ':"', @FolderId, '"', '}') WHEN @FolderId IS NOT NULL THEN JSON_MODIFY([Folders], @UserIdPath, CAST(@FolderId AS VARCHAR(50))) ELSE JSON_MODIFY([Folders], @UserIdPath, NULL) END, [Favorites] = CASE WHEN @Favorite = 1 AND [Favorites] IS NULL THEN CONCAT('{', @UserIdKey, ':true}') WHEN @Favorite = 1 THEN JSON_MODIFY([Favorites], @UserIdPath, CAST(1 AS BIT)) ELSE JSON_MODIFY([Favorites], @UserIdPath, NULL) END, [CreationDate] = @CreationDate, [RevisionDate] = @RevisionDate, [DeletedDate] = @DeletedDate WHERE [Id] = @Id IF @OrganizationId IS NOT NULL BEGIN EXEC [dbo].[User_BumpAccountRevisionDateByCipherId] @Id, @OrganizationId END ELSE IF @UserId IS NOT NULL BEGIN EXEC [dbo].[User_BumpAccountRevisionDate] @UserId END END GO IF OBJECT_ID('[dbo].[CipherDetails_Create]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[CipherDetails_Create] END GO CREATE PROCEDURE [dbo].[CipherDetails_Create] @Id UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @Type TINYINT, @Data NVARCHAR(MAX), @Favorites NVARCHAR(MAX), -- not used @Folders NVARCHAR(MAX), -- not used @Attachments NVARCHAR(MAX), -- not used @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @FolderId UNIQUEIDENTIFIER, @Favorite BIT, @Edit BIT, -- not used @ViewPassword BIT, -- not used @OrganizationUseTotp BIT, -- not used @DeletedDate DATETIME2(7) AS BEGIN SET NOCOUNT ON DECLARE @UserIdKey VARCHAR(50) = CONCAT('"', @UserId, '"') DECLARE @UserIdPath VARCHAR(50) = CONCAT('$.', @UserIdKey) INSERT INTO [dbo].[Cipher] ( [Id], [UserId], [OrganizationId], [Type], [Data], [Favorites], [Folders], [CreationDate], [RevisionDate], [DeletedDate] ) VALUES ( @Id, CASE WHEN @OrganizationId IS NULL THEN @UserId ELSE NULL END, @OrganizationId, @Type, @Data, CASE WHEN @Favorite = 1 THEN CONCAT('{', @UserIdKey, ':true}') ELSE NULL END, CASE WHEN @FolderId IS NOT NULL THEN CONCAT('{', @UserIdKey, ':"', @FolderId, '"', '}') ELSE NULL END, @CreationDate, @RevisionDate, @DeletedDate ) IF @OrganizationId IS NOT NULL BEGIN EXEC [dbo].[User_BumpAccountRevisionDateByCipherId] @Id, @OrganizationId END ELSE IF @UserId IS NOT NULL BEGIN EXEC [dbo].[User_BumpAccountRevisionDate] @UserId END END GO IF OBJECT_ID('[dbo].[CipherDetails_CreateWithCollections]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[CipherDetails_CreateWithCollections] END GO CREATE PROCEDURE [dbo].[CipherDetails_CreateWithCollections] @Id UNIQUEIDENTIFIER, @UserId UNIQUEIDENTIFIER, @OrganizationId UNIQUEIDENTIFIER, @Type TINYINT, @Data NVARCHAR(MAX), @Favorites NVARCHAR(MAX), -- not used @Folders NVARCHAR(MAX), -- not used @Attachments NVARCHAR(MAX), -- not used @CreationDate DATETIME2(7), @RevisionDate DATETIME2(7), @FolderId UNIQUEIDENTIFIER, @Favorite BIT, @Edit BIT, -- not used @ViewPassword BIT, -- not used @OrganizationUseTotp BIT, -- not used @DeletedDate DATETIME2(7), @CollectionIds AS [dbo].[GuidIdArray] READONLY AS BEGIN SET NOCOUNT ON EXEC [dbo].[CipherDetails_Create] @Id, @UserId, @OrganizationId, @Type, @Data, @Favorites, @Folders, @Attachments, @CreationDate, @RevisionDate, @FolderId, @Favorite, @Edit, @ViewPassword, @OrganizationUseTotp, @DeletedDate DECLARE @UpdateCollectionsSuccess INT EXEC @UpdateCollectionsSuccess = [dbo].[Cipher_UpdateCollections] @Id, @UserId, @OrganizationId, @CollectionIds END GO IF OBJECT_ID('[dbo].[CipherDetails_ReadWithoutOrganizationsByUserId]') IS NOT NULL BEGIN DROP PROCEDURE [dbo].[CipherDetails_ReadWithoutOrganizationsByUserId] END GO CREATE PROCEDURE [dbo].[CipherDetails_ReadWithoutOrganizationsByUserId] @UserId UNIQUEIDENTIFIER AS BEGIN SET NOCOUNT ON SELECT *, 1 [Edit], 1 [ViewPassword], 0 [OrganizationUseTotp] FROM [dbo].[CipherDetails](@UserId) WHERE [UserId] = @UserId END GO