public async Task <ActionResult <ApiResult <SessionPreview> > > LoginMfa([FromBody] MfaLoginModel data, CancellationToken cancellationToken = default) { if (data.ActionToken == null || data.MfaCode == null) { return(this.StatusCode(403, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.Unauthorized, "MFA state validation failed.")))); } var(stateId, clientTk) = this.UnpackState(data.ActionToken); var serverTk = await this.MfaStateRepository.ValidateStateAsync(this.HttpContext.Connection.RemoteIpAddress.ToString(), stateId, cancellationToken); var tokenPair = new ActionTokenPair(clientTk, serverTk); if (!this.ActionTokenPairHandler.ValidateTokenPair(tokenPair, TokenActionMFA)) { return(this.StatusCode(403, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.Unauthorized, "MFA state validation failed.")))); } var userId = BinaryPrimitives.ReadInt64BigEndian(clientTk.State); var mfa = await this.MfaRepository.GetMfaSettingsAsync(userId, cancellationToken); if (mfa == null || !mfa.IsConfirmed) { return(this.StatusCode(400, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.InvalidCredentials, "MFA not configured.")))); } if (data.MfaCode.Length == 6) { if (!this.MfaValidator.ValidateCode(data.MfaCode, mfa)) { return(this.StatusCode(403, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.InvalidCredentials, "Invalid MFA code provided.")))); } } else if (data.MfaCode.Length == 8) { if (!this.MfaValidator.ValidateRecoveryCode(data.MfaCode, mfa)) { return(this.StatusCode(403, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.InvalidCredentials, "Invalid MFA code provided.")))); } await this.MfaRepository.TripRecoveryCodeAsync(userId, cancellationToken); } else { return(this.StatusCode(403, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.InvalidCredentials, "Invalid MFA code provided.")))); } var user = await this.UserRepository.GetUserAsync(userId, cancellationToken); var ruser = this.UserPreviewRepository.GetUser(user); var token = this.Jwt.IssueToken(ruser); return(this.Ok(ApiResult.FromResult(this.UserPreviewRepository.GetSession(ruser, token.Token, token.ExpiresAt, user.RequiresMfa)))); }
public async Task <ActionResult <ApiResult <SessionPreview> > > MfaEnable([FromBody] MfaLoginModel data, CancellationToken cancellationToken = default) { var(stateId, clientTk) = this.UnpackState(data.ActionToken); var serverTk = await this.MfaStateRepository.ValidateStateAsync(this.HttpContext.Connection.RemoteIpAddress.ToString(), stateId, cancellationToken); var tokenPair = new ActionTokenPair(clientTk, serverTk); if (!this.ActionTokenPairHandler.ValidateTokenPair(tokenPair, TokenActionMFAConfigure)) { return(this.StatusCode(403, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.Unauthorized, "MFA state validation failed.")))); } var user = this.RosettaUser; var pwd = await this.UserRepository.GetUserPasswordAsync(user.Id, cancellationToken); if (pwd == null) { return(this.StatusCode(401, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.InvalidCredentials, "Specified credentials were invalid.")))); } var mfa = await this.MfaRepository.GetMfaSettingsAsync(user.Id, cancellationToken); if (mfa == null) { return(this.StatusCode(401, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.InvalidCredentials, "MFA not configured.")))); } if (mfa.IsConfirmed) { return(this.StatusCode(401, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.AlreadyConfigured, "MFA is already configured.")))); } if (!this.MfaValidator.ValidateCode(data.MfaCode, mfa)) { await this.MfaRepository.RemoveMfaAsync(user.Id, cancellationToken); return(this.StatusCode(403, ApiResult.FromError <SessionPreview>(new ApiError(ApiErrorCode.InvalidCredentials, "Invalid MFA code provided.")))); } await this.MfaRepository.ConfirmMfaAsync(user.Id, cancellationToken); var ruser = this.UserPreviewRepository.GetUser(user); var token = this.Jwt.IssueToken(ruser); return(this.Ok(ApiResult.FromResult(this.UserPreviewRepository.GetSession(ruser, token.Token, token.ExpiresAt, user.RequiresMfa)))); }