From 832c1137aeae564d30ba493e0e4ce52ff4681113 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:45:28 -0400 Subject: [PATCH 01/11] feat: update sql proj --- ...nUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql | 1 + src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql b/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql index 269a297b6e2f..a2b98d127dfe 100644 --- a/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql +++ b/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql @@ -11,6 +11,7 @@ BEGIN U.[KdfIterations], U.[KdfMemory], U.[KdfParallelism], + U.[MasterPasswordSalt] AS [Salt], OU.[ResetPasswordKey], O.[PrivateKey] AS EncryptedPrivateKey FROM @OrganizationUserIds AS OUIDs diff --git a/src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql b/src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql index ee0d87742e8f..1e6ce2cb9b4c 100644 --- a/src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql +++ b/src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql @@ -8,7 +8,8 @@ BEGIN [Kdf], [KdfIterations], [KdfMemory], - [KdfParallelism] + [KdfParallelism], + [MasterPasswordSalt] AS [Salt] FROM [dbo].[User] WHERE From 31464d7f3d6722e14c696ac51497f1053edb2324 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:45:29 -0400 Subject: [PATCH 02/11] feat: add dapper migration scripts --- .../2026-03-06_00_AlterReadKdfByEmail.sql | 18 +++++++++++++ ...ntRecoveryDetailsByOrganizationUserIds.sql | 26 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql create mode 100644 util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql diff --git a/util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql b/util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql new file mode 100644 index 000000000000..6f3940a038fe --- /dev/null +++ b/util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql @@ -0,0 +1,18 @@ +CREATE OR ALTER PROCEDURE [dbo].[User_ReadKdfByEmail] + @Email NVARCHAR(256) +AS +BEGIN + SET NOCOUNT ON + + SELECT + [Kdf], + [KdfIterations], + [KdfMemory], + [KdfParallelism], + [MasterPasswordSalt] AS [Salt] + FROM + [dbo].[User] + WHERE + [Email] = @Email +END +GO diff --git a/util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql b/util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql new file mode 100644 index 000000000000..03d151bb5cc3 --- /dev/null +++ b/util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql @@ -0,0 +1,26 @@ +CREATE OR ALTER PROCEDURE [dbo].[OrganizationUser_ReadManyAccountRecoveryDetailsByOrganizationUserIds] + @OrganizationId UNIQUEIDENTIFIER, + @OrganizationUserIds AS [dbo].[GuidIdArray] READONLY +AS +BEGIN + SET NOCOUNT ON + + SELECT + OU.[Id] AS OrganizationUserId, + U.[Kdf], + U.[KdfIterations], + U.[KdfMemory], + U.[KdfParallelism], + U.[MasterPasswordSalt] AS [Salt], + OU.[ResetPasswordKey], + O.[PrivateKey] AS EncryptedPrivateKey + FROM @OrganizationUserIds AS OUIDs + INNER JOIN [dbo].[OrganizationUser] AS OU + ON OUIDs.[Id] = OU.[Id] + INNER JOIN [dbo].[Organization] AS O + ON OU.[OrganizationId] = O.[Id] + INNER JOIN [dbo].[User] U + ON U.[Id] = OU.[UserId] + WHERE OU.[OrganizationId] = @OrganizationId +END +GO From 9a14ce7e988d237599f335968a2a03dc4964ebb0 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:45:31 -0400 Subject: [PATCH 03/11] feat: use MasterPasswordSalt instead of Salt as return values for consistency in the SQL --- ...onUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql | 2 +- src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql | 2 +- util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql | 2 +- ...AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql b/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql index a2b98d127dfe..aa29b49e9391 100644 --- a/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql +++ b/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql @@ -11,7 +11,7 @@ BEGIN U.[KdfIterations], U.[KdfMemory], U.[KdfParallelism], - U.[MasterPasswordSalt] AS [Salt], + U.[MasterPasswordSalt], OU.[ResetPasswordKey], O.[PrivateKey] AS EncryptedPrivateKey FROM @OrganizationUserIds AS OUIDs diff --git a/src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql b/src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql index 1e6ce2cb9b4c..cd5d68e78b24 100644 --- a/src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql +++ b/src/Sql/dbo/Stored Procedures/User_ReadKdfByEmail.sql @@ -9,7 +9,7 @@ BEGIN [KdfIterations], [KdfMemory], [KdfParallelism], - [MasterPasswordSalt] AS [Salt] + [MasterPasswordSalt] FROM [dbo].[User] WHERE diff --git a/util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql b/util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql index 6f3940a038fe..88a630c88932 100644 --- a/util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql +++ b/util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql @@ -9,7 +9,7 @@ BEGIN [KdfIterations], [KdfMemory], [KdfParallelism], - [MasterPasswordSalt] AS [Salt] + [MasterPasswordSalt] FROM [dbo].[User] WHERE diff --git a/util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql b/util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql index 03d151bb5cc3..c60e93858923 100644 --- a/util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql +++ b/util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql @@ -11,7 +11,7 @@ BEGIN U.[KdfIterations], U.[KdfMemory], U.[KdfParallelism], - U.[MasterPasswordSalt] AS [Salt], + U.[MasterPasswordSalt], OU.[ResetPasswordKey], O.[PrivateKey] AS EncryptedPrivateKey FROM @OrganizationUserIds AS OUIDs From 1f542acc02ccb387fb9e4affef74f80392dc0451 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:48:43 -0400 Subject: [PATCH 04/11] chore: rename database migrations --- ...erReadKdfByEmail.sql => 2026-03-16_00_AlterReadKdfByEmail.sql} | 0 ..._AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename util/Migrator/DbScripts/{2026-03-06_00_AlterReadKdfByEmail.sql => 2026-03-16_00_AlterReadKdfByEmail.sql} (100%) rename util/Migrator/DbScripts/{2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql => 2026-03-16_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql} (100%) diff --git a/util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql b/util/Migrator/DbScripts/2026-03-16_00_AlterReadKdfByEmail.sql similarity index 100% rename from util/Migrator/DbScripts/2026-03-06_00_AlterReadKdfByEmail.sql rename to util/Migrator/DbScripts/2026-03-16_00_AlterReadKdfByEmail.sql diff --git a/util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql b/util/Migrator/DbScripts/2026-03-16_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql similarity index 100% rename from util/Migrator/DbScripts/2026-03-06_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql rename to util/Migrator/DbScripts/2026-03-16_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql From dc275a68b2bcbaba4453f528ef23ee6442269994 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:55:50 -0400 Subject: [PATCH 05/11] feat: add MasterPasswordSalt to dtos --- src/Core/Models/Data/UserKdfInformation.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Core/Models/Data/UserKdfInformation.cs b/src/Core/Models/Data/UserKdfInformation.cs index 0e5696e5816c..649e4d5e6fd9 100644 --- a/src/Core/Models/Data/UserKdfInformation.cs +++ b/src/Core/Models/Data/UserKdfInformation.cs @@ -8,4 +8,5 @@ public class UserKdfInformation public required int KdfIterations { get; set; } public int? KdfMemory { get; set; } public int? KdfParallelism { get; set; } + public string? MasterPasswordSalt {get; set; } } From 3ef201c335624b362b18a43a876255d72aae6d25 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:55:52 -0400 Subject: [PATCH 06/11] feat: add Null Coalesce to user entity --- src/Core/Entities/User.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Entities/User.cs b/src/Core/Entities/User.cs index 94dec8015b5d..5c72fb7af0b3 100644 --- a/src/Core/Entities/User.cs +++ b/src/Core/Entities/User.cs @@ -116,7 +116,7 @@ public class User : ITableObject, IStorableSubscriber, IRevisable, ITwoFac public string GetMasterPasswordSalt() { - return Email.ToLowerInvariant().Trim(); + return MasterPasswordSalt ?? Email.ToLowerInvariant().Trim(); } public void SetNewId() From 4175d1c3387d8a61a6e45141ce20f473275ad273 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:55:53 -0400 Subject: [PATCH 07/11] feat: add MasterPasswordSalt to EF response --- src/Core/Repositories/IUserRepository.cs | 2 -- .../Repositories/UserRepository.cs | 5 +++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Core/Repositories/IUserRepository.cs b/src/Core/Repositories/IUserRepository.cs index a5a8c4310b3e..322133ae2424 100644 --- a/src/Core/Repositories/IUserRepository.cs +++ b/src/Core/Repositories/IUserRepository.cs @@ -4,8 +4,6 @@ using Bit.Core.KeyManagement.UserKey; using Bit.Core.Models.Data; -#nullable enable - namespace Bit.Core.Repositories; public interface IUserRepository : IRepository diff --git a/src/Infrastructure.EntityFramework/Repositories/UserRepository.cs b/src/Infrastructure.EntityFramework/Repositories/UserRepository.cs index c364eeb8bc4c..b003d997bac1 100644 --- a/src/Infrastructure.EntityFramework/Repositories/UserRepository.cs +++ b/src/Infrastructure.EntityFramework/Repositories/UserRepository.cs @@ -73,7 +73,8 @@ public UserRepository(IServiceScopeFactory serviceScopeFactory, IMapper mapper) Kdf = e.Kdf, KdfIterations = e.KdfIterations, KdfMemory = e.KdfMemory, - KdfParallelism = e.KdfParallelism + KdfParallelism = e.KdfParallelism, + MasterPasswordSalt = e.MasterPasswordSalt }).SingleOrDefaultAsync(); } } @@ -307,7 +308,7 @@ public async Task SetV2AccountCryptographicStateAsync( userEntity.SecurityVersion = accountKeysData.SecurityStateData.SecurityVersion; userEntity.SignedPublicKey = accountKeysData.PublicKeyEncryptionKeyPairData.SignedPublicKey; - // Replace existing keypair if it exists + // Replace existing key-pair if it exists var existingKeyPair = await dbContext.UserSignatureKeyPairs .FirstOrDefaultAsync(x => x.UserId == userId); if (existingKeyPair != null) From bfcac6240b7fcc5a7e178dc7e77ac05d96217285 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:55:54 -0400 Subject: [PATCH 08/11] test: add or modify tests for affected repositories --- .../Repositories/UserRepositoryTests.cs | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/test/Infrastructure.IntegrationTest/Repositories/UserRepositoryTests.cs b/test/Infrastructure.IntegrationTest/Repositories/UserRepositoryTests.cs index 3bb3a70b0dc4..067eb0d68944 100644 --- a/test/Infrastructure.IntegrationTest/Repositories/UserRepositoryTests.cs +++ b/test/Infrastructure.IntegrationTest/Repositories/UserRepositoryTests.cs @@ -740,6 +740,103 @@ public async Task UpdateUserKeyAndEncryptedDataV2Async_InvokesUpdateDataActions( Assert.True(actionWasInvoked); } + [Theory, DatabaseData] + public async Task GetKdfInformationByEmailAsync_WithPbkdf2User_ReturnsKdfInformation( + IUserRepository userRepository) + { + // Arrange + var email = $"test+{Guid.NewGuid()}@example.com"; + var salt = "test-salt-value"; + await userRepository.CreateAsync(new User + { + Name = "Test User", + Email = email, + ApiKey = "TEST", + SecurityStamp = "stamp", + MasterPassword = "password_hash", + MasterPasswordSalt = salt, + Kdf = KdfType.PBKDF2_SHA256, + KdfIterations = AuthConstants.PBKDF2_ITERATIONS.Default, + }); + + // Act + var result = await userRepository.GetKdfInformationByEmailAsync(email); + + // Assert + Assert.NotNull(result); + Assert.Equal(KdfType.PBKDF2_SHA256, result.Kdf); + Assert.Equal(AuthConstants.PBKDF2_ITERATIONS.Default, result.KdfIterations); + Assert.Null(result.KdfMemory); + Assert.Null(result.KdfParallelism); + Assert.Equal(salt, result.MasterPasswordSalt); + } + + [Theory, DatabaseData] + public async Task GetKdfInformationByEmailAsync_WithArgon2idUser_ReturnsKdfInformationWithMemoryAndParallelism( + IUserRepository userRepository) + { + // Arrange + var email = $"test+{Guid.NewGuid()}@example.com"; + var salt = "argon2-salt-value"; + await userRepository.CreateAsync(new User + { + Name = "Test User", + Email = email, + ApiKey = "TEST", + SecurityStamp = "stamp", + MasterPassword = "password_hash", + MasterPasswordSalt = salt, + Kdf = KdfType.Argon2id, + KdfIterations = AuthConstants.ARGON2_ITERATIONS.Default, + KdfMemory = AuthConstants.ARGON2_MEMORY.Default, + KdfParallelism = AuthConstants.ARGON2_PARALLELISM.Default, + }); + + // Act + var result = await userRepository.GetKdfInformationByEmailAsync(email); + + // Assert + Assert.NotNull(result); + Assert.Equal(KdfType.Argon2id, result.Kdf); + Assert.Equal(AuthConstants.ARGON2_ITERATIONS.Default, result.KdfIterations); + Assert.Equal(AuthConstants.ARGON2_MEMORY.Default, result.KdfMemory); + Assert.Equal(AuthConstants.ARGON2_PARALLELISM.Default, result.KdfParallelism); + Assert.Equal(salt, result.MasterPasswordSalt); + } + + [Theory, DatabaseData] + public async Task GetKdfInformationByEmailAsync_WithNoMasterPassword_ReturnsNullSalt( + IUserRepository userRepository) + { + // Arrange + var email = $"test+{Guid.NewGuid()}@example.com"; + await userRepository.CreateAsync(new User + { + Name = "Test User", + Email = email, + ApiKey = "TEST", + SecurityStamp = "stamp", + }); + + // Act + var result = await userRepository.GetKdfInformationByEmailAsync(email); + + // Assert + Assert.NotNull(result); + Assert.Null(result.MasterPasswordSalt); + } + + [Theory, DatabaseData] + public async Task GetKdfInformationByEmailAsync_WithNonExistentEmail_ReturnsNull( + IUserRepository userRepository) + { + // Act + var result = await userRepository.GetKdfInformationByEmailAsync($"nonexistent+{Guid.NewGuid()}@example.com"); + + // Assert + Assert.Null(result); + } + private static async Task RunUpdateUserDataAsync(UpdateUserData task, Database database) { if (database.Type == SupportedDatabaseProviders.SqlServer && !database.UseEf) From 01a8eacc7bb9f515dfeb9238fa422c11eb9ad24a Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:55:56 -0400 Subject: [PATCH 09/11] chore: dotnet format --- src/Core/Models/Data/UserKdfInformation.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Core/Models/Data/UserKdfInformation.cs b/src/Core/Models/Data/UserKdfInformation.cs index 649e4d5e6fd9..e5a463481672 100644 --- a/src/Core/Models/Data/UserKdfInformation.cs +++ b/src/Core/Models/Data/UserKdfInformation.cs @@ -8,5 +8,5 @@ public class UserKdfInformation public required int KdfIterations { get; set; } public int? KdfMemory { get; set; } public int? KdfParallelism { get; set; } - public string? MasterPasswordSalt {get; set; } + public string? MasterPasswordSalt { get; set; } } From 6505d0557a01e988cb2c88473b5ded0ccbb25459 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Mon, 16 Mar 2026 16:22:13 -0400 Subject: [PATCH 10/11] test: remove strict email check in EmergencyAccessTakeOverResponseModelTest --- .../EmergencyAccessTakeoverResponseModelTests.cs | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/Api.Test/Auth/Models/Response/EmergencyAccessTakeoverResponseModelTests.cs b/test/Api.Test/Auth/Models/Response/EmergencyAccessTakeoverResponseModelTests.cs index 1a46cb195655..5245c5494696 100644 --- a/test/Api.Test/Auth/Models/Response/EmergencyAccessTakeoverResponseModelTests.cs +++ b/test/Api.Test/Auth/Models/Response/EmergencyAccessTakeoverResponseModelTests.cs @@ -33,18 +33,6 @@ public void Constructor_ValidInputs_SetsAllPropertiesCorrectly( Assert.Equal(grantor.GetMasterPasswordSalt(), model.Salt); } - [Theory] - [BitAutoData] - public void Constructor_Salt_EqualsGrantorEmailLowercasedAndTrimmed( - EmergencyAccess emergencyAccess, User grantor) - { - grantor.Email = " TEST@Example.COM "; - - var model = new EmergencyAccessTakeoverResponseModel(emergencyAccess, grantor); - - Assert.Equal("test@example.com", model.Salt); - } - [Theory] [InlineData("user@domain.com", "user@domain.com")] [InlineData("USER@DOMAIN.COM", "user@domain.com")] From bc2aa7cfb43a30f484ccbbf3f6d145b46188c644 Mon Sep 17 00:00:00 2001 From: Ike Kottlowski Date: Tue, 17 Mar 2026 13:57:50 -0400 Subject: [PATCH 11/11] chore: migration script formatting --- ...ntRecoveryDetailsByOrganizationUserIds.sql} | 18 ++++++++++-------- ...untRecoveryDetailsByOrganizationUserIds.sql | 18 ++++++++++-------- 2 files changed, 20 insertions(+), 16 deletions(-) rename src/Sql/dbo/Stored Procedures/{OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql => OrganizationUser_ReadManyAccountRecoveryDetailsByOrganizationUserIds.sql} (59%) diff --git a/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql b/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyAccountRecoveryDetailsByOrganizationUserIds.sql similarity index 59% rename from src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql rename to src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyAccountRecoveryDetailsByOrganizationUserIds.sql index aa29b49e9391..808bc66dbd94 100644 --- a/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyResetPasswordDetailsByOrganizationUserIds.sql +++ b/src/Sql/dbo/Stored Procedures/OrganizationUser_ReadManyAccountRecoveryDetailsByOrganizationUserIds.sql @@ -14,12 +14,14 @@ BEGIN U.[MasterPasswordSalt], OU.[ResetPasswordKey], O.[PrivateKey] AS EncryptedPrivateKey - FROM @OrganizationUserIds AS OUIDs - INNER JOIN [dbo].[OrganizationUser] AS OU - ON OUIDs.[Id] = OU.[Id] - INNER JOIN [dbo].[Organization] AS O - ON OU.[OrganizationId] = O.[Id] - INNER JOIN [dbo].[User] U - ON U.[Id] = OU.[UserId] - WHERE OU.[OrganizationId] = @OrganizationId + FROM + @OrganizationUserIds AS OUIDs + INNER JOIN + [dbo].[OrganizationUser] AS OU ON OUIDs.[Id] = OU.[Id] + INNER JOIN + [dbo].[Organization] AS O ON OU.[OrganizationId] = O.[Id] + INNER JOIN + [dbo].[User] U ON U.[Id] = OU.[UserId] + WHERE + OU.[OrganizationId] = @OrganizationId END diff --git a/util/Migrator/DbScripts/2026-03-16_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql b/util/Migrator/DbScripts/2026-03-16_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql index c60e93858923..27bf95c196b2 100644 --- a/util/Migrator/DbScripts/2026-03-16_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql +++ b/util/Migrator/DbScripts/2026-03-16_01_AlterReadManyAccountRecoveryDetailsByOrganizationUserIds.sql @@ -14,13 +14,15 @@ BEGIN U.[MasterPasswordSalt], OU.[ResetPasswordKey], O.[PrivateKey] AS EncryptedPrivateKey - FROM @OrganizationUserIds AS OUIDs - INNER JOIN [dbo].[OrganizationUser] AS OU - ON OUIDs.[Id] = OU.[Id] - INNER JOIN [dbo].[Organization] AS O - ON OU.[OrganizationId] = O.[Id] - INNER JOIN [dbo].[User] U - ON U.[Id] = OU.[UserId] - WHERE OU.[OrganizationId] = @OrganizationId + FROM + @OrganizationUserIds AS OUIDs + INNER JOIN + [dbo].[OrganizationUser] AS OU ON OUIDs.[Id] = OU.[Id] + INNER JOIN + [dbo].[Organization] AS O ON OU.[OrganizationId] = O.[Id] + INNER JOIN + [dbo].[User] U ON U.[Id] = OU.[UserId] + WHERE + OU.[OrganizationId] = @OrganizationId END GO