public async Task <IActionResult> HandleExternalLogin(string returnUrl = null, string remoteError = null) { if (remoteError != null) { return(BadRequest($"Error while login via external provider. Message = {remoteError}")); } var info = await loginService.GetExternalLoginInfoAsync(); var result = await loginService.CheckExternalProviderSignIn(info.LoginProvider, info.ProviderKey); await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); if (result) { var signedUser = await loginService.FindByEmailAsync(info.Principal.FindFirstValue(ClaimTypes.Email)); return(new OkObjectResult(await jwtService.GetJwtToken(signedUser))); } var userEmail = info.Principal.FindFirstValue(ClaimTypes.Email); if (string.IsNullOrEmpty(userEmail)) { return(BadRequest($"Email scope access is required to add {info.ProviderDisplayName} provider")); } var user = await loginService.FindByEmailAsync(userEmail); if (user != null) { if (!user.EmailConfirmed) { var token = await loginService.GenerateEmailConfirmationTokenAsync(user); var callbackUrl = Url.Action("ConfirmExternalProvider", "Account", values: new { userId = user.Id, code = token, loginProvider = info.LoginProvider, providerDisplayName = info.LoginProvider, providerKey = info.ProviderKey }, protocol: HttpContext.Request.Scheme); await emailService.SendEmailAsync(user.Email, $"Confirm {info.ProviderDisplayName} external login", $"Please confirm association of your {info.ProviderDisplayName} " + $"account by clicking <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>here</a>"); return(new OkObjectResult($"External account association with {info.ProviderDisplayName} is pending. Please check your email")); } await loginService.AddLoginAsync(user, info); return(new OkObjectResult(await jwtService.GetJwtToken(user))); } return(new OkObjectResult(new { Message = "Use this to associate your account with external provider", associate = userEmail, loginProvider = info.LoginProvider, providerDisplayName = info.ProviderDisplayName, providerKey = info.ProviderKey })); }