public async Task <IActionResult> SendPhoneNumberConfirmation() { var id = _manager.GetUserId(User); var systemUser = await _manager.FindByIdAsync(id); var token = await _manager.GenerateChangePhoneNumberTokenAsync(systemUser, systemUser.PhoneNumber); await _smsSender.SendPhoneNumberChangeConfirmationSMSAsync(systemUser.PhoneNumber, token); return(Ok()); }
public async Task <IActionResult> OnPostAsync() { if (!ModelState.IsValid) { return(Page()); } IList <IdentityResult> resultFinal = new List <IdentityResult>(); bool confirmationEmailSent = false; bool confirmationSmsSent = false; using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled)) { try { var id = _manager.GetUserId(User); var systemUser = await _manager.FindByIdAsync(id); if ((systemUser.NormalizedEmail != _manager.KeyNormalizer.Normalize(EditProfileViewModel.Email) || systemUser.PhoneNumber != EditProfileViewModel.PhoneNumber) && (string.IsNullOrWhiteSpace(Password) || !await _manager.CheckPasswordAsync(systemUser, Password))) { ModelState.AddModelError(nameof(Password), "Invalid password when changing email or phone number"); return(Page()); } EditProfileViewModel.UpdatedAt = DateTime.UtcNow; var newValues = EditProfileViewModel.ToClaims(); var currentValues = await _manager.GetClaimsAsync(systemUser); var toInsert = newValues.Where(nv => !currentValues.Select(c => c.Type).Distinct().Contains(nv.Type)); var toUpdate = newValues.Where(nv => currentValues.Select(c => c.Type).Distinct().Contains(nv.Type) && currentValues.Where(c => c.Type == nv.Type).Single().Value != newValues.Where(c => c.Type == nv.Type).Single().Value); var toRemove = currentValues.Where(ov => !newValues.Select(c => c.Type).Distinct().Contains(ov.Type) || string.IsNullOrWhiteSpace(newValues.Where(c => c.Type == ov.Type).Single().Value)); var resultAdd = await _manager.AddClaimsAsync(systemUser, toInsert); var resultRemove = await _manager.RemoveClaimsAsync(systemUser, toRemove); resultFinal.Add(resultAdd); resultFinal.Add(resultRemove); foreach (var newClaim in toUpdate) { var oldClaim = User.Claims.SingleOrDefault(c => c.Type == newClaim.Type); if (oldClaim != null) { resultFinal.Add(await _manager.ReplaceClaimAsync(systemUser, oldClaim, newClaim)); } } if (resultFinal.Any(r => !r.Succeeded)) { var errors = resultFinal.Where(r => !r.Succeeded); foreach (var error in errors.SelectMany(e => e.Errors)) { ModelState.AddModelError(error.Code, error.Description); } scope.Dispose(); return(Page()); } else { if (RefreshSignIn) { await _signInManager.SignInAsync(systemUser, RememberMe); } scope.Complete(); if (systemUser.NormalizedEmail != _manager.KeyNormalizer.Normalize(EditProfileViewModel.Email)) { var token = await _manager.GenerateChangeEmailTokenAsync(systemUser, EditProfileViewModel.Email); var callbackUrl = Url.Page("/Account/ConfirmEmail", pageHandler: null, values: new { userId = id, token, newEmail = EditProfileViewModel.Email }, protocol: Request.Scheme); await _emailSender.SendEmailConfirmationEmailAsync(EditProfileViewModel.Email, callbackUrl); confirmationEmailSent = true; } if (systemUser.PhoneNumber != EditProfileViewModel.PhoneNumber) { var token = await _manager.GenerateChangePhoneNumberTokenAsync(systemUser, EditProfileViewModel.PhoneNumber); var callbackUrl = Url.Page("/Account/ConfirmPhoneNumber", pageHandler: null, values: new { userId = id, token, newNumber = EditProfileViewModel.PhoneNumber }, protocol: Request.Scheme); await _smsSender.SendPhoneNumberChangeConfirmationSMSAsync(EditProfileViewModel.PhoneNumber, callbackUrl); confirmationSmsSent = true; } return(RedirectToPage("Index", new { profileUpdated = true, confirmationEmailSent, confirmationSmsSent })); } } catch (Exception) { scope.Dispose(); throw; } } }