protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <StartRequest> input, CacheItem relatedItem) { var wasContinued = CheckIfContinued(input, relatedItem); var composeInfo = new BaseJwtComposeInfo(input) { Behavior = GetNextBehaviorFunc(input, relatedItem), IncludeRequester = true }; var jwt = JwtComposer.GenerateBaseStepJwt(composeInfo, IdentitiesProvider.GenerateUserId()); if (!wasContinued) { await StartFlowCommand.ExecuteAsync(new StartFlowCommand.Input { Context = input.Context, ResponseJwt = jwt, CredIdCookieValue = input.Data.CredId, EncryptionTokenCookieValue = input.Data.EncryptionToken, RecoveryTokenCookieValue = input.Data.RecoveryToken, RequestToken = input.RequestToken }); } return(new JwtContainer { Jwt = jwt }); }
protected override async Task <ITransitionResult> ExecuteInternalAsync(TransitionInput <AcceptStartRequest> input, CacheItem relatedItem) { var composeInfo = new BaseJwtComposeInfo(input) { IncludeFido2FallbackBehavior = true }; if (input.Data.AuthType.HasValue) { switch (input.Data.AuthType) { case ConnectionAuthType.Basic: if (String.IsNullOrEmpty(input.Data.ExtAuthPayload)) { composeInfo.Behavior = GetNextBehaviorFunc(input, relatedItem); } else { composeInfo.Behavior = new FrontendBehavior(StepType.UpgradeToFido2, ChallengeType.Login, new CallAction(UrlProvider.GetSwitchAuthTypeUrl(relatedItem.Context, ConnectionAuthType.Fido2))); } break; case ConnectionAuthType.Passcode: composeInfo.Behavior = NavigateToEnterPasscode(input, relatedItem); break; case ConnectionAuthType.Fido2: if (string.IsNullOrEmpty(input.Data.ExtAuthPayload)) { composeInfo.Behavior = await NavigateToPasswordlessPageAsync(input, relatedItem); } else { var switchResult = await _trySwitchToFido2FlowCommand.ExecuteAsync(relatedItem, input.Data.ExtAuthPayload); if (switchResult == null && _coreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Block) { return(CreateErrorResponse(input, ErrorType.RequiresBiometricInput)); } composeInfo.Behavior = switchResult ?? GetNextBehaviorFunc(input, relatedItem); } return(new JwtContainer(JwtComposer.GenerateBaseStepJwt(composeInfo))); default: throw new ArgumentOutOfRangeException(); } } else if (_coreConfiguration.TFAEnabled) { if (input.Data.SupportsFido2 && _coreConfiguration.Fido2.IsEnabled) { // check if fido2 page response available if (string.IsNullOrWhiteSpace(input.Data.ExtAuthPayload)) { composeInfo.Behavior = await NavigateToPasswordlessPageAsync(input, relatedItem); } else { var switchResult = await _trySwitchToFido2FlowCommand.ExecuteAsync(relatedItem, input.Data.ExtAuthPayload); if (switchResult == null && _coreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Block) { return(CreateErrorResponse(input, ErrorType.RequiresBiometricInput)); } composeInfo.Behavior = switchResult ?? GetNextBehaviorFunc(input, relatedItem); } return(new JwtContainer(JwtComposer.GenerateBaseStepJwt(composeInfo))); } // if FIDO2 flow or there is no way to login (with/without recovery with previously created creds) if (relatedItem.IsFido2Flow || _coreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Block && relatedItem.ChallengeType != ChallengeType.Login && (!input.Data.AuthType.HasValue || !string.IsNullOrEmpty(relatedItem .RecoveryToken))) { return(CreateErrorResponse(input, ErrorType.RequiresBiometricInput)); } // go to passcode if such behavior enabled and check if create if (_coreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Passcode && (relatedItem.AuthCookieType == CookieType.Passcode || relatedItem.ChallengeType != ChallengeType.Login)) { composeInfo.Behavior = NavigateToEnterPasscode(input, relatedItem); } } if (composeInfo.Behavior == null && (!_coreConfiguration.TFAEnabled || _coreConfiguration.Fido2FallbackBehavior == Fido2FallbackBehavior.Basic)) { composeInfo.Behavior = GetNextBehaviorFunc(input, relatedItem); } if (!string.IsNullOrWhiteSpace(relatedItem.EncKey)) { composeInfo.EncKey = relatedItem.EncKey; composeInfo.EncVector = relatedItem.EncVector; } else { var updatedItem = await _setNewEncryptionTokenCommand.ExecuteAsync(relatedItem.Context); composeInfo.EncKey = updatedItem.EncKey; composeInfo.EncVector = updatedItem.EncVector; // TODO: rework relatedItem = updatedItem; } composeInfo.CanBeRecovered = !string.IsNullOrEmpty(relatedItem.RecoveryToken); return(new JwtContainer(JwtComposer.GenerateBaseStepJwt(composeInfo, relatedItem.DID ?? _identitiesProvider.GenerateUserId()))); }