From 1535fa35d33afcd7320050dc6904f899f10fa73a Mon Sep 17 00:00:00 2001 From: Patrick Pimentel Date: Tue, 9 Dec 2025 17:08:54 -0500 Subject: [PATCH] feat(register): [PM-27084] Account Register Uses New Data Types - Fixed up reference to master password hash --- .../Accounts/RegisterFinishRequestModel.cs | 8 ++-- .../Controllers/AccountsController.cs | 40 ++++++++++++++----- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/Core/Auth/Models/Api/Request/Accounts/RegisterFinishRequestModel.cs b/src/Core/Auth/Models/Api/Request/Accounts/RegisterFinishRequestModel.cs index 92cafbfe7b..3ef3e8fb68 100644 --- a/src/Core/Auth/Models/Api/Request/Accounts/RegisterFinishRequestModel.cs +++ b/src/Core/Auth/Models/Api/Request/Accounts/RegisterFinishRequestModel.cs @@ -25,9 +25,9 @@ public class RegisterFinishRequestModel : IValidatableObject public MasterPasswordAuthenticationData? MasterPasswordAuthenticationData { get; set; } public MasterPasswordUnlockData? MasterPasswordUnlockData { get; set; } - // PM-28143 - Made to be optional as migrating to MasterPasswordUnlockData + // PM-28143 - Remove line below (made optional during migration to MasterPasswordUnlockData [StringLength(1000)] - public required string? MasterPasswordHash { get; set; } + public string? MasterPasswordHash { get; set; } [StringLength(50)] public string? MasterPasswordHint { get; set; } @@ -62,8 +62,8 @@ public class RegisterFinishRequestModel : IValidatableObject { Email = Email, MasterPasswordHint = MasterPasswordHint, - Kdf = MasterPasswordUnlockData?.Kdf.KdfType ?? Kdf ?? throw new Exception($"{nameof(Kdf)} is required"), - KdfIterations = MasterPasswordUnlockData?.Kdf.Iterations ?? KdfIterations ?? throw new Exception($"{nameof(KdfIterations)} is required"), + Kdf = MasterPasswordUnlockData?.Kdf.KdfType ?? Kdf ?? throw new Exception("KdfType couldn't be found on either the MasterPasswordUnlockData or the Kdf property passed in."), + KdfIterations = MasterPasswordUnlockData?.Kdf.Iterations ?? KdfIterations ?? throw new Exception("KdfIterations couldn't be found on either the MasterPasswordUnlockData or the KdfIterations property passed in."), KdfMemory = MasterPasswordUnlockData?.Kdf.Memory ?? KdfMemory, KdfParallelism = MasterPasswordUnlockData?.Kdf.Parallelism ?? KdfParallelism, // PM-28827 To be added when MasterPasswordSalt is added to the user column diff --git a/src/Identity/Controllers/AccountsController.cs b/src/Identity/Controllers/AccountsController.cs index b7d4342c1b..57155b640a 100644 --- a/src/Identity/Controllers/AccountsController.cs +++ b/src/Identity/Controllers/AccountsController.cs @@ -145,37 +145,59 @@ public class AccountsController : Controller [HttpPost("register/finish")] public async Task PostRegisterFinish([FromBody] RegisterFinishRequestModel model) { - var user = model.ToUser(); + User user; + + try + { + user = model.ToUser(); + } + catch (Exception e) + { + throw new BadRequestException(e.Message); + } // Users will either have an emailed token or an email verification token - not both. IdentityResult identityResult = null; + // PM-28143 - Just use the MasterPasswordAuthenticationData.MasterPasswordAuthenticationHash + string masterPasswordHash = model.MasterPasswordAuthenticationData?.MasterPasswordAuthenticationHash + ?? model.MasterPasswordHash ?? throw new BadRequestException("MasterPasswordHash couldn't be found on either the MasterPasswordAuthenticationData or the MasterPasswordHash property passed in."); + switch (model.GetTokenType()) { case RegisterFinishTokenType.EmailVerification: - identityResult = - await _registerUserCommand.RegisterUserViaEmailVerificationToken(user, model.MasterPasswordHash, - model.EmailVerificationToken); - + identityResult = await _registerUserCommand.RegisterUserViaEmailVerificationToken( + user, + masterPasswordHash, + model.EmailVerificationToken); return ProcessRegistrationResult(identityResult, user); case RegisterFinishTokenType.OrganizationInvite: - identityResult = await _registerUserCommand.RegisterUserViaOrganizationInviteToken(user, model.MasterPasswordHash, + identityResult = await _registerUserCommand.RegisterUserViaOrganizationInviteToken( + user, + masterPasswordHash, model.OrgInviteToken, model.OrganizationUserId); return ProcessRegistrationResult(identityResult, user); case RegisterFinishTokenType.OrgSponsoredFreeFamilyPlan: - identityResult = await _registerUserCommand.RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken(user, model.MasterPasswordHash, model.OrgSponsoredFreeFamilyPlanToken); + identityResult = await _registerUserCommand.RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken( + user, + masterPasswordHash, + model.OrgSponsoredFreeFamilyPlanToken); return ProcessRegistrationResult(identityResult, user); case RegisterFinishTokenType.EmergencyAccessInvite: Debug.Assert(model.AcceptEmergencyAccessId.HasValue); - identityResult = await _registerUserCommand.RegisterUserViaAcceptEmergencyAccessInviteToken(user, model.MasterPasswordHash, + identityResult = await _registerUserCommand.RegisterUserViaAcceptEmergencyAccessInviteToken( + user, + masterPasswordHash, model.AcceptEmergencyAccessInviteToken, model.AcceptEmergencyAccessId.Value); return ProcessRegistrationResult(identityResult, user); case RegisterFinishTokenType.ProviderInvite: Debug.Assert(model.ProviderUserId.HasValue); - identityResult = await _registerUserCommand.RegisterUserViaProviderInviteToken(user, model.MasterPasswordHash, + identityResult = await _registerUserCommand.RegisterUserViaProviderInviteToken( + user, + masterPasswordHash, model.ProviderInviteToken, model.ProviderUserId.Value); return ProcessRegistrationResult(identityResult, user);