1
0
mirror of https://github.com/bitwarden/server synced 2026-02-13 15:04:03 +00:00

[PM-27281] Support v2 account encryption on JIT master password signups (#6777)

* V2 prep, rename existing SSO JIT MP command to V1

* set initial master password for account registraton V2

* later removel docs

* TDE MP onboarding split

* revert separate TDE onboarding controller api

* Server side hash of the user master password hash

* use `ValidationResult` instead for validation errors

* unit test coverage

* integration test coverage

* update sql migration script date

* revert validate password change

* better requests validation

* explicit error message when org sso identifier invalid

* more unit test coverage

* renamed onboarding to set, hash naming clarifications

* update db sql script, formatting

* use raw json as request instead of request models for integration test

* v1 integration test coverage

* change of name
This commit is contained in:
Maciej Zieniuk
2026-01-09 09:17:45 +01:00
committed by GitHub
parent 62ae828143
commit 2e92a53f11
25 changed files with 2642 additions and 279 deletions

View File

@@ -510,6 +510,51 @@ public class UserRepository : Repository<Core.Entities.User, User, Guid>, IUserR
};
}
public UpdateUserData SetMasterPassword(Guid userId, MasterPasswordUnlockData masterPasswordUnlockData,
string serverSideHashedMasterPasswordAuthenticationHash, string? masterPasswordHint)
{
return async (_, _) =>
{
using var scope = ServiceScopeFactory.CreateScope();
var dbContext = GetDatabaseContext(scope);
var userEntity = await dbContext.Users.FindAsync(userId);
if (userEntity == null)
{
throw new ArgumentException("User not found", nameof(userId));
}
var timestamp = DateTime.UtcNow;
userEntity.MasterPassword = serverSideHashedMasterPasswordAuthenticationHash;
userEntity.MasterPasswordHint = masterPasswordHint;
userEntity.Key = masterPasswordUnlockData.MasterKeyWrappedUserKey;
userEntity.Kdf = masterPasswordUnlockData.Kdf.KdfType;
userEntity.KdfIterations = masterPasswordUnlockData.Kdf.Iterations;
userEntity.KdfMemory = masterPasswordUnlockData.Kdf.Memory;
userEntity.KdfParallelism = masterPasswordUnlockData.Kdf.Parallelism;
userEntity.RevisionDate = timestamp;
userEntity.AccountRevisionDate = timestamp;
await dbContext.SaveChangesAsync();
};
}
public async Task UpdateUserDataAsync(IEnumerable<UpdateUserData> updateUserDataActions)
{
using var scope = ServiceScopeFactory.CreateScope();
var dbContext = GetDatabaseContext(scope);
await using var transaction = await dbContext.Database.BeginTransactionAsync();
foreach (var action in updateUserDataActions)
{
await action();
}
await transaction.CommitAsync();
}
private static void MigrateDefaultUserCollectionsToShared(DatabaseContext dbContext, IEnumerable<Guid> userIds)
{
var defaultCollections = (from c in dbContext.Collections