public async Task HandleAsync(AccountDeletedIntegrationEvent integrationEvent, CancellationToken cancellationToken = default) { try { var user = await _userRepository.GetByIdAsync(integrationEvent.AccountId); user.AddDeletedEvent(integrationEvent.CorrelationId); await _communicationBus.DispatchDomainEventsAsync(user, cancellationToken); await _userRepository.DeleteAsync(user); var userDeletedIntegrationEvent = new UserDeletedIntegrationEvent(integrationEvent.CorrelationId, user.Id); await _integrationEventBus.PublishIntegrationEventAsync(userDeletedIntegrationEvent); } catch (Exception e) { _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaUsers, integrationEvent, "userId={userId}, message={message}, stackTrace={stackTrace}", integrationEvent.AccountId, e.Message, e.StackTrace); var userDeletionCompletedIntegrationEventFailure = new UserDeletionCompletedIntegrationEventFailure( integrationEvent.CorrelationId, IntegrationEventErrorCodeEnumeration.UnexpectedError.DisplayName, IntegrationEventErrorMessage.UnexpectedError, integrationEvent.AccountId); await _integrationEventBus.PublishIntegrationEventAsync(userDeletionCompletedIntegrationEventFailure); } }
public async Task HandleAsync(UserCreationCompletedIntegrationEvent integrationEvent, CancellationToken cancellationToken = default) { try { var getAccountResult = await _accountGetterService.GetByIdAsync(integrationEvent.UserId); var accountCreationCompletedIntegrationEvent = new AccountCreationCompletedIntegrationEvent(integrationEvent.CorrelationId, getAccountResult.Value.Id); var publishIntegrationEvenTask = _integrationEventBus.PublishIntegrationEventAsync(accountCreationCompletedIntegrationEvent); var accountConfirmationToken = getAccountResult.Value.Tokens.SingleOrDefault(x => x.Type.Equals(TokenTypeEnumeration.AccountConfirmation)); if (accountConfirmationToken != null) { await _accountConfirmationRequestService.PublishAccountConfirmationRequestedIntegrationEventAsync( getAccountResult.Value.Email, accountConfirmationToken.Value, integrationEvent.CorrelationId); } await publishIntegrationEvenTask; } catch (Exception e) { _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaIdentity, integrationEvent, "accountId={accountId}, message={message}, stackTrace={stackTrace}", integrationEvent.UserId, e.Message, e.StackTrace); var accountCreationCompletedIntegrationEventFailure = new AccountCreationCompletedIntegrationEventFailure(integrationEvent.CorrelationId, IntegrationEventErrorCodeEnumeration.UnexpectedError.DisplayName, IntegrationEventErrorMessage.UnexpectedError, integrationEvent.UserId); await _integrationEventBus.PublishIntegrationEventAsync(accountCreationCompletedIntegrationEventFailure); } }
public async Task HandleAsync(AccountCreatedIntegrationEvent integrationEvent, CancellationToken cancellationToken = default) { try { var user = User.Builder() .SetId(integrationEvent.AccountId) .SetEmail(integrationEvent.Email) .SetServiceActive(DefaultUserSettings.ServiceActive) .SetAnnouncementPreferenceLimit(DefaultUserSettings.AnnouncementPreferenceLimit) .SetAnnouncementSendingFrequency(DefaultUserSettings.AnnouncementSendingFrequency) .SetPicture(integrationEvent.Picture) .Build(); user.AddCreatedEvent(integrationEvent.CorrelationId); await _communicationBus.DispatchDomainEventsAsync(user, cancellationToken); await _userRepository.AddAsync(user); var userCreationCompletedIntegrationEvent = new UserCreationCompletedIntegrationEvent(integrationEvent.CorrelationId, user.Id); await _integrationEventBus.PublishIntegrationEventAsync(userCreationCompletedIntegrationEvent); } catch (Exception e) { _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaUsers, integrationEvent, "userId={userId}, message={message}, stackTrace={stackTrace}", integrationEvent.AccountId, e.Message, e.StackTrace); var userCreationCompletedIntegrationEventFailure = new UserCreationCompletedIntegrationEventFailure( integrationEvent.CorrelationId, IntegrationEventErrorCodeEnumeration.UnexpectedError.DisplayName, IntegrationEventErrorMessage.UnexpectedError, integrationEvent.AccountId); await _integrationEventBus.PublishIntegrationEventAsync(userCreationCompletedIntegrationEventFailure); } }
public async Task HandleAsync(UpdateUserCommand command, CancellationToken cancellationToken = default) { var getUserResult = await _userGetterService.GetByIdAsync(command.UserId); if (!getUserResult.Success) { throw new ResourceNotFoundException(getUserResult.Errors); } UpdateAnnouncementPreferenceLimit(getUserResult.Value, command.AnnouncementPreferenceLimit, command.CorrelationId); UpdateAnnouncementSendingFrequency(getUserResult.Value, command.AnnouncementSendingFrequency, command.CorrelationId); getUserResult.Value.ChangeServiceActive(command.ServiceActive, command.CorrelationId); if (command.Picture != null && command.Picture.Data.Any()) { var pictureUrl = await _blobContainerService.UploadFileAsync(command.Picture.Data, $"image-{getUserResult.Value.Id.ToString().ToLower()}", command.Picture.ContentType); getUserResult.Value.ChangePicture(pictureUrl, command.CorrelationId); } await _communicationBus.DispatchDomainEventsAsync(getUserResult.Value, cancellationToken); await _userRepository.UpdateAsync(getUserResult.Value); var userUpdatedIntegrationEvent = new UserUpdatedIntegrationEvent(command.CorrelationId, getUserResult.Value.Id, getUserResult.Value.ServiceActive, getUserResult.Value.AnnouncementSendingFrequency.ConvertToEnum()); await _integrationEventBus.PublishIntegrationEventAsync(userUpdatedIntegrationEvent); }
public async Task HandleAsync(UserCreationCompletedIntegrationEventFailure integrationEvent, CancellationToken cancellationToken) { var message = $"Could not finish {nameof(Account)} creation process."; _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaIdentity, integrationEvent, "accountId={accountId}, message={message}, reason={reason}, code={code}", integrationEvent.UserId, message, integrationEvent.Reason, integrationEvent.Code); var accountCreationCompletedIntegrationEventFailure = new AccountCreationCompletedIntegrationEventFailure(integrationEvent.CorrelationId, integrationEvent.Code, integrationEvent.Reason, integrationEvent.UserId); var completeAccountCreationProcessWithFailureTask = _integrationEventBus.PublishIntegrationEventAsync(accountCreationCompletedIntegrationEventFailure); try { var getAccountResult = await _accountGetterService.GetByIdAsync(integrationEvent.UserId); await _accountDataConsistencyService.DeleteAccountWithRelatedPersistedGrants(getAccountResult.Value); } catch (Exception e) { _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaIdentity, integrationEvent, "accountId={accountId}, message={message}, stackTrace={stackTrace}", integrationEvent.UserId, e.Message, e.StackTrace); } finally { await completeAccountCreationProcessWithFailureTask; } }
public Task HandleAsync(UserDeletionCompletedIntegrationEvent integrationEvent, CancellationToken cancellationToken = default) { var accountDeletionCompletedIntegrationEvent = new AccountDeletionCompletedIntegrationEvent(integrationEvent.CorrelationId, integrationEvent.UserId); return(_integrationEventBus.PublishIntegrationEventAsync(accountDeletionCompletedIntegrationEvent)); }
public async Task HandleAsync(CreateFlatForRentAnnouncementPreferenceCommand command, CancellationToken cancellationToken = default) { var getUserResult = await _userGetterService.GetByIdAsync(command.UserId); if (!getUserResult.Success) { throw new ResourceNotFoundException(getUserResult.Errors); } var cityAndCityDistrictsVerificationResult = await _cityVerificationService.VerifyCityAndCityDistrictsAsync(command.CityId, command.CityDistricts); if (!cityAndCityDistrictsVerificationResult.Success) { throw new ValidationException(cityAndCityDistrictsVerificationResult.Errors); } var announcementPreferenceLimitIsNotExceededVerificationResult = _userVerificationService.VerifyAnnouncementPreferenceLimitIsNotExceeded( getUserResult.Value.AnnouncementPreferenceLimit, getUserResult.Value.FlatForRentAnnouncementPreferences.Count + getUserResult.Value.RoomForRentAnnouncementPreferences.Count); if (!announcementPreferenceLimitIsNotExceededVerificationResult.Success) { throw new ValidationException(announcementPreferenceLimitIsNotExceededVerificationResult.Errors); } var flatForRentAnnouncementPreference = _mapper.Map <CreateFlatForRentAnnouncementPreferenceCommand, FlatForRentAnnouncementPreference>(command); var flatForRentAnnouncementPreferences = getUserResult.Value.FlatForRentAnnouncementPreferences.ToList(); flatForRentAnnouncementPreferences.Add(flatForRentAnnouncementPreference); var flatForRentAnnouncementPreferencesVerificationResult = _flatForRentAnnouncementPreferenceVerificationService.VerifyFlatForRentAnnouncementPreferences(flatForRentAnnouncementPreferences); if (!flatForRentAnnouncementPreferencesVerificationResult.Success) { throw new ValidationException(flatForRentAnnouncementPreferencesVerificationResult.Errors); } getUserResult.Value.AddFlatForRentAnnouncementPreference(flatForRentAnnouncementPreference, command.CorrelationId); await _communicationBus.DispatchDomainEventsAsync(getUserResult.Value, cancellationToken); await _userRepository.UpdateAsync(getUserResult.Value); var userFlatForRentAnnouncementPreferenceCreatedIntegrationEvent = new UserFlatForRentAnnouncementPreferenceCreatedIntegrationEvent(command.CorrelationId, getUserResult.Value.Id, flatForRentAnnouncementPreference.Id, getUserResult.Value.Email, flatForRentAnnouncementPreference.CityId, getUserResult.Value.ServiceActive, getUserResult.Value.AnnouncementSendingFrequency.ConvertToEnum(), flatForRentAnnouncementPreference.PriceMin, flatForRentAnnouncementPreference.PriceMax, flatForRentAnnouncementPreference.RoomNumbersMin, flatForRentAnnouncementPreference.RoomNumbersMax, flatForRentAnnouncementPreference.CityDistricts); await _integrationEventBus.PublishIntegrationEventAsync(userFlatForRentAnnouncementPreferenceCreatedIntegrationEvent); }
public async Task HandleAsync(DeleteRoomForRentAnnouncementPreferenceCommand command, CancellationToken cancellationToken = default) { var getUserResult = await _userGetterService.GetByIdAsync(command.UserId); if (!getUserResult.Success) { throw new ResourceNotFoundException(getUserResult.Errors); } var getRoomForRentAnnouncementPreferenceResult = _roomForRentAnnouncementPreferenceGetterService.GetByByUserAndId( getUserResult.Value, command.RoomForRentAnnouncementPreferenceId); if (!getRoomForRentAnnouncementPreferenceResult.Success) { throw new ResourceNotFoundException(getRoomForRentAnnouncementPreferenceResult.Errors); } getUserResult.Value.DeleteRoomForRentAnnouncementPreference(getRoomForRentAnnouncementPreferenceResult.Value, command.CorrelationId); await _communicationBus.DispatchDomainEventsAsync(getUserResult.Value, cancellationToken); await _userRepository.UpdateAsync(getUserResult.Value); var userAnnouncementPreferenceDeletedIntegrationEvent = new UserAnnouncementPreferenceDeletedIntegrationEvent(command.CorrelationId, getUserResult.Value.Id, getRoomForRentAnnouncementPreferenceResult.Value.Id, AnnouncementPreferenceType.RoomForRentAnnouncementPreference); await _integrationEventBus.PublishIntegrationEventAsync(userAnnouncementPreferenceDeletedIntegrationEvent); }
public async Task HandleAsync(AnnouncementPreferenceCreationCompletedIntegrationEventFailure integrationEvent, CancellationToken cancellationToken = default) { var announcementPreferenceName = integrationEvent.AnnouncementPreferenceType == AnnouncementPreferenceType.FlatForRentAnnouncementPreference ? nameof(FlatForRentAnnouncementPreference) : nameof(RoomForRentAnnouncementPreference); var message = $"Could not finish {announcementPreferenceName} creation process."; _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaUsers, integrationEvent, "userId={userId}, message={message}, reason={reason}, code={code}", integrationEvent.UserId, message, integrationEvent.Reason, integrationEvent.Code); var userAnnouncementPreferenceCreationCompletedIntegrationEventFailure = new UserAnnouncementPreferenceCreationCompletedIntegrationEventFailure(integrationEvent.CorrelationId, integrationEvent.Code, integrationEvent.Reason, integrationEvent.UserId, integrationEvent.AnnouncementPreferenceId, integrationEvent.AnnouncementPreferenceType); var userAnnouncementPreferenceCreationCompletedIntegrationEventFailureTask = _integrationEventBus.PublishIntegrationEventAsync(userAnnouncementPreferenceCreationCompletedIntegrationEventFailure); try { await _userRevertService.RevertUserAsync(integrationEvent.UserId, integrationEvent.CorrelationId); } catch (Exception e) { _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaUsers, integrationEvent, "userId={userId}, message={message}, stackTrace={stackTrace}", integrationEvent.UserId, e.Message, e.StackTrace); } await userAnnouncementPreferenceCreationCompletedIntegrationEventFailureTask; }
public Task HandleAsync(AnnouncementPreferenceDeletionCompletedIntegrationEvent integrationEvent, CancellationToken cancellationToken = default) { var userAnnouncementPreferenceDeletionCompletedIntegrationEvent = new UserAnnouncementPreferenceDeletionCompletedIntegrationEvent(integrationEvent.CorrelationId, integrationEvent.UserId, integrationEvent.AnnouncementPreferenceId, integrationEvent.AnnouncementPreferenceType); return(_integrationEventBus.PublishIntegrationEventAsync(userAnnouncementPreferenceDeletionCompletedIntegrationEvent)); }
public Task PublishPasswordResetRequestedIntegrationEventAsync(string email, string token, Guid correlationId) { var url = new Uri($"{_resetPasswordUrl}?email={email}&code={token}"); var messageBody = $"Please use this <strong><a href={url}>link</a></strong> to reset Your password."; var integrationEvent = new PasswordResetRequestedIntegrationEvent(correlationId, email, messageBody); return(_integrationEventBus.PublishIntegrationEventAsync(integrationEvent)); }
public Task PublishAccountConfirmationRequestedIntegrationEventAsync(string email, string token, Guid correlationId) { var url = new Uri($"{_registrationConfirmationUrl}?email={email}&code={token}"); var messageBody = $"Please use this <strong><a href={url}>link</a></strong> to confirm Your account."; var integrationEvent = new AccountConfirmationRequestedIntegrationEvent(correlationId, email, messageBody); return(_integrationEventBus.PublishIntegrationEventAsync(integrationEvent)); }
public async Task HandleAsync(UpdateFlatForRentAnnouncementPreferenceCommand command, CancellationToken cancellationToken = default) { var getUserResult = await _userGetterService.GetByIdAsync(command.UserId); if (!getUserResult.Success) { throw new ResourceNotFoundException(getUserResult.Errors); } var getFlatForRentAnnouncementPreferenceResult = _flatForRentAnnouncementPreferenceGetterService.GetByByUserAndId( getUserResult.Value, command.FlatForRentAnnouncementPreferenceId); if (!getFlatForRentAnnouncementPreferenceResult.Success) { throw new ResourceNotFoundException(getFlatForRentAnnouncementPreferenceResult.Errors); } await UpdateCityAndCityDistrictsAsync(getFlatForRentAnnouncementPreferenceResult.Value, command.CityId, command.CityDistricts.ToList()); getFlatForRentAnnouncementPreferenceResult.Value.ChangePriceMin(command.PriceMin); getFlatForRentAnnouncementPreferenceResult.Value.ChangePriceMax(command.PriceMax); getFlatForRentAnnouncementPreferenceResult.Value.ChangeRoomNumbersMin(command.RoomNumbersMin); getFlatForRentAnnouncementPreferenceResult.Value.ChangeRoomNumbersMax(command.RoomNumbersMax); var flatForRentAnnouncementPreferencesVerificationResult = _flatForRentAnnouncementPreferenceVerificationService.VerifyFlatForRentAnnouncementPreferences(getUserResult.Value.FlatForRentAnnouncementPreferences); if (!flatForRentAnnouncementPreferencesVerificationResult.Success) { throw new ValidationException(flatForRentAnnouncementPreferencesVerificationResult.Errors); } getUserResult.Value.AddFlatForRentAnnouncementPreferenceChangedEvent(getFlatForRentAnnouncementPreferenceResult.Value, command.CorrelationId); await _communicationBus.DispatchDomainEventsAsync(getUserResult.Value, cancellationToken); await _userRepository.UpdateAsync(getUserResult.Value); var userFlatForRentAnnouncementPreferenceUpdatedIntegrationEvent = new UserFlatForRentAnnouncementPreferenceUpdatedIntegrationEvent(command.CorrelationId, getUserResult.Value.Id, getFlatForRentAnnouncementPreferenceResult.Value.Id, getFlatForRentAnnouncementPreferenceResult.Value.CityId, getFlatForRentAnnouncementPreferenceResult.Value.PriceMin, getFlatForRentAnnouncementPreferenceResult.Value.PriceMax, getFlatForRentAnnouncementPreferenceResult.Value.RoomNumbersMin, getFlatForRentAnnouncementPreferenceResult.Value.RoomNumbersMax, getFlatForRentAnnouncementPreferenceResult.Value.CityDistricts); await _integrationEventBus.PublishIntegrationEventAsync(userFlatForRentAnnouncementPreferenceUpdatedIntegrationEvent); }
public async Task HandleAsync(CreateAccountCommand command, CancellationToken cancellationToken = default) { var emailIsNotTakenVerificationResult = await _accountVerificationService.VerifyEmailIsNotTakenAsync(command.Email); if (!emailIsNotTakenVerificationResult.Success) { throw new ConflictException(emailIsNotTakenVerificationResult.Errors); } await _accountCreatorService.CreateAsync(command.AccountId, command.Email, command.Password, command.CorrelationId); var accountCreatedIntegrationEvent = new AccountCreatedIntegrationEvent(command.CorrelationId, command.AccountId, command.Email, string.Empty); await _integrationEventBus.PublishIntegrationEventAsync(accountCreatedIntegrationEvent); }
public async Task HandleAsync(DeleteAccountCommand command, CancellationToken cancellationToken = default) { var getAccountResult = await _accountGetterService.GetByIdAsync(command.AccountId); if (!getAccountResult.Success) { throw new ResourceNotFoundException(getAccountResult.Errors); } getAccountResult.Value.AddDeletedEvent(command.CorrelationId); await _communicationBus.DispatchDomainEventsAsync(getAccountResult.Value, cancellationToken); await _accountDataConsistencyService.DeleteAccountWithRelatedPersistedGrants(getAccountResult.Value); var accountDeletedIntegrationEvent = new AccountDeletedIntegrationEvent(command.CorrelationId, command.AccountId); await _integrationEventBus.PublishIntegrationEventAsync(accountDeletedIntegrationEvent); }
public async Task HandleAsync(UserDeletionCompletedIntegrationEventFailure integrationEvent, CancellationToken cancellationToken) { var message = $"Could not finish {nameof(Account)} deletion process."; _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaIdentity, integrationEvent, "accountId={accountId}, message={message}, reason={reason}, code={code}", integrationEvent.UserId, message, integrationEvent.Reason, integrationEvent.Code); var accountDeletionCompletedIntegrationEventFailure = new AccountDeletionCompletedIntegrationEventFailure( integrationEvent.CorrelationId, integrationEvent.Code, integrationEvent.Reason, integrationEvent.UserId); var accountDeletionCompletedIntegrationEventFailureTask = _integrationEventBus.PublishIntegrationEventAsync(accountDeletionCompletedIntegrationEventFailure); try { var domainEvents = await _domainEventStore.FindAllAsync(integrationEvent.UserId); var accountCreatedDomainEvent = (AccountCreatedDomainEvent)domainEvents.First(x => x is AccountCreatedDomainEvent); var account = Account.Builder() .SetId(accountCreatedDomainEvent.AggregateId) .SetEmail(accountCreatedDomainEvent.Email) .SetConfirmed(accountCreatedDomainEvent.Confirmed) .SetPasswordHash(accountCreatedDomainEvent.PasswordHash) .SetSecurityStamp(accountCreatedDomainEvent.SecurityStamp) .SetCreated(accountCreatedDomainEvent.Created) .SetLastLogin(accountCreatedDomainEvent.LastLogin) .Build(); await _accountRepository.AddAsync(account); account.AddEvents(domainEvents); account.ApplyEvents(); await _accountRepository.UpdateAsync(account); } catch (Exception e) { _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaIdentity, integrationEvent, "userId={userId}, message={message}, stackTrace={stackTrace}", integrationEvent.UserId, e.Message, e.StackTrace); } await accountDeletionCompletedIntegrationEventFailureTask; }
public async Task HandleAsync(AnnouncementPreferencesDeletionCompletedIntegrationEventFailure integrationEvent, CancellationToken cancellationToken = default) { var message = $"Could not finish {nameof(User)} deletion process."; _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaUsers, integrationEvent, "userId={userId}, message={message}, reason={reason}, code={code}", integrationEvent.UserId, message, integrationEvent.Reason, integrationEvent.Code); var userDeletionCompletedIntegrationEventFailure = new UserDeletionCompletedIntegrationEventFailure( integrationEvent.CorrelationId, integrationEvent.Code, integrationEvent.Reason, integrationEvent.UserId); var userDeletionCompletedIntegrationEventFailureTask = _integrationEventBus.PublishIntegrationEventAsync(userDeletionCompletedIntegrationEventFailure); try { var domainEvents = await _domainEventStore.FindAllAsync(integrationEvent.UserId); var userCreatedDomainEvent = (UserCreatedDomainEvent)domainEvents.First(x => x is UserCreatedDomainEvent); var user = User.Builder() .SetId(integrationEvent.UserId) .SetEmail(userCreatedDomainEvent.Email) .SetServiceActive(userCreatedDomainEvent.ServiceActive) .SetAnnouncementPreferenceLimit(userCreatedDomainEvent.AnnouncementPreferenceLimit) .SetAnnouncementSendingFrequency(userCreatedDomainEvent.AnnouncementSendingFrequency) .Build(); await _userRepository.AddAsync(user); user.AddEvents(domainEvents); user.ApplyEvents(); await _userRepository.UpdateAsync(user); } catch (Exception e) { _logger.LogIntegrationEventError(ServiceComponentEnumeration.RivaUsers, integrationEvent, "userId={userId}, message={message}, stackTrace={stackTrace}", integrationEvent.UserId, e.Message, e.StackTrace); } await userDeletionCompletedIntegrationEventFailureTask; }
public async Task <ExternalLoginResultOutput> ExecuteAsync(string scheme) { var authResult = await _authenticationService.AuthenticateAsync(scheme); if (!authResult.Succeeded) { throw authResult.Failure; } var emailClaim = authResult.Principal.FindFirst(ClaimTypes.Email); var correlationId = Guid.NewGuid(); var account = await _accountProviderService.ProvideAccountForExternalLoginAsync(emailClaim.Value, correlationId); if (account.DomainEvents.Any(x => x.GetType() == typeof(AccountCreatedDomainEvent))) { var pictureClaim = authResult.Principal.FindFirst("picture"); var picture = pictureClaim != null ? pictureClaim.Value : string.Empty; var accountCreatedIntegrationEvent = new AccountCreatedIntegrationEvent(correlationId, account.Id, account.Email, picture); await _integrationEventBus.PublishIntegrationEventAsync(accountCreatedIntegrationEvent); } var claims = await _accountClaimsCreatorService.CreateAccountClaimsAsync(account); var externalSignInTask = _signInService.ExternalSignInAsync(account.Id, account.Email, scheme, claims); var signOutTask = _signOutService.SignOutAsync(scheme); var returnUrl = authResult.Items is null || !authResult.Items.ContainsKey("returnUrl") || string.IsNullOrWhiteSpace(authResult.Items["returnUrl"]) ? "~/" : authResult.Items["returnUrl"]; var authRequest = await _authorizationService.GetAuthorizationRequestAsync(returnUrl); await Task.WhenAll(externalSignInTask, signOutTask); return(new ExternalLoginResultOutput(returnUrl, authRequest?.IsNativeClient)); }