From 4cbabe57a81c8767457ef695bab472bca86a6dbe Mon Sep 17 00:00:00 2001 From: Newman Chow Date: Wed, 2 Oct 2024 15:34:46 +0800 Subject: [PATCH 01/17] Implement identity and authenticator backend actions for account management --- pkg/auth/wire_gen.go | 310 +++++++----------- pkg/lib/accountmanagement/service.go | 31 +- pkg/lib/accountmanagement/service_identity.go | 258 ++++++++++----- pkg/lib/accountmanagement/token_test.go | 5 +- pkg/lib/deps/deps_common.go | 4 +- 5 files changed, 320 insertions(+), 288 deletions(-) diff --git a/pkg/auth/wire_gen.go b/pkg/auth/wire_gen.go index 3841296759..7c3d6f1520 100644 --- a/pkg/auth/wire_gen.go +++ b/pkg/auth/wire_gen.go @@ -80188,41 +80188,66 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt Logger: jsonResponseWriterLogger, } handle := appProvider.AppDatabase + request := p.Request + contextContext := deps.ProvideRequestContext(request) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - secretConfig := config.SecretConfig - databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) appID := appConfig.ID - sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - request := p.Request - contextContext := deps.ProvideRequestContext(request) - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + appredisHandle := appProvider.Redis clockClock := _wireSystemClockValue - store := &user.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, - AppID: appID, + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, + identityConfig := appConfig.Identity + secretConfig := config.SecretConfig + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + loginIDConfig := identityConfig.LoginID + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, } - rawQueries := &user.RawQueries{ - Store: store, + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, } rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } trustProxy := environmentConfig.TrustProxy remoteIP := deps.ProvideRemoteIP(request, trustProxy) userAgentString := deps.ProvideUserAgentString(request) logger := event.NewLogger(factory) localizationConfig := appConfig.Localization + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: store, + } authenticationConfig := appConfig.Authentication - identityConfig := appConfig.Identity featureConfig := config.FeatureConfig identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -80233,7 +80258,6 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - loginIDConfig := identityConfig.LoginID uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ @@ -80245,9 +80269,6 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt Config: loginIDConfig, TypeCheckerFactory: typeCheckerFactory, } - normalizerFactory := &loginid.NormalizerFactory{ - Config: loginIDConfig, - } provider := &loginid.Provider{ Store: loginidStore, Config: loginIDConfig, @@ -80285,7 +80306,6 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, Redis: appredisHandle, @@ -80376,9 +80396,6 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - normalizer := &stdattrs.Normalizer{ - LoginIDNormalizerFactory: normalizerFactory, - } ldapProvider := &ldap.Provider{ Store: ldapStore, Clock: clockClock, @@ -80661,42 +80678,6 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt Database: handle, } eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, - } - redisStore := &accountmanagement.RedisStore{ - Context: contextContext, - AppID: appID, - Redis: appredisHandle, - Clock: clockClock, - } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: appredisHandle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ Redis: appredisHandle, AppID: appID, @@ -80777,6 +80758,21 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, @@ -80901,39 +80897,12 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt identityFacade := &facade.IdentityFacade{ Coordinator: coordinator, } - messageSender := &otp.MessageSender{ - AppID: appID, - Translation: translationService, - Endpoints: endpointsEndpoints, - Sender: sender, - WhatsappService: whatsappService, - } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, - } accountmanagementService := &accountmanagement.Service{ - Database: handle, - Config: appConfig, - Users: userProvider, - Store: redisStore, - OAuthProvider: oAuthProviderFactory, - Identities: identityFacade, - Events: eventService, - OTPSender: messageSender, - OTPCodeService: otpService, - Authenticators: authenticatorFacade, - AuthenticationInfoService: authenticationinfoStoreRedis, - PasskeyService: passkeyService, - Verification: verificationService, - UIInfoResolver: uiService, + Database: handle, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: identityFacade, + Events: eventService, } accountManagementV1IdentificationHandler := &api.AccountManagementV1IdentificationHandler{ JSON: jsonResponseWriter, @@ -80950,41 +80919,66 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Logger: jsonResponseWriterLogger, } handle := appProvider.AppDatabase + request := p.Request + contextContext := deps.ProvideRequestContext(request) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - secretConfig := config.SecretConfig - databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) appID := appConfig.ID - sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - request := p.Request - contextContext := deps.ProvideRequestContext(request) - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + appredisHandle := appProvider.Redis clockClock := _wireSystemClockValue - store := &user.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, - AppID: appID, + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, + identityConfig := appConfig.Identity + secretConfig := config.SecretConfig + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + loginIDConfig := identityConfig.LoginID + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, } - rawQueries := &user.RawQueries{ - Store: store, + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, } rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } trustProxy := environmentConfig.TrustProxy remoteIP := deps.ProvideRemoteIP(request, trustProxy) userAgentString := deps.ProvideUserAgentString(request) logger := event.NewLogger(factory) localizationConfig := appConfig.Localization + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: store, + } authenticationConfig := appConfig.Authentication - identityConfig := appConfig.Identity featureConfig := config.FeatureConfig identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -80995,7 +80989,6 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - loginIDConfig := identityConfig.LoginID uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ @@ -81007,9 +81000,6 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Config: loginIDConfig, TypeCheckerFactory: typeCheckerFactory, } - normalizerFactory := &loginid.NormalizerFactory{ - Config: loginIDConfig, - } provider := &loginid.Provider{ Store: loginidStore, Config: loginIDConfig, @@ -81047,7 +81037,6 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, Redis: appredisHandle, @@ -81138,9 +81127,6 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - normalizer := &stdattrs.Normalizer{ - LoginIDNormalizerFactory: normalizerFactory, - } ldapProvider := &ldap.Provider{ Store: ldapStore, Clock: clockClock, @@ -81423,42 +81409,6 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Database: handle, } eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, - } - redisStore := &accountmanagement.RedisStore{ - Context: contextContext, - AppID: appID, - Redis: appredisHandle, - Clock: clockClock, - } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: appredisHandle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ Redis: appredisHandle, AppID: appID, @@ -81539,6 +81489,21 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, @@ -81663,39 +81628,12 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider identityFacade := &facade.IdentityFacade{ Coordinator: coordinator, } - messageSender := &otp.MessageSender{ - AppID: appID, - Translation: translationService, - Endpoints: endpointsEndpoints, - Sender: sender, - WhatsappService: whatsappService, - } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, - } accountmanagementService := &accountmanagement.Service{ - Database: handle, - Config: appConfig, - Users: userProvider, - Store: redisStore, - OAuthProvider: oAuthProviderFactory, - Identities: identityFacade, - Events: eventService, - OTPSender: messageSender, - OTPCodeService: otpService, - Authenticators: authenticatorFacade, - AuthenticationInfoService: authenticationinfoStoreRedis, - PasskeyService: passkeyService, - Verification: verificationService, - UIInfoResolver: uiService, + Database: handle, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: identityFacade, + Events: eventService, } accountManagementV1IdentificationOAuthHandler := &api.AccountManagementV1IdentificationOAuthHandler{ JSON: jsonResponseWriter, diff --git a/pkg/lib/accountmanagement/service.go b/pkg/lib/accountmanagement/service.go index 716617afb3..5a59b10261 100644 --- a/pkg/lib/accountmanagement/service.go +++ b/pkg/lib/accountmanagement/service.go @@ -76,7 +76,7 @@ type PasskeyService interface { ConsumeAttestationResponse(attestationResponse []byte) (err error) } -type UIInfoResolver interface { +type SettingsDeleteAccountSuccessUIInfoResolver interface { SetAuthenticationInfoInQuery(redirectURI string, e *authenticationinfo.Entry) string } @@ -110,7 +110,7 @@ type Service struct { AuthenticationInfoService AuthenticationInfoService PasskeyService PasskeyService Verification VerificationService - UIInfoResolver UIInfoResolver + UIInfoResolver SettingsDeleteAccountSuccessUIInfoResolver } type StartAddingInput struct { @@ -259,6 +259,19 @@ func (s *Service) FinishAdding(input *FinishAddingInput) (*FinishAddingOutput, e return &FinishAddingOutput{}, nil } +func (s *Service) GetToken(resolvedSession session.ResolvedSession, tokenString string) (*Token, error) { + userID := resolvedSession.GetAuthenticationInfo().UserID + token, err := s.Store.GetToken(tokenString) + if err != nil { + return nil, err + } + err = token.CheckUser(userID) + if err != nil { + return nil, err + } + return token, nil +} + func (s *Service) ResendOTPCode(resolvedSession session.ResolvedSession, tokenString string) (err error) { userID := resolvedSession.GetAuthenticationInfo().UserID @@ -286,12 +299,14 @@ func (s *Service) ResendOTPCode(resolvedSession session.ResolvedSession, tokenSt panic(fmt.Errorf("accountmanagement: unexpected token in resend otp code")) } - err = s.sendOTPCode( - userID, - channel, - target, - true, - ) + err = s.Database.WithTx(func() error { + return s.sendOTPCode( + userID, + channel, + target, + true, + ) + }) if err != nil { return err } diff --git a/pkg/lib/accountmanagement/service_identity.go b/pkg/lib/accountmanagement/service_identity.go index 8ec9d61f0d..766265b50f 100644 --- a/pkg/lib/accountmanagement/service_identity.go +++ b/pkg/lib/accountmanagement/service_identity.go @@ -177,13 +177,24 @@ func (s *Service) StartAddIdentityEmail(resolvedSession session.ResolvedSession, return err } - verified, err := s.checkIdentityVerified(info) + verified, err := s.CheckIdentityVerified(info) if err != nil { return err } needVerification = !verified - - if !verified { + if needVerification { + channel, target := info.LoginID.ToChannelTarget() + err = s.sendOTPCode(userID, channel, target, false) + if err != nil { + return err + } + token, err = s.Store.GenerateToken(GenerateTokenOptions{ + UserID: userID, + Email: info.LoginID.LoginID, + }) + if err != nil { + return err + } return nil } @@ -203,21 +214,6 @@ func (s *Service) StartAddIdentityEmail(resolvedSession session.ResolvedSession, return nil, err } - if needVerification { - channel, target := info.LoginID.ToChannelTarget() - err = s.sendOTPCode(userID, channel, target, false) - if err != nil { - return nil, err - } - token, err = s.Store.GenerateToken(GenerateTokenOptions{ - UserID: userID, - Email: info.LoginID.LoginID, - }) - if err != nil { - return nil, err - } - } - return &StartAddIdentityEmailOutput{ IdentityInfo: info, NeedVerification: needVerification, @@ -307,7 +303,8 @@ type StartUpdateIdentityEmailInput struct { } type StartUpdateIdentityEmailOutput struct { - IdentityInfo *identity.Info + OldInfo *identity.Info + NewInfo *identity.Info NeedVerification bool Token string } @@ -322,7 +319,8 @@ func (s *Service) StartUpdateIdentityEmail(resolvedSession session.ResolvedSessi return nil, err } - var info *identity.Info + var oldInfo *identity.Info + var newInfo *identity.Info var token string var needVerification bool err = s.Database.WithTx(func() error { @@ -330,15 +328,27 @@ func (s *Service) StartUpdateIdentityEmail(resolvedSession session.ResolvedSessi if err != nil { return err } - info = newInfo - verified, err := s.checkIdentityVerified(newInfo) + verified, err := s.CheckIdentityVerified(newInfo) if err != nil { return err } needVerification = !verified - if !verified { + if needVerification { + channel, target := newInfo.LoginID.ToChannelTarget() + err = s.sendOTPCode(userID, channel, target, false) + if err != nil { + return err + } + token, err = s.Store.GenerateToken(GenerateTokenOptions{ + UserID: userID, + Email: newInfo.LoginID.LoginID, + IdentityID: newInfo.ID, + }) + if err != nil { + return err + } return nil } @@ -358,24 +368,9 @@ func (s *Service) StartUpdateIdentityEmail(resolvedSession session.ResolvedSessi return nil, err } - if needVerification { - channel, target := info.LoginID.ToChannelTarget() - err = s.sendOTPCode(userID, channel, target, false) - if err != nil { - return nil, err - } - token, err = s.Store.GenerateToken(GenerateTokenOptions{ - UserID: userID, - Email: info.LoginID.LoginID, - IdentityID: info.ID, - }) - if err != nil { - return nil, err - } - } - return &StartUpdateIdentityEmailOutput{ - IdentityInfo: info, + OldInfo: oldInfo, + NewInfo: newInfo, NeedVerification: needVerification, Token: token, }, nil @@ -387,7 +382,8 @@ type ResumeUpdateIdentityEmailInput struct { } type ResumeUpdateIdentityEmailOutput struct { - IdentityInfo *identity.Info + OldInfo *identity.Info + NewInfo *identity.Info } func (s *Service) ResumeUpdateIdentityEmail(resolvedSession session.ResolvedSession, tokenString string, input *ResumeUpdateIdentityEmailInput) (output *ResumeUpdateIdentityEmailOutput, err error) { @@ -417,24 +413,24 @@ func (s *Service) ResumeUpdateIdentityEmail(resolvedSession session.ResolvedSess return } - var info *identity.Info + var oldInfo *identity.Info + var newInfo *identity.Info err = s.Database.WithTx(func() error { - oldInfo, newInfo, err := s.prepareUpdateIdentity(userID, token.Identity.IdentityID, spec) + oldInfo, newInfo, err = s.prepareUpdateIdentity(userID, token.Identity.IdentityID, spec) if err != nil { return err } - info = newInfo err = s.updateIdentity(oldInfo, newInfo) if err != nil { return err } - claimName, ok := model.GetLoginIDKeyTypeClaim(info.LoginID.LoginIDType) + claimName, ok := model.GetLoginIDKeyTypeClaim(newInfo.LoginID.LoginIDType) if !ok { panic(fmt.Errorf("accountmanagement: unexpected login ID key")) } - err = s.markClaimVerified(userID, claimName, info.LoginID.LoginID) + err = s.markClaimVerified(userID, claimName, newInfo.LoginID.LoginID) if err != nil { return err } @@ -452,11 +448,54 @@ func (s *Service) ResumeUpdateIdentityEmail(resolvedSession session.ResolvedSess } output = &ResumeUpdateIdentityEmailOutput{ - IdentityInfo: info, + OldInfo: oldInfo, + NewInfo: newInfo, } return } +type ResumeAddOrUpdateIdentityEmailInput struct { + LoginIDKey string + Code string +} + +type ResumeAddOrUpdateIdentityEmailOutput struct { + OldInfo *identity.Info + NewInfo *identity.Info +} + +func (s *Service) ResumeAddOrUpdateIdentityEmail(resolvedSession session.ResolvedSession, tokenString string, input *ResumeAddOrUpdateIdentityEmailInput) (*ResumeAddOrUpdateIdentityEmailOutput, error) { + token, err := s.Store.GetToken(tokenString) + if err != nil { + return nil, err + } + + if token.Identity.IdentityID == "" { + output, err := s.ResumeAddIdentityEmail(resolvedSession, tokenString, &ResumeAddIdentityEmailInput{ + LoginIDKey: input.LoginIDKey, + Code: input.Code, + }) + if err != nil { + return nil, err + } + return &ResumeAddOrUpdateIdentityEmailOutput{ + NewInfo: output.IdentityInfo, + }, nil + } + + output, err := s.ResumeUpdateIdentityEmail(resolvedSession, tokenString, &ResumeUpdateIdentityEmailInput{ + LoginIDKey: input.LoginIDKey, + Code: input.Code, + }) + if err != nil { + return nil, err + } + return &ResumeAddOrUpdateIdentityEmailOutput{ + OldInfo: output.OldInfo, + NewInfo: output.NewInfo, + }, nil +} + type DeleteIdentityEmailInput struct { IdentityID string } @@ -525,13 +564,25 @@ func (s *Service) StartAddIdentityPhone(resolvedSession session.ResolvedSession, return err } - verified, err := s.checkIdentityVerified(info) + verified, err := s.CheckIdentityVerified(info) if err != nil { return err } needVerification = !verified - if !verified { + if needVerification { + channel, target := info.LoginID.ToChannelTarget() + err = s.sendOTPCode(userID, channel, target, false) + if err != nil { + return err + } + token, err = s.Store.GenerateToken(GenerateTokenOptions{ + UserID: userID, + PhoneNumber: info.LoginID.LoginID, + }) + if err != nil { + return err + } return nil } @@ -551,21 +602,6 @@ func (s *Service) StartAddIdentityPhone(resolvedSession session.ResolvedSession, return nil, err } - if needVerification { - channel, target := info.LoginID.ToChannelTarget() - err = s.sendOTPCode(userID, channel, target, false) - if err != nil { - return nil, err - } - token, err = s.Store.GenerateToken(GenerateTokenOptions{ - UserID: userID, - PhoneNumber: info.LoginID.LoginID, - }) - if err != nil { - return nil, err - } - } - return &StartAddIdentityPhoneOutput{ IdentityInfo: info, NeedVerification: needVerification, @@ -680,13 +716,25 @@ func (s *Service) StartUpdateIdentityPhone(resolvedSession session.ResolvedSessi } info = newInfo - verified, err := s.checkIdentityVerified(newInfo) + verified, err := s.CheckIdentityVerified(newInfo) if err != nil { return err } needVerification = !verified - - if !verified { + if needVerification { + channel, target := info.LoginID.ToChannelTarget() + err = s.sendOTPCode(userID, channel, target, false) + if err != nil { + return err + } + token, err = s.Store.GenerateToken(GenerateTokenOptions{ + UserID: userID, + PhoneNumber: info.LoginID.LoginID, + IdentityID: info.ID, + }) + if err != nil { + return err + } return nil } @@ -706,22 +754,6 @@ func (s *Service) StartUpdateIdentityPhone(resolvedSession session.ResolvedSessi return nil, err } - if needVerification { - channel, target := info.LoginID.ToChannelTarget() - err = s.sendOTPCode(userID, channel, target, false) - if err != nil { - return nil, err - } - token, err = s.Store.GenerateToken(GenerateTokenOptions{ - UserID: userID, - PhoneNumber: info.LoginID.LoginID, - IdentityID: info.ID, - }) - if err != nil { - return nil, err - } - } - return &StartUpdateIdentityPhoneOutput{ IdentityInfo: info, NeedVerification: needVerification, @@ -735,7 +767,8 @@ type ResumeUpdateIdentityPhoneInput struct { } type ResumeUpdateIdentityPhoneOutput struct { - IdentityInfo *identity.Info + OldInfo *identity.Info + NewInfo *identity.Info } func (s *Service) ResumeUpdateIdentityPhone(resolvedSession session.ResolvedSession, tokenString string, input *ResumeUpdateIdentityPhoneInput) (output *ResumeUpdateIdentityPhoneOutput, err error) { @@ -765,24 +798,24 @@ func (s *Service) ResumeUpdateIdentityPhone(resolvedSession session.ResolvedSess return } - var info *identity.Info + var oldInfo *identity.Info + var newInfo *identity.Info err = s.Database.WithTx(func() error { oldInfo, newInfo, err := s.prepareUpdateIdentity(userID, token.Identity.IdentityID, spec) if err != nil { return err } - info = newInfo err = s.updateIdentity(oldInfo, newInfo) if err != nil { return err } - claimName, ok := model.GetLoginIDKeyTypeClaim(info.LoginID.LoginIDType) + claimName, ok := model.GetLoginIDKeyTypeClaim(newInfo.LoginID.LoginIDType) if !ok { panic(fmt.Errorf("accountmanagement: unexpected login ID key")) } - err = s.markClaimVerified(userID, claimName, info.LoginID.LoginID) + err = s.markClaimVerified(userID, claimName, newInfo.LoginID.LoginID) if err != nil { return err } @@ -800,11 +833,54 @@ func (s *Service) ResumeUpdateIdentityPhone(resolvedSession session.ResolvedSess } output = &ResumeUpdateIdentityPhoneOutput{ - IdentityInfo: info, + OldInfo: oldInfo, + NewInfo: newInfo, } return } +type ResumeAddOrUpdateIdentityPhoneInput struct { + LoginIDKey string + Code string +} + +type ResumeAddOrUpdateIdentityPhoneOutput struct { + OldInfo *identity.Info + NewInfo *identity.Info +} + +func (s *Service) ResumeAddOrUpdateIdentityPhone(resolvedSession session.ResolvedSession, tokenString string, input *ResumeAddOrUpdateIdentityPhoneInput) (*ResumeAddOrUpdateIdentityPhoneOutput, error) { + token, err := s.Store.GetToken(tokenString) + if err != nil { + return nil, err + } + + if token.Identity.IdentityID == "" { + output, err := s.ResumeAddIdentityPhone(resolvedSession, tokenString, &ResumeAddIdentityPhoneInput{ + LoginIDKey: input.LoginIDKey, + Code: input.Code, + }) + if err != nil { + return nil, err + } + return &ResumeAddOrUpdateIdentityPhoneOutput{ + NewInfo: output.IdentityInfo, + }, nil + } + + output, err := s.ResumeUpdateIdentityPhone(resolvedSession, tokenString, &ResumeUpdateIdentityPhoneInput{ + LoginIDKey: input.LoginIDKey, + Code: input.Code, + }) + if err != nil { + return nil, err + } + return &ResumeAddOrUpdateIdentityPhoneOutput{ + OldInfo: output.OldInfo, + NewInfo: output.NewInfo, + }, nil +} + type DeleteIdentityPhoneInput struct { IdentityID string } @@ -813,7 +889,7 @@ type DeleteIdentityPhoneOutput struct { IdentityInfo *identity.Info } -func (s *Service) DeleteIdentityPhone(resolvedSession session.ResolvedSession, input *DeleteIdentityEmailInput) (*DeleteIdentityPhoneOutput, error) { +func (s *Service) DeleteIdentityPhone(resolvedSession session.ResolvedSession, input *DeleteIdentityPhoneInput) (*DeleteIdentityPhoneOutput, error) { userID := resolvedSession.GetAuthenticationInfo().UserID identityID := input.IdentityID @@ -1083,7 +1159,7 @@ func (s *Service) prepareDeleteIdentity(userID string, identityID string) (*iden return info, nil } -func (s *Service) checkIdentityVerified(info *identity.Info) (bool, error) { +func (s *Service) CheckIdentityVerified(info *identity.Info) (bool, error) { claims, err := s.Verification.GetIdentityVerificationStatus(info) if err != nil { return false, err diff --git a/pkg/lib/accountmanagement/token_test.go b/pkg/lib/accountmanagement/token_test.go index 98655978ac..9a6868ba00 100644 --- a/pkg/lib/accountmanagement/token_test.go +++ b/pkg/lib/accountmanagement/token_test.go @@ -14,7 +14,10 @@ func TestTokenCheckUser(t *testing.T) { err := token.CheckUser("") So(errors.Is(err, ErrAccountManagementTokenNotBoundToUser), ShouldBeTrue) - err = token.CheckUser("user") + err = token.CheckUser_OAuth("") + So(errors.Is(err, ErrOAuthTokenNotBoundToUser), ShouldBeTrue) + + err = token.CheckUser_OAuth("user") So(err, ShouldBeNil) }) } diff --git a/pkg/lib/deps/deps_common.go b/pkg/lib/deps/deps_common.go index c1e7b385ef..f877b859ac 100644 --- a/pkg/lib/deps/deps_common.go +++ b/pkg/lib/deps/deps_common.go @@ -116,7 +116,6 @@ var CommonDependencySet = wire.NewSet( wire.Bind(new(authenticationflow.ServiceUIInfoResolver), new(*authenticationinfo.UIService)), wire.Bind(new(webapp.SelectAccountUIInfoResolver), new(*authenticationinfo.UIService)), wire.Bind(new(handlerwebappauthflowv2.SelectAccountUIInfoResolver), new(*authenticationinfo.UIService)), - wire.Bind(new(accountmanagement.UIInfoResolver), new(*authenticationinfo.UIService)), ), wire.NewSet( @@ -284,6 +283,7 @@ var CommonDependencySet = wire.NewSet( identitybiometric.DependencySet, wire.Bind(new(interaction.BiometricIdentityProvider), new(*identitybiometric.Provider)), + wire.Bind(new(handlerwebappauthflowv2.BiometricIdentityProvider), new(*identitybiometric.Provider)), identitysiwe.DependencySet, @@ -337,8 +337,8 @@ var CommonDependencySet = wire.NewSet( wire.Bind(new(session.UserQuery), new(*user.Queries)), wire.Bind(new(interaction.UserService), new(*user.Provider)), wire.Bind(new(workflow.UserService), new(*user.Provider)), - wire.Bind(new(authenticationflow.UserService), new(*user.Provider)), wire.Bind(new(accountmanagement.UserService), new(*user.Provider)), + wire.Bind(new(authenticationflow.UserService), new(*user.Provider)), wire.Bind(new(oidc.UserProvider), new(*user.Queries)), wire.Bind(new(featurestdattrs.UserQueries), new(*user.RawQueries)), wire.Bind(new(featurestdattrs.UserStore), new(*user.Store)), From ce6ddfb22246ba0856662022eeef8ad00f108963 Mon Sep 17 00:00:00 2001 From: Newman Chow Date: Wed, 2 Oct 2024 17:42:02 +0800 Subject: [PATCH 02/17] Implement count device tokens --- pkg/lib/authn/mfa/service.go | 5 ++++ pkg/lib/authn/mfa/store_device_token_redis.go | 26 +++++++++++++++---- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/pkg/lib/authn/mfa/service.go b/pkg/lib/authn/mfa/service.go index 2106934678..9bb60bbb04 100644 --- a/pkg/lib/authn/mfa/service.go +++ b/pkg/lib/authn/mfa/service.go @@ -23,6 +23,7 @@ type StoreDeviceToken interface { Create(token *DeviceToken) error DeleteAll(userID string) error HasTokens(userID string) (bool, error) + Count(userID string) (int, error) } type StoreRecoveryCode interface { @@ -131,6 +132,10 @@ func (s *Service) HasDeviceTokens(userID string) (bool, error) { return s.DeviceTokens.HasTokens(userID) } +func (s *Service) CountDeviceTokens(userID string) (int, error) { + return s.DeviceTokens.Count(userID) +} + func (s *Service) GenerateRecoveryCodes() []string { codes := make([]string, s.Config.RecoveryCode.Count) for i := range codes { diff --git a/pkg/lib/authn/mfa/store_device_token_redis.go b/pkg/lib/authn/mfa/store_device_token_redis.go index 9bba0bd67e..3a99ec99e5 100644 --- a/pkg/lib/authn/mfa/store_device_token_redis.go +++ b/pkg/lib/authn/mfa/store_device_token_redis.go @@ -21,6 +21,8 @@ type StoreDeviceTokenRedis struct { Clock clock.Clock } +var _ StoreDeviceToken = &StoreDeviceTokenRedis{} + func (s *StoreDeviceTokenRedis) Get(userID string, token string) (*DeviceToken, error) { var deviceToken *DeviceToken err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { @@ -108,24 +110,38 @@ func (s *StoreDeviceTokenRedis) DeleteAll(userID string) error { } func (s *StoreDeviceTokenRedis) HasTokens(userID string) (bool, error) { - hasTokens := false + count, err := s.Count(userID) + if err != nil { + return false, err + } + hasTokens := count > 0 + return hasTokens, nil +} + +func (s *StoreDeviceTokenRedis) Count(userID string) (int, error) { + count := 0 err := s.Redis.WithConn(func(conn redis.Redis_6_0_Cmdable) error { ctx := context.Background() key := redisDeviceTokensKey(s.AppID, userID) - _, err := conn.Get(ctx, key).Bytes() + data, err := conn.Get(ctx, key).Bytes() if err != nil { if errors.Is(err, goredis.Nil) { - hasTokens = false return nil } return err } - hasTokens = true + + tokens := map[string]*DeviceToken{} + if err := json.Unmarshal(data, &tokens); err != nil { + return err + } + + count = len(tokens) return nil }) - return hasTokens, err + return count, err } func (s *StoreDeviceTokenRedis) saveTokens(conn redis.Redis_6_0_Cmdable, key string, tokens map[string]*DeviceToken, ttl time.Duration) error { From b953c11c2cbda1be56b09653bf7838da552cd686 Mon Sep 17 00:00:00 2001 From: Newman Chow Date: Wed, 2 Oct 2024 17:44:47 +0800 Subject: [PATCH 03/17] Implement settings v2 handlers for homepage, manage identities and mfa password --- authui/src/authflowv2.ts | 5 + authui/src/authflowv2/base.css | 4 + authui/src/authflowv2/components.css | 5 + .../src/authflowv2/components/body-text.css | 2 +- .../src/authflowv2/components/otp-input.css | 1 + .../authflowv2/components/primary-button.css | 7 + .../components/settings-action-item.css | 115 + .../components/settings-description.css | 7 + .../authflowv2/components/settings-dialog.css | 15 + .../components/settings-headline.css | 30 + .../authflowv2/components/settings-item.css | 40 +- .../components/settings-link-button.css | 95 + .../components/settings-text-color.css | 9 + authui/src/authflowv2/settingsDialog.ts | 16 + pkg/auth/deps.go | 2 + pkg/auth/handler/webapp/account_status.go | 2 +- pkg/auth/handler/webapp/authflowv2/deps.go | 28 + .../handler/webapp/authflowv2/not_found.go | 2 +- .../webapp/authflowv2/reset_password.go | 2 +- pkg/auth/handler/webapp/authflowv2/routes.go | 26 + .../webapp/authflowv2/select_account.go | 4 +- .../handler/webapp/authflowv2/settings.go | 14 +- .../webapp/authflowv2/settings_advanced.go | 55 + .../webapp/authflowv2/settings_biometric.go | 122 + .../authflowv2/settings_change_password.go | 123 + .../authflowv2/settings_delete_account.go | 131 + .../settings_delete_account_success.go | 87 + .../authflowv2/settings_identity_add_email.go | 130 + .../authflowv2/settings_identity_add_phone.go | 129 + .../settings_identity_change_primary_email.go | 151 + .../settings_identity_change_primary_phone.go | 146 + .../settings_identity_edit_email.go | 153 + .../settings_identity_edit_phone.go | 155 + .../settings_identity_edit_username.go | 127 + .../settings_identity_list_email.go | 132 + .../settings_identity_list_phone.go | 132 + .../settings_identity_list_username.go | 101 + .../settings_identity_new_username.go | 115 + .../settings_identity_verify_email.go | 189 + .../settings_identity_verify_phone.go | 194 + .../settings_identity_view_email.go | 201 + .../settings_identity_view_phone.go | 201 + .../settings_identity_view_username.go | 138 + .../handler/webapp/authflowv2/settings_mfa.go | 73 + .../settings_mfa_create_password.go | 111 + .../authflowv2/settings_mfa_password.go | 72 + .../webapp/authflowv2/settings_oob_otp.go | 90 + .../webapp/authflowv2/settings_passkey.go | 157 + .../webapp/authflowv2/settings_profile.go | 2 +- .../authflowv2/settings_profile_edit.go | 23 +- .../webapp/authflowv2/settings_sessions.go | 177 + .../webapp/authflowv2/settings_totp.go | 83 + .../webapp/authflowv2/verify_login_link.go | 2 +- pkg/auth/handler/webapp/change_password.go | 2 +- .../webapp/change_secondary_password.go | 2 +- .../confirm_terminate_other_sessions.go | 2 +- .../handler/webapp/confirm_web3_account.go | 2 +- pkg/auth/handler/webapp/controller.go | 28 +- pkg/auth/handler/webapp/create_passkey.go | 2 +- pkg/auth/handler/webapp/create_password.go | 2 +- pkg/auth/handler/webapp/enter_login_id.go | 2 +- pkg/auth/handler/webapp/enter_oob_otp.go | 2 +- pkg/auth/handler/webapp/enter_password.go | 2 +- .../handler/webapp/enter_recovery_code.go | 2 +- pkg/auth/handler/webapp/enter_totp.go | 2 +- pkg/auth/handler/webapp/error.go | 2 +- .../handler/webapp/error_feature_disabled.go | 2 +- pkg/auth/handler/webapp/forgot_password.go | 2 +- .../handler/webapp/forgot_password_success.go | 2 +- pkg/auth/handler/webapp/login.go | 2 +- pkg/auth/handler/webapp/login_link_otp.go | 2 +- pkg/auth/handler/webapp/logout.go | 2 +- .../handler/webapp/missing_web3_wallet.go | 2 +- pkg/auth/handler/webapp/not_found.go | 2 +- pkg/auth/handler/webapp/promote.go | 2 +- .../handler/webapp/prompt_create_passkey.go | 2 +- pkg/auth/handler/webapp/reauth.go | 2 +- pkg/auth/handler/webapp/reset_password.go | 2 +- .../handler/webapp/reset_password_success.go | 2 +- pkg/auth/handler/webapp/return.go | 2 +- pkg/auth/handler/webapp/select_account.go | 4 +- pkg/auth/handler/webapp/settings.go | 2 +- pkg/auth/handler/webapp/settings_biometric.go | 2 +- .../webapp/settings_change_password.go | 2 +- .../settings_change_secondary_password.go | 2 +- .../handler/webapp/settings_delete_account.go | 2 +- .../webapp/settings_delete_account_success.go | 4 +- pkg/auth/handler/webapp/settings_identity.go | 2 +- pkg/auth/handler/webapp/settings_mfa.go | 2 +- pkg/auth/handler/webapp/settings_oob_otp.go | 2 +- pkg/auth/handler/webapp/settings_passkey.go | 2 +- pkg/auth/handler/webapp/settings_profile.go | 2 +- .../handler/webapp/settings_profile_edit.go | 2 +- .../handler/webapp/settings_recovery_code.go | 2 +- pkg/auth/handler/webapp/settings_sessions.go | 2 +- pkg/auth/handler/webapp/settings_totp.go | 2 +- .../handler/webapp/setup_login_link_otp.go | 2 +- pkg/auth/handler/webapp/setup_oob_otp.go | 2 +- .../handler/webapp/setup_recovery_code.go | 2 +- pkg/auth/handler/webapp/setup_totp.go | 2 +- pkg/auth/handler/webapp/setup_whatsapp_otp.go | 2 +- pkg/auth/handler/webapp/signup.go | 2 +- pkg/auth/handler/webapp/sso_callback.go | 2 +- pkg/auth/handler/webapp/tester.go | 2 +- pkg/auth/handler/webapp/use_passkey.go | 2 +- pkg/auth/handler/webapp/verify_identity.go | 2 +- .../handler/webapp/verify_identity_success.go | 2 +- pkg/auth/handler/webapp/verify_login_link.go | 2 +- .../handler/webapp/viewmodels/settings.go | 7 +- pkg/auth/handler/webapp/wechat_auth.go | 2 +- pkg/auth/handler/webapp/wechat_callback.go | 2 +- pkg/auth/handler/webapp/whatsapp_otp.go | 2 +- pkg/auth/routes.go | 66 +- pkg/auth/wire_gen.go | 43404 +++++++++++++--- pkg/auth/wire_handler.go | 196 + pkg/lib/web/html.go | 4 + .../authgear/templates/en/translation.json | 121 +- .../templates/en/web/authflowv2/__error.html | 12 +- .../web/authflowv2/__new_password_field.html | 2 + .../en/web/authflowv2/__otp_input.html | 1 + .../en/web/authflowv2/__password_input.html | 18 +- .../en/web/authflowv2/__select_input.html | 2 +- .../authflowv2/__settings_action_item.html | 61 + .../en/web/authflowv2/__settings_dialog.html | 90 + .../en/web/authflowv2/__settings_item.html | 14 +- .../templates/en/web/authflowv2/settings.html | 27 +- .../en/web/authflowv2/settings_advanced.html | 24 + .../en/web/authflowv2/settings_biometric.html | 77 + .../authflowv2/settings_change_password.html | 122 + .../authflowv2/settings_delete_account.html | 45 + .../settings_delete_account_success.html | 35 + .../settings_identity_add_email.html | 49 + .../settings_identity_add_phone.html | 58 + ...ettings_identity_change_primary_email.html | 55 + ...ettings_identity_change_primary_phone.html | 56 + .../settings_identity_edit_email.html | 64 + .../settings_identity_edit_phone.html | 74 + .../settings_identity_edit_username.html | 59 + .../settings_identity_list_email.html | 86 + .../settings_identity_list_phone.html | 86 + .../settings_identity_list_username.html | 41 + .../settings_identity_new_username.html | 52 + .../settings_identity_verify_email.html | 76 + .../settings_identity_verify_phone.html | 76 + .../settings_identity_view_email.html | 126 + .../settings_identity_view_phone.html | 123 + .../settings_identity_view_username.html | 78 + .../en/web/authflowv2/settings_mfa.html | 151 + .../settings_mfa_create_password.html | 96 + .../web/authflowv2/settings_mfa_password.html | 79 + .../en/web/authflowv2/settings_oob_otp.html | 70 + .../en/web/authflowv2/settings_passkey.html | 103 + .../en/web/authflowv2/settings_profile.html | 54 +- .../settings_profile_edit_address.html | 2 +- .../settings_profile_edit_birthdate.html | 2 +- .../settings_profile_edit_custom.html | 196 + .../settings_profile_edit_locale.html | 2 +- .../settings_profile_edit_name.html | 2 +- .../settings_profile_edit_zoneinfo.html | 2 +- .../en/web/authflowv2/settings_sessions.html | 121 + .../en/web/authflowv2/settings_totp.html | 57 + 161 files changed, 42289 insertions(+), 8414 deletions(-) create mode 100644 authui/src/authflowv2/components/settings-action-item.css create mode 100644 authui/src/authflowv2/components/settings-dialog.css create mode 100644 authui/src/authflowv2/components/settings-headline.css create mode 100644 authui/src/authflowv2/components/settings-link-button.css create mode 100644 authui/src/authflowv2/components/settings-text-color.css create mode 100644 authui/src/authflowv2/settingsDialog.ts create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_advanced.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_biometric.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_change_password.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_delete_account.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_delete_account_success.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_add_email.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_add_phone.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_change_primary_email.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_change_primary_phone.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_edit_email.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_edit_phone.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_edit_username.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_list_email.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_list_phone.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_list_username.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_new_username.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_verify_email.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_verify_phone.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_view_email.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_view_phone.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_identity_view_username.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_mfa.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_mfa_create_password.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_mfa_password.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_oob_otp.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_passkey.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_sessions.go create mode 100644 pkg/auth/handler/webapp/authflowv2/settings_totp.go create mode 100644 resources/authgear/templates/en/web/authflowv2/__settings_action_item.html create mode 100644 resources/authgear/templates/en/web/authflowv2/__settings_dialog.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_advanced.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_biometric.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_change_password.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_delete_account.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_delete_account_success.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_add_email.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_add_phone.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_change_primary_email.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_change_primary_phone.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_edit_email.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_edit_phone.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_edit_username.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_list_email.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_list_phone.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_list_username.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_new_username.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_verify_email.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_verify_phone.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_view_email.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_view_phone.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_identity_view_username.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_mfa.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_mfa_create_password.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_mfa_password.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_oob_otp.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_passkey.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_profile_edit_custom.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_sessions.html create mode 100644 resources/authgear/templates/en/web/authflowv2/settings_totp.html diff --git a/authui/src/authflowv2.ts b/authui/src/authflowv2.ts index 9458870cac..d300f93311 100644 --- a/authui/src/authflowv2.ts +++ b/authui/src/authflowv2.ts @@ -50,6 +50,8 @@ import { DialogController } from "./authflowv2/dialog"; import { BotProtectionStandalonePageController } from "./authflowv2/botprotection/botProtectionStandalonePage"; import { ImagePickerController } from "./imagepicker"; import { SelectInputController } from "./authflowv2/selectInput"; +import { SettingsDialogController } from "./authflowv2/settingsDialog"; +import { AccountDeletionController } from "./accountdeletion"; axios.defaults.withCredentials = true; @@ -96,6 +98,7 @@ Stimulus.register("image-picker", ImagePickerController); Stimulus.register("text-field", TextFieldController); Stimulus.register("dialog", DialogController); +Stimulus.register("settings-dialog", SettingsDialogController); Stimulus.register("overlay", OverlayController); Stimulus.register("loading", LoadingController); Stimulus.register("new-password-field", NewPasswordFieldController); @@ -135,4 +138,6 @@ Stimulus.register("bot-protection", BotProtectionController); Stimulus.register("bot-protection-dialog", BotProtectionDialogController); Stimulus.register("select-input", SelectInputController); +Stimulus.register("account-deletion", AccountDeletionController); + injectCSSAttrs(document.documentElement); diff --git a/authui/src/authflowv2/base.css b/authui/src/authflowv2/base.css index 15d6bbbb94..4d9c7f2f11 100644 --- a/authui/src/authflowv2/base.css +++ b/authui/src/authflowv2/base.css @@ -51,6 +51,10 @@ /* --color-primary-theme-lighter: #d8e6fd; */ /* --color-primary-theme-lighter-alt: #f5f9fe; */ + /* secondary */ + --color-secondary-theme-primary: #ff295b; + --color-secondary-theme-dark: #c4003d; + /* Neutral colors is tonal palette */ /* https://m3.material.io/styles/color/system/how-the-system-works#395813c8-b314-48d1-bb55-266f421eb3a4 */ /* neutral */ diff --git a/authui/src/authflowv2/components.css b/authui/src/authflowv2/components.css index a5c7a48b0a..8cc6ed6adf 100644 --- a/authui/src/authflowv2/components.css +++ b/authui/src/authflowv2/components.css @@ -33,6 +33,7 @@ @import "./components/dialog.css"; @import "./components/watermark.css"; @import "./components/settings-content.css"; +@import "./components/settings-headline.css"; @import "./components/settings-title.css"; @import "./components/settings-description.css"; @import "./components/settings-item.css"; @@ -41,3 +42,7 @@ @import "./components/settings-user-profile-pic.css"; @import "./components/select-input.css"; @import "./components/direct-access-layout.css"; +@import "./components/settings-link-button.css"; +@import "./components/settings-text-color.css"; +@import "./components/settings-action-item.css"; +@import "./components/settings-dialog.css"; diff --git a/authui/src/authflowv2/components/body-text.css b/authui/src/authflowv2/components/body-text.css index ef2a0c9f5f..18adff7f18 100644 --- a/authui/src/authflowv2/components/body-text.css +++ b/authui/src/authflowv2/components/body-text.css @@ -18,7 +18,7 @@ --body-text__letter-spacing--sm: var( --typography-body-small__letter-spacing ); - --body-text__font-weight--sm: var(--typography-body-medium__font-weight); + --body-text__font-weight--sm: var(--typography-body-small__font-weight); /* sm link */ --body-text__font-family--link-sm: var( diff --git a/authui/src/authflowv2/components/otp-input.css b/authui/src/authflowv2/components/otp-input.css index e8f73fd172..93315ebf52 100644 --- a/authui/src/authflowv2/components/otp-input.css +++ b/authui/src/authflowv2/components/otp-input.css @@ -80,6 +80,7 @@ @apply items-stretch; @apply gap-x-[var(--otp-input\_\_spacing)]; @apply pointer-events-none; + @apply justify-center; } .otp-input__digit { diff --git a/authui/src/authflowv2/components/primary-button.css b/authui/src/authflowv2/components/primary-button.css index 9d3a92732c..55e6828c5a 100644 --- a/authui/src/authflowv2/components/primary-button.css +++ b/authui/src/authflowv2/components/primary-button.css @@ -104,4 +104,11 @@ .primary-btn--success { background-color: var(--color-success); } + + .primary-btn--destructive { + @apply primary-btn; + --primary-btn__bg-color: var(--color-secondary-theme-primary); + --primary-btn__bg-color--hover: var(--color-secondary-theme-dark); + --primary-btn__bg-color--active: var(--color-secondary-theme-dark); + } } diff --git a/authui/src/authflowv2/components/settings-action-item.css b/authui/src/authflowv2/components/settings-action-item.css new file mode 100644 index 0000000000..b28f592c5e --- /dev/null +++ b/authui/src/authflowv2/components/settings-action-item.css @@ -0,0 +1,115 @@ +@layer components { + :root { + --settings-action-item__description-color: var(--body-text__text-color); + --settings-action-item__description-font-family: var( + --body-text__font-family--md + ); + --settings-action-item__description-font-size: var( + --body-text__font-size--md + ); + --settings-action-item__description-line-height: var( + --body-text__line-height--md + ); + --settings-action-item__description-letter-spacing: var( + --body-text__letter-spacing--md + ); + --settings-action-item__description-font-weight: var( + --body-text__font-weight--md + ); + + --settings-action-item__icon-color--pale: var(--color-neutral-200); + } + + .settings-action-item__container { + @apply flex; + --settings-action-item-padding-x: 0.5rem; + --settings-action-item-padding-y: 1rem; + color: var(--settings-item__text-color); + border-color: var(--settings-item__border-color); + border-bottom-width: 1px; + border-style: solid; + + --icon-placeholder-display: none; + --icon-size: 1.5rem; + &.settings-action-item__container-with-icon { + --icon-placeholder-display: block; + } + } + + .settings-action-item__container { + &.settings-action-item__container-with-extra-content { + .settings-action-item__content-container { + @apply pb-2; + } + } + } + + .settings-action-item__content-container { + @apply block; + @apply px-[var(--settings-action-item-padding-x)]; + @apply py-[var(--settings-action-item-padding-y)]; + } + + .settings-action-item__label-container { + @apply flex gap-x-2; + } + + .settings-action-item__description-container { + @apply text-start; + @apply flex gap-x-2 items-center justify-start; + @apply mt-1; + &::before { + content: ""; + width: var(--icon-size); + display: var(--icon-placeholder-display); + } + + color: var(--settings-action-item__description-color); + font-family: var(--settings-action-item__description-font-family); + font-size: var(--settings-action-item__description-font-size); + line-height: var(--settings-action-item__description-line-height); + letter-spacing: var(--settings-action-item__description-letter-spacing); + font-weight: var(--settings-action-item__description-font-weight); + } + + .settings-action-item__extra-content-container { + @apply flex gap-x-2 items-center; + @apply px-[var(--settings-action-item-padding-x)]; + @apply pb-[var(--settings-action-item-padding-y)]; + &::before { + content: ""; + width: var(--icon-size); + display: var(--icon-placeholder-display); + } + } + + .settings-action-item__icon { + @apply settings-item-icon; + } + + .settings-action-item__action-button-container { + @apply py-[var(--settings-action-item-padding-y)]; + } + + .settings-action-item__arrow-container { + @apply flex flex-none items-center; + @apply py-[var(--settings-action-item-padding-y)]; + } + + .settings-action-item__label { + @apply settings-item__label; + @apply break-all; + } + + .settings-action-item__icon--pale { + @apply settings-item-icon; + line-height: normal; + color: var(--settings-action-item__icon-color--pale); + } + + .settings-action-item__icon--pale { + @apply settings-item-icon; + line-height: normal; + color: var(--settings-action-item__icon-color--pale); + } +} diff --git a/authui/src/authflowv2/components/settings-description.css b/authui/src/authflowv2/components/settings-description.css index 8d115a31c5..e3d9c2bcb2 100644 --- a/authui/src/authflowv2/components/settings-description.css +++ b/authui/src/authflowv2/components/settings-description.css @@ -14,6 +14,8 @@ --typography-title-medium__font-weight ); --settings-description__text-color: var(--color-neutral-400); + + --settings-description__text-color--primary: var(--color-link); } :root.dark { --settings-description__text-color: var(--color-neutral-200); @@ -27,4 +29,9 @@ font-weight: var(--settings-description__font-weight); color: var(--settings-description__text-color); } + + .settings-description--primary-color { + @apply settings-description; + color: var(--settings-description__text-color--primary); + } } diff --git a/authui/src/authflowv2/components/settings-dialog.css b/authui/src/authflowv2/components/settings-dialog.css new file mode 100644 index 0000000000..0d57bd7469 --- /dev/null +++ b/authui/src/authflowv2/components/settings-dialog.css @@ -0,0 +1,15 @@ +@layer components { + :root { + --settings-dialog__description-text--highlight-color: var( + --color-neutral-700 + ); + } + + .settings-dialog { + @apply p-8 tablet:p-10; + } + + .settings-dialog__description-text--highlight { + color: var(--settings-dialog__description-text--highlight-color); + } +} diff --git a/authui/src/authflowv2/components/settings-headline.css b/authui/src/authflowv2/components/settings-headline.css new file mode 100644 index 0000000000..844d26a060 --- /dev/null +++ b/authui/src/authflowv2/components/settings-headline.css @@ -0,0 +1,30 @@ +@layer components { + :root { + --settings-headlien__font-family: var( + --typography-headline-small__font-family + ); + --settings-headline__font-size: var(--typography-headline-small__font-size); + --settings-headline__line-height: var( + --typography-headline-small__line-height + ); + --settings-headline__letter-spacing: var( + --typography-headline-small__letter-spacing + ); + --settings-headline__font-weight: var( + --typography-headline-small__font-weight + ); + --settings-headline__text-color: var(--color-neutral-700); + } + :root.dark { + --settings-headline__text-color: var(--color-neutral-100); + } + + .settings-headline { + font-family: var(--settings-headline__font-family); + font-size: var(--settings-headline__font-size); + line-height: var(--settings-headline__line-height); + letter-spacing: var(--settings-headline__letter-spacing); + font-weight: var(--settings-headline__font-weight); + color: var(--settings-headline__text-color); + } +} diff --git a/authui/src/authflowv2/components/settings-item.css b/authui/src/authflowv2/components/settings-item.css index 7566edd841..952f3b09d5 100644 --- a/authui/src/authflowv2/components/settings-item.css +++ b/authui/src/authflowv2/components/settings-item.css @@ -25,6 +25,20 @@ --settings-item__ring-width--active: var(--settings-item__ring-width); --settings-item__ring-color--active: var(--settings-item__ring-color); + --settings-item__note-font-family: var( + --typography-body-medium__font-family + ); + --settings-item__note-font-size: var(--typography-body-medium__font-size); + --settings-item__note-line-height: var( + --typography-body-medium__line-height + ); + --settings-item__note-letter-spacing: var( + --typography-body-medium__letter-spacing + ); + --settings-item__note-font-weight: var( + --typography-body-medium__font-weight + ); + --settings-item__forward-arrow-font-size: 1.125rem; --settings-item__forward-arrow-color: var(--color-neutral-200); @@ -44,8 +58,7 @@ } .settings-item { - @apply grid; - @apply gap-x-2; + @apply grid gap-x-2 gap-y-1; @apply items-center text-start; background-color: var(--settings-item__bg-color); @@ -79,6 +92,13 @@ grid-template-columns: var(--settings-item__grid-col-icon-width) auto 1.125rem; } + &.with-note { + grid-template-areas: + "icon title arrow" + ". note arrow"; + grid-template-columns: var(--settings-item__grid-col-icon-width) auto 1.125rem; + } + &:hover { background-color: var(--settings-item__bg-color--hover); color: var(--settings-item__text-color--hover); @@ -96,19 +116,27 @@ } } - .settings-item > .settings-item_icon-container { + .settings-item_icon-container { grid-area: icon; @apply flex items-center; } - .settings-item > .settings-item__label { + .settings-item__label { grid-area: title; } - .settings-item > .settings-item__description { + .settings-item__content { grid-area: content; } - .settings-item > .settings-item__forward_arrow { + .settings-item__forward_arrow { grid-area: arrow; } + .settings-item__note { + grid-area: note; + font-family: var(--settings-item__note-font-family); + font-size: var(--settings-item__note-font-size); + line-height: var(--settings-item__note-line-height); + letter-spacing: var(--settings-item__note-letter-spacing); + font-weight: var(--settings-item__note-font-weight); + } } .settings-item__label { diff --git a/authui/src/authflowv2/components/settings-link-button.css b/authui/src/authflowv2/components/settings-link-button.css new file mode 100644 index 0000000000..2eb896d00f --- /dev/null +++ b/authui/src/authflowv2/components/settings-link-button.css @@ -0,0 +1,95 @@ +@layer components { + :root { + --settings-link-btn-bg-color: var(--link-btn-bg-color); + --settings-link-btn-text-color: var(--link-btn-text-color); + --settings-link-btn-border-radius: var(--link-btn-border-radius); + + --settings-link-btn-font-family: var(--typography-label-large__font-family); + --settings-link-btn-font-size: var(--typography-label-large__font-size); + --settings-link-btn-line-height: var(--typography-label-large__line-height); + --settings-link-btn-letter-spacing: var( + --typography-label-large__letter-spacing + ); + --settings-link-btn-font-weight: var(--typography-label-large__font-weight); + --settings-link-btn-ring-width: var(--link-btn-ring-width); + --settings-link-btn-ring-color: var(--link-btn-ring-color); + + --settings-link-btn-bg-color--hover: var(--link-btn-bg-color--hover); + --settings-link-btn-text-color--hover: var(--link-btn-text-color--hover); + --settings-link-btn-ring-width--hover: var(--settings-link-btn-ring-width); + --settings-link-btn-ring-color--hover: var(--settings-link-btn-ring-color); + + --settings-link-btn-bg-color--active: var(--link-btn-bg-color--active); + --settings-link-btn-text-color--active: var(--link-btn-text-color--active); + --settings-link-btn-ring-width--active: var(--settings-link-btn-ring-width); + --settings-link-btn-ring-color--active: var(--settings-link-btn-ring-color); + + --settings-link-btn-bg-color--disabled: var(--link-btn-bg-color--disabled); + --settings-link-btn-text-color--disabled: var( + --link-btn-text-color--disabled + ); + --settings-link-btn-ring-width--disabled: var( + --settings-link-btn-ring-width + ); + --settings-link-btn-ring-color--disabled: var( + --settings-link-btn-ring-color + ); + } + + :root.dark { + --settings-link-btn-text-color--disabled: var( + --link-btn-text-color--disabled + ); + + --settings-link-btn-text-color--hover: var(--link-btn-text-color--hover); + --settings-link-btn-text-color--active: var(--link-btn-text-color--active); + } + + .settings-link-btn { + @apply text-center; + + background-color: var(--settings-link-btn-bg-color); + color: var(--settings-link-btn-text-color); + border-radius: var(--settings-link-btn-border-radius); + font-family: var(--settings-link-btn-font-family); + font-size: var(--settings-link-btn-font-size); + line-height: var(--settings-link-btn-line-height); + letter-spacing: var(--settings-link-btn-letter-spacing); + font-weight: var(--settings-link-btn-font-weight); + @apply ring-inset + ring-[length:var(--settings-link-btn-ring-width)] + ring-[color:var(--settings-link-btn-ring-color)]; + padding: var(--settings-link-btn-py) var(--link-btn-px); + + &:hover { + background-color: var(--settings-link-btn-bg-color--hover); + color: var(--settings-link-btn-text-color--hover); + @apply ring-inset + ring-[length:var(--settings-link-btn-ring-width--hover)] + ring-[color:var(--settings-link-btn-ring-color--hover)]; + } + + &:active { + background-color: var(--settings-link-btn-bg-color--active); + color: var(--settings-link-btn-text-color--active); + @apply ring-inset + ring-[length:var(--settings-link-btn-ring-width--active)] + ring-[color:var(--settings-link-btn-ring-color--active)]; + } + + &:disabled { + background-color: var(--settings-link-btn-bg-color--disabled); + color: var(--settings-link-btn-text-color--disabled); + @apply ring-inset + ring-[length:var(--settings-link-btn-ring-width--disabled)] + ring-[color:var(--settings-link-btn-ring-color--disabled)]; + } + } + + .settings-link-btn--destructive { + @apply settings-link-btn; + --settings-link-btn-text-color: var(--color-secondary-theme-primary); + --settings-link-btn-text-color--hover: var(--color-secondary-theme-dark); + --settings-link-btn-text-color--active: var(--color-secondary-theme-dark); + } +} diff --git a/authui/src/authflowv2/components/settings-text-color.css b/authui/src/authflowv2/components/settings-text-color.css new file mode 100644 index 0000000000..eb7f3045d0 --- /dev/null +++ b/authui/src/authflowv2/components/settings-text-color.css @@ -0,0 +1,9 @@ +@layer components { + .settings-text-color-success { + color: var(--color-success); + } + + .settings-text-color-failure { + color: var(--color-error); + } +} diff --git a/authui/src/authflowv2/settingsDialog.ts b/authui/src/authflowv2/settingsDialog.ts new file mode 100644 index 0000000000..0b8c7335f7 --- /dev/null +++ b/authui/src/authflowv2/settingsDialog.ts @@ -0,0 +1,16 @@ +import { Controller } from "@hotwired/stimulus"; +import { dispatchDialogOpen } from "./dialog"; + +/** + * Dispatch a custom event to set settings dialog open + */ +export function dispatchSettingsDialogOpen(dialogID: string) { + dispatchDialogOpen(dialogID); +} + +export class SettingsDialogController extends Controller { + open = (e: Event) => { + const dialogID: string = (e as any).params.dialogid; + dispatchSettingsDialogOpen(dialogID); + }; +} diff --git a/pkg/auth/deps.go b/pkg/auth/deps.go index 95a3c0c73b..82e92d23cf 100644 --- a/pkg/auth/deps.go +++ b/pkg/auth/deps.go @@ -222,6 +222,7 @@ var DependencySet = wire.NewSet( wire.Bind(new(handlerwebapp.MeterService), new(*meter.Service)), wire.Bind(new(handlerwebapp.ErrorService), new(*webapp.ErrorService)), wire.Bind(new(handlerwebapp.PasskeyCreationOptionsService), new(*featurepasskey.CreationOptionsService)), + wire.Bind(new(handlerwebappauthflowv2.PasskeyCreationOptionsService), new(*featurepasskey.CreationOptionsService)), wire.Bind(new(handlerwebapp.PasskeyRequestOptionsService), new(*featurepasskey.RequestOptionsService)), wire.Bind(new(handlerwebapp.WorkflowWebsocketEventStore), new(*workflow.EventStoreImpl)), wire.Bind(new(handlerwebapp.AuthenticationFlowWebsocketEventStore), new(*authenticationflow.WebsocketEventStore)), @@ -248,6 +249,7 @@ var DependencySet = wire.NewSet( wire.Bind(new(api.JSONResponseWriter), new(*httputil.JSONResponseWriter)), wire.Bind(new(authenticationflow.JSONResponseWriter), new(*httputil.JSONResponseWriter)), wire.Bind(new(accountmanagement.RateLimitMiddlewareJSONResponseWriter), new(*httputil.JSONResponseWriter)), + wire.Bind(new(accountmanagement.SettingsDeleteAccountSuccessUIInfoResolver), new(*authenticationinfo.UIService)), wire.Bind(new(handlerwebapp.PanicMiddlewareUIImplementationService), new(*web.UIImplementationService)), wire.Bind(new(handlerwebapp.CSRFMiddlewareUIImplementationService), new(*web.UIImplementationService)), diff --git a/pkg/auth/handler/webapp/account_status.go b/pkg/auth/handler/webapp/account_status.go index 5ce4ea9c5e..390a288185 100644 --- a/pkg/auth/handler/webapp/account_status.go +++ b/pkg/auth/handler/webapp/account_status.go @@ -44,7 +44,7 @@ func (h *AccountStatusHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { graph, err := ctrl.InteractionGet() diff --git a/pkg/auth/handler/webapp/authflowv2/deps.go b/pkg/auth/handler/webapp/authflowv2/deps.go index 19741e3776..3a671f4869 100644 --- a/pkg/auth/handler/webapp/authflowv2/deps.go +++ b/pkg/auth/handler/webapp/authflowv2/deps.go @@ -44,4 +44,32 @@ var DependencySet = wire.NewSet( wire.Struct(new(AuthflowV2SettingsHandler), "*"), wire.Struct(new(AuthflowV2SettingsProfileHandler), "*"), wire.Struct(new(AuthflowV2SettingsProfileEditHandler), "*"), + wire.Struct(new(AuthflowV2SettingsChangePasswordHandler), "*"), + wire.Struct(new(AuthflowV2SettingsChangePasskeyHandler), "*"), + wire.Struct(new(AuthflowV2SettingsBiometricHandler), "*"), + wire.Struct(new(AuthflowV2SettingsSessionsHandler), "*"), + wire.Struct(new(AuthflowV2SettingsMFAHandler), "*"), + wire.Struct(new(AuthflowV2SettingsAdvancedSettingsHandler), "*"), + wire.Struct(new(AuthflowV2SettingsDeleteAccountHandler), "*"), + wire.Struct(new(AuthflowV2SettingsDeleteAccountSuccessHandler), "*"), + wire.Struct(new(AuthflowV2SettingsMFACreatePasswordHandler), "*"), + wire.Struct(new(AuthflowV2SettingsMFAPasswordHandler), "*"), + wire.Struct(new(AuthflowV2SettingsTOTPHandler), "*"), + wire.Struct(new(AuthflowV2SettingsOOBOTPHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityAddEmailHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityEditEmailHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityVerifyEmailHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityListEmailHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityViewEmailHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityChangePrimaryEmailHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityListPhoneHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityViewPhoneHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityAddPhoneHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityEditPhoneHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityChangePrimaryPhoneHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityVerifyPhoneHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityListUsernameHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityNewUsernameHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityViewUsernameHandler), "*"), + wire.Struct(new(AuthflowV2SettingsIdentityEditUsernameHandler), "*"), ) diff --git a/pkg/auth/handler/webapp/authflowv2/not_found.go b/pkg/auth/handler/webapp/authflowv2/not_found.go index d3cbd28da1..e5e2bd737e 100644 --- a/pkg/auth/handler/webapp/authflowv2/not_found.go +++ b/pkg/auth/handler/webapp/authflowv2/not_found.go @@ -32,7 +32,7 @@ func (h *AuthflowV2NotFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Req http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/authflowv2/reset_password.go b/pkg/auth/handler/webapp/authflowv2/reset_password.go index 4385132c26..f3872a303d 100644 --- a/pkg/auth/handler/webapp/authflowv2/reset_password.go +++ b/pkg/auth/handler/webapp/authflowv2/reset_password.go @@ -125,7 +125,7 @@ func (h *AuthflowV2ResetPasswordHandler) serveHTTPNonAuthflow(w http.ResponseWri return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetNonAuthflowData(w, r) diff --git a/pkg/auth/handler/webapp/authflowv2/routes.go b/pkg/auth/handler/webapp/authflowv2/routes.go index 7f96a600b4..9fb6d90e79 100644 --- a/pkg/auth/handler/webapp/authflowv2/routes.go +++ b/pkg/auth/handler/webapp/authflowv2/routes.go @@ -71,6 +71,8 @@ const ( SettingsV2RouteSettingsProfileGenderEdit = "/settings/profile/gender/edit" + SettingsV2RouteAdvancedSettings = "/settings/advanced_settings" + // The following routes are dead ends. AuthflowV2RouteAccountStatus = "/authflow/v2/account_status" AuthflowV2RouteNoAuthenticator = "/authflow/v2/no_authenticator" @@ -78,6 +80,30 @@ const ( AuthflowV2RouteFinishFlow = "/authflow/v2/finish" AuthflowV2RouteSettingsProfile = "/settings/v2/profile" + AuthflowV2RouteSettingsMFA = "/settings/mfa" + // nolint: gosec + AuthflowV2RouteSettingsMFACreatePassword = "/settings/mfa/create_password" + // nolint: gosec + AuthflowV2RouteSettingsMFAPassword = "/settings/mfa/password" + + AuthflowV2RouteSettingsIdentityListEmail = "/settings/identity/email" + AuthflowV2RouteSettingsIdentityAddEmail = "/settings/identity/add_email" + AuthflowV2RouteSettingsIdentityEditEmail = "/settings/identity/edit_email" + AuthflowV2RouteSettingsIdentityViewEmail = "/settings/identity/view_email" + AuthflowV2RouteSettingsIdentityChangePrimaryEmail = "/settings/identity/change_primary_email" + AuthflowV2RouteSettingsIdentityVerifyEmail = "/settings/identity/verify_email" + + AuthflowV2RouteSettingsIdentityListPhone = "/settings/identity/phone" + AuthflowV2RouteSettingsIdentityAddPhone = "/settings/identity/add_phone" + AuthflowV2RouteSettingsIdentityEditPhone = "/settings/identity/edit_phone" + AuthflowV2RouteSettingsIdentityViewPhone = "/settings/identity/view_phone" + AuthflowV2RouteSettingsIdentityChangePrimaryPhone = "/settings/identity/change_primary_phone" + AuthflowV2RouteSettingsIdentityVerifyPhone = "/settings/identity/verify_phone" + + AuthflowV2RouteSettingsIdentityListUsername = "/settings/identity/username" + AuthflowV2RouteSettingsIdentityNewUsername = "/settings/identity/new_username" + AuthflowV2RouteSettingsIdentityViewUsername = "/settings/identity/view_username" + AuthflowV2RouteSettingsIdentityEditUsername = "/settings/identity/edit_username" ) type AuthflowV2NavigatorEndpointsProvider interface { diff --git a/pkg/auth/handler/webapp/authflowv2/select_account.go b/pkg/auth/handler/webapp/authflowv2/select_account.go index cf8ebf4606..e56f011546 100644 --- a/pkg/auth/handler/webapp/authflowv2/select_account.go +++ b/pkg/auth/handler/webapp/authflowv2/select_account.go @@ -240,9 +240,9 @@ func (h *AuthflowV2SelectAccountHandler) ServeHTTP(w http.ResponseWriter, r *htt h.continueFlow(w, r, "/reauth") } - // ctrl.Serve() always write response. + // ctrl.ServeWithDBTx() always write response. // So we have to put http.Redirect before it. - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { // When promote anonymous user, the end-user should not see this page. diff --git a/pkg/auth/handler/webapp/authflowv2/settings.go b/pkg/auth/handler/webapp/authflowv2/settings.go index 8c9cdb610c..61a99676c4 100644 --- a/pkg/auth/handler/webapp/authflowv2/settings.go +++ b/pkg/auth/handler/webapp/authflowv2/settings.go @@ -5,6 +5,7 @@ import ( handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/lib/config" "github.com/authgear/authgear-server/pkg/lib/session" "github.com/authgear/authgear-server/pkg/util/httproute" "github.com/authgear/authgear-server/pkg/util/template" @@ -21,6 +22,10 @@ func ConfigureSettingsV2Route(route httproute.Route) httproute.Route { WithPathPattern(SettingsV2RouteSettings) } +type SettingsAccountDeletionViewModel struct { + AccountDeletionAllowed bool +} + type AuthflowV2SettingsHandler struct { ControllerFactory handlerwebapp.ControllerFactory BaseViewModel *viewmodels.BaseViewModeler @@ -29,6 +34,7 @@ type AuthflowV2SettingsHandler struct { SettingsProfileViewModel *viewmodels.SettingsProfileViewModeler Identities handlerwebapp.SettingsIdentityService Renderer handlerwebapp.Renderer + AccountDeletion *config.AccountDeletionConfig } func (h *AuthflowV2SettingsHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { @@ -62,6 +68,12 @@ func (h *AuthflowV2SettingsHandler) GetData(r *http.Request, rw http.ResponseWri authenticationViewModel := h.AuthenticationViewModel.NewWithCandidates(candidates, r.Form) viewmodels.Embed(data, authenticationViewModel) + // Account Deletion + accountDeletionViewModel := SettingsAccountDeletionViewModel{ + AccountDeletionAllowed: h.AccountDeletion.ScheduledByEndUserEnabled, + } + viewmodels.Embed(data, accountDeletionViewModel) + return data, nil } @@ -71,7 +83,7 @@ func (h *AuthflowV2SettingsHandler) ServeHTTP(w http.ResponseWriter, r *http.Req http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/authflowv2/settings_advanced.go b/pkg/auth/handler/webapp/authflowv2/settings_advanced.go new file mode 100644 index 0000000000..9705b42764 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_advanced.go @@ -0,0 +1,55 @@ +package authflowv2 + +import ( + "net/http" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsV2AdvancedSettingsHTML = template.RegisterHTML( + "web/authflowv2/settings_advanced.html", + handlerwebapp.SettingsComponents..., +) + +type AuthflowV2SettingsAdvancedSettingsHandler struct { + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer +} + +func ConfigureSettingsV2AdvancedSettingsRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "GET", "POST"). + WithPathPattern(SettingsV2RouteAdvancedSettings) +} + +func (h *AuthflowV2SettingsAdvancedSettingsHandler) GetData(r *http.Request, w http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + // BaseViewModel + baseViewModel := h.BaseViewModel.ViewModel(r, w) + viewmodels.Embed(data, baseViewModel) + + return data, nil +} + +func (h *AuthflowV2SettingsAdvancedSettingsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return nil + } + h.Renderer.RenderHTML(w, r, TemplateWebSettingsV2AdvancedSettingsHTML, data) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_biometric.go b/pkg/auth/handler/webapp/authflowv2/settings_biometric.go new file mode 100644 index 0000000000..4e1a424b79 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_biometric.go @@ -0,0 +1,122 @@ +package authflowv2 + +import ( + "net/http" + "time" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httputil" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsV2BiometricHTML = template.RegisterHTML( + "web/authflowv2/settings_biometric.html", + handlerwebapp.SettingsComponents..., +) + +type BiometricIdentity struct { + ID string + DisplayName string + CreatedAt time.Time +} + +type SettingsBiometricViewModel struct { + BiometricIdentities []*BiometricIdentity +} + +type BiometricIdentityProvider interface { + List(userID string) ([]*identity.Biometric, error) +} + +type AuthflowV2SettingsBiometricHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + Identities handlerwebapp.SettingsIdentityService + BiometricProvider BiometricIdentityProvider + AccountManagementService *accountmanagement.Service +} + +func (h *AuthflowV2SettingsBiometricHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + userID := session.GetUserID(r.Context()) + + // BaseViewModel + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + // BiometricViewModel + var biometricIdentityInfos []*identity.Biometric + err := h.Database.WithTx(func() (err error) { + biometricIdentityInfos, err = h.BiometricProvider.List(*userID) + if err != nil { + return err + } + return nil + }) + if err != nil { + return nil, err + } + + biometricViewModel := SettingsBiometricViewModel{} + + for _, biometricInfo := range biometricIdentityInfos { + displayName := biometricInfo.FormattedDeviceInfo() + biometricViewModel.BiometricIdentities = append(biometricViewModel.BiometricIdentities, &BiometricIdentity{ + ID: biometricInfo.ID, + DisplayName: displayName, + CreatedAt: biometricInfo.CreatedAt, + }) + } + + viewmodels.Embed(data, biometricViewModel) + + return data, nil +} + +func (h *AuthflowV2SettingsBiometricHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsV2BiometricHTML, data) + + return nil + }) + + ctrl.PostAction("remove", func() error { + identityID := r.Form.Get("x_identity_id") + + s := session.GetSession(r.Context()) + + input := &accountmanagement.DeleteIdentityBiometricInput{ + IdentityID: identityID, + } + _, err = h.AccountManagementService.DeleteIdentityBiometric(s, input) + if err != nil { + return err + } + + redirectURI := httputil.HostRelative(r.URL).String() + result := webapp.Result{RedirectURI: redirectURI} + result.WriteResponse(w, r) + + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_change_password.go b/pkg/auth/handler/webapp/authflowv2/settings_change_password.go new file mode 100644 index 0000000000..d90c1577ba --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_change_password.go @@ -0,0 +1,123 @@ +package authflowv2 + +import ( + "net/http" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/session" + pwd "github.com/authgear/authgear-server/pkg/util/password" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsV2ChangePasswordHTML = template.RegisterHTML( + "web/authflowv2/settings_change_password.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsChangePasswordSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_old_password": { "type": "string" }, + "x_new_password": { "type": "string" }, + "x_confirm_password": { "type": "string" } + }, + "required": ["x_old_password", "x_new_password", "x_confirm_password"] + } +`) + +type AuthflowV2SettingsChangePasswordHandler struct { + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + AccountManagementService *accountmanagement.Service + PasswordPolicy handlerwebapp.PasswordPolicy +} + +func (h *AuthflowV2SettingsChangePasswordHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := make(map[string]interface{}) + + // BaseViewModel + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + passwordPolicyViewModel := viewmodels.NewPasswordPolicyViewModel( + h.PasswordPolicy.PasswordPolicy(), + h.PasswordPolicy.PasswordRules(), + baseViewModel.RawError, + viewmodels.GetDefaultPasswordPolicyViewModelOptions(), + ) + viewmodels.Embed(data, passwordPolicyViewModel) + + viewmodels.Embed(data, handlerwebapp.ChangePasswordViewModel{ + Force: false, + }) + + return data, nil +} + +func (h *AuthflowV2SettingsChangePasswordHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsV2ChangePasswordHTML, data) + + return nil + }) + + ctrl.PostAction("", func() error { + err := AuthflowV2SettingsChangePasswordSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + oldPassword := r.Form.Get("x_old_password") + newPassword := r.Form.Get("x_new_password") + confirmPassword := r.Form.Get("x_confirm_password") + + err = pwd.ConfirmPassword(newPassword, confirmPassword) + if err != nil { + return err + } + + s := session.GetSession(r.Context()) + webappSession := webapp.GetSession(r.Context()) + var oAuthSessionID string + redirectURI := SettingsV2RouteSettings + if webappSession != nil { + oAuthSessionID = webappSession.OAuthSessionID + redirectURI = webappSession.RedirectURI + } + + input := &accountmanagement.ChangePasswordInput{ + OAuthSessionID: oAuthSessionID, + RedirectURI: redirectURI, + OldPassword: oldPassword, + NewPassword: newPassword, + } + + changePasswordOutput, err := h.AccountManagementService.ChangePassword(s, input) + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: changePasswordOutput.RedirectURI} + result.WriteResponse(w, r) + return nil + }) + +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_delete_account.go b/pkg/auth/handler/webapp/authflowv2/settings_delete_account.go new file mode 100644 index 0000000000..6155009f0d --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_delete_account.go @@ -0,0 +1,131 @@ +package authflowv2 + +import ( + "net/http" + "time" + + "github.com/authgear/authgear-server/pkg/api/apierrors" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/authn/authenticationinfo" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/oauth/oauthsession" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/lib/successpage" + "github.com/authgear/authgear-server/pkg/util/clock" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsV2DeleteAccountHTML = template.RegisterHTML( + "web/authflowv2/settings_delete_account.html", + handlerwebapp.SettingsComponents..., +) + +type AuthflowV2SettingsDeleteAccountViewModel struct { + ExpectedAccountDeletionTime time.Time +} + +type AuthflowV2SettingsDeleteAccountHandler struct { + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + Clock clock.Clock + Cookies handlerwebapp.CookieManager + Users handlerwebapp.SettingsDeleteAccountUserService + Sessions handlerwebapp.SettingsDeleteAccountSessionStore + OAuthSessions handlerwebapp.SettingsDeleteAccountOAuthSessionService + AccountDeletion *config.AccountDeletionConfig + AuthenticationInfoService handlerwebapp.SettingsDeleteAccountAuthenticationInfoService +} + +func (h *AuthflowV2SettingsDeleteAccountHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + // BaseViewModel + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + now := h.Clock.NowUTC() + deletionTime := now.Add(h.AccountDeletion.GracePeriod.Duration()) + deleteAccountViewModel := AuthflowV2SettingsDeleteAccountViewModel{ + ExpectedAccountDeletionTime: deletionTime, + } + viewmodels.Embed(data, deleteAccountViewModel) + + return data, nil +} + +func (h *AuthflowV2SettingsDeleteAccountHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithDBTx() + + currentSession := session.GetSession(r.Context()) + redirectURI := "/settings/delete_account/success" + webSession := webapp.GetSession(r.Context()) + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsV2DeleteAccountHTML, data) + + return nil + }) + + ctrl.PostAction("delete", func() error { + confirmation := r.Form.Get("delete") + isConfirmed := confirmation == "DELETE" + if !isConfirmed { + return apierrors.NewInvalid("confirmation is required to delete account") + } + + err := h.Users.ScheduleDeletionByEndUser(currentSession.GetAuthenticationInfo().UserID) + if err != nil { + return err + } + + if webSession != nil && webSession.OAuthSessionID != "" { + // delete account triggered by sdk via settings action + // handle settings action result here + + authInfoEntry := authenticationinfo.NewEntry(currentSession.CreateNewAuthenticationInfoByThisSession(), webSession.OAuthSessionID, "") + err := h.AuthenticationInfoService.Save(authInfoEntry) + if err != nil { + return err + } + webSession.Extra["authentication_info_id"] = authInfoEntry.ID + err = h.Sessions.Update(webSession) + if err != nil { + return err + } + + entry, err := h.OAuthSessions.Get(webSession.OAuthSessionID) + if err != nil { + return err + } + + entry.T.SettingsActionResult = oauthsession.NewSettingsActionResult() + err = h.OAuthSessions.Save(entry) + if err != nil { + return err + } + } + + // set success page path cookie before visiting success page + result := webapp.Result{ + RedirectURI: redirectURI, + Cookies: []*http.Cookie{ + h.Cookies.ValueCookie(successpage.PathCookieDef, redirectURI), + }, + } + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_delete_account_success.go b/pkg/auth/handler/webapp/authflowv2/settings_delete_account_success.go new file mode 100644 index 0000000000..eb424fedd3 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_delete_account_success.go @@ -0,0 +1,87 @@ +package authflowv2 + +import ( + "net/http" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/util/clock" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsV2DeleteAccountSuccessHTML = template.RegisterHTML( + "web/authflowv2/settings_delete_account_success.html", + handlerwebapp.SettingsComponents..., +) + +type AuthflowV2SettingsDeleteAccountSuccessHandler struct { + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + AccountDeletion *config.AccountDeletionConfig + Clock clock.Clock + UIInfoResolver handlerwebapp.SettingsDeleteAccountSuccessUIInfoResolver + AuthenticationInfoService handlerwebapp.SettingsDeleteAccountSuccessAuthenticationInfoService +} + +func (h *AuthflowV2SettingsDeleteAccountSuccessHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + // BaseViewModel + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + // DeleteAccountViewModel + now := h.Clock.NowUTC() + deletionTime := now.Add(h.AccountDeletion.GracePeriod.Duration()) + deleteAccountViewModel := AuthflowV2SettingsDeleteAccountViewModel{ + ExpectedAccountDeletionTime: deletionTime, + } + viewmodels.Embed(data, deleteAccountViewModel) + + return data, nil +} + +func (h *AuthflowV2SettingsDeleteAccountSuccessHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + webSession := webapp.GetSession(r.Context()) + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return nil + } + h.Renderer.RenderHTML(w, r, TemplateWebSettingsV2DeleteAccountSuccessHTML, data) + return nil + }) + + ctrl.PostAction("", func() error { + redirectURI := "/login" + if webSession != nil && webSession.RedirectURI != "" { + // delete account triggered by sdk via settings action + // redirect to oauth callback + redirectURI = webSession.RedirectURI + if authInfoID, ok := webSession.Extra["authentication_info_id"].(string); ok { + authInfo, err := h.AuthenticationInfoService.Get(authInfoID) + if err != nil { + return err + } + redirectURI = h.UIInfoResolver.SetAuthenticationInfoInQuery(redirectURI, authInfo) + } + } + + result := webapp.Result{ + RedirectURI: redirectURI, + } + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_add_email.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_add_email.go new file mode 100644 index 0000000000..f22a627b47 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_add_email.go @@ -0,0 +1,130 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsIdentityAddEmailHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_add_email.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityAddEmailSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id": { "type": "string" } + }, + "required": ["x_login_id"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityAddEmailRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityAddEmail) +} + +type AuthflowV2SettingsIdentityAddEmailViewModel struct { + LoginIDKey string +} + +type AuthflowV2SettingsIdentityAddEmailHandler struct { + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + AccountManagement accountmanagement.Service +} + +func (h *AuthflowV2SettingsIdentityAddEmailHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + vm := AuthflowV2SettingsIdentityAddEmailViewModel{ + LoginIDKey: loginIDKey, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityAddEmailHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityAddEmailHTML, data) + return nil + }) + + ctrl.PostAction("", func() error { + loginIDKey := r.Form.Get("q_login_id_key") + + err := AuthflowV2SettingsIdentityAddEmailSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + loginID := r.Form.Get("x_login_id") + + s := session.GetSession(r.Context()) + output, err := h.AccountManagement.StartAddIdentityEmail(s, &accountmanagement.StartAddIdentityEmailInput{ + LoginID: loginID, + LoginIDKey: loginIDKey, + }) + if err != nil { + return err + } + + var redirectURI *url.URL + if output.NeedVerification { + redirectURI, err = url.Parse(AuthflowV2RouteSettingsIdentityVerifyEmail) + if err != nil { + return err + } + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + q.Set("q_token", output.Token) + + redirectURI.RawQuery = q.Encode() + } else { + redirectURI, err = url.Parse(AuthflowV2RouteSettingsIdentityListEmail) + if err != nil { + return err + } + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + + redirectURI.RawQuery = q.Encode() + } + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_add_phone.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_add_phone.go new file mode 100644 index 0000000000..d6351e6756 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_add_phone.go @@ -0,0 +1,129 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsIdentityAddPhoneHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_add_phone.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityAddPhoneSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id": { "type": "string" } + }, + "required": ["x_login_id"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityAddPhoneRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityAddPhone) +} + +type AuthflowV2SettingsIdentityAddPhoneViewModel struct { + LoginIDKey string +} + +type AuthflowV2SettingsIdentityAddPhoneHandler struct { + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + AuthenticatorConfig *config.AuthenticatorConfig + AccountManagement accountmanagement.Service +} + +func (h *AuthflowV2SettingsIdentityAddPhoneHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + vm := AuthflowV2SettingsIdentityAddPhoneViewModel{ + LoginIDKey: loginIDKey, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityAddPhoneHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityAddPhoneHTML, data) + return nil + }) + + ctrl.PostAction("", func() error { + loginIDKey := r.Form.Get("q_login_id_key") + + err := AuthflowV2SettingsIdentityAddPhoneSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + loginID := r.Form.Get("x_login_id") + + s := session.GetSession(r.Context()) + output, err := h.AccountManagement.StartAddIdentityPhone(s, &accountmanagement.StartAddIdentityPhoneInput{ + LoginID: loginID, + LoginIDKey: loginIDKey, + }) + if err != nil { + return err + } + + var redirectURI *url.URL + if output.NeedVerification { + redirectURI, err = url.Parse(AuthflowV2RouteSettingsIdentityVerifyPhone) + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + q.Set("q_token", output.Token) + + redirectURI.RawQuery = q.Encode() + } else { + redirectURI, err = url.Parse(AuthflowV2RouteSettingsIdentityListPhone) + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + + redirectURI.RawQuery = q.Encode() + } + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_change_primary_email.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_change_primary_email.go new file mode 100644 index 0000000000..67e3157d39 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_change_primary_email.go @@ -0,0 +1,151 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + "sort" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/authn/stdattrs" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsIdentityChangePrimaryEmailHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_change_primary_email.html", + handlerwebapp.SettingsComponents..., +) + +func ConfigureAuthflowV2SettingsIdentityChangePrimaryEmailRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityChangePrimaryEmail) +} + +type AuthflowV2SettingsIdentityChangePrimaryEmailViewModel struct { + LoginIDKey string + EmailIdentities []*identity.LoginID +} + +type AuthflowV2SettingsIdentityChangePrimaryEmailHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + SettingsProfileViewModel *viewmodels.SettingsProfileViewModeler + Renderer handlerwebapp.Renderer + Users handlerwebapp.SettingsProfileEditUserService + StdAttrs handlerwebapp.SettingsProfileEditStdAttrsService + Identities *identityservice.Service +} + +func (h *AuthflowV2SettingsIdentityChangePrimaryEmailHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + + identities, err := h.Identities.LoginID.List(*userID) + if err != nil { + return nil, err + } + + settingsProfileViewModel, err := h.SettingsProfileViewModel.ViewModel(*userID) + if err != nil { + return nil, err + } + viewmodels.Embed(data, *settingsProfileViewModel) + + var emailIdentities []*identity.LoginID + for _, identity := range identities { + if identity.LoginIDType == model.LoginIDKeyTypeEmail { + emailIdentities = append(emailIdentities, identity) + } + } + + sort.Slice(emailIdentities, func(i, j int) bool { + return emailIdentities[i].UpdatedAt.Before(emailIdentities[j].UpdatedAt) + }) + + vm := AuthflowV2SettingsIdentityListEmailViewModel{ + LoginIDKey: loginIDKey, + EmailIdentities: emailIdentities, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityChangePrimaryEmailHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(r, w) + return err + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityChangePrimaryEmailHTML, data) + return nil + }) + + ctrl.PostAction("save", func() error { + userID := *session.GetUserID(r.Context()) + m := handlerwebapp.JSONPointerFormToMap(r.Form) + + err := h.Database.WithTx(func() error { + u, err := h.Users.GetRaw(userID) + if err != nil { + return err + } + + attrs, err := stdattrs.T(u.StandardAttributes).MergedWithForm(m) + if err != nil { + return err + } + + err = h.StdAttrs.UpdateStandardAttributes(config.RoleEndUser, userID, attrs) + if err != nil { + return err + } + + return nil + }) + if err != nil { + return err + } + + loginIDKey := r.Form.Get("q_login_id_key") + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityListEmail) + if err != nil { + return err + } + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + redirectURI.RawQuery = q.Encode() + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_change_primary_phone.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_change_primary_phone.go new file mode 100644 index 0000000000..a403582d8f --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_change_primary_phone.go @@ -0,0 +1,146 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/authn/stdattrs" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsIdentityChangePrimaryPhoneHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_change_primary_phone.html", + handlerwebapp.SettingsComponents..., +) + +func ConfigureAuthflowV2SettingsIdentityChangePrimaryPhoneRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityChangePrimaryPhone) +} + +type AuthflowV2SettingsIdentityChangePrimaryPhoneViewModel struct { + LoginIDKey string + PhoneIdentities []*identity.LoginID +} + +type AuthflowV2SettingsIdentityChangePrimaryPhoneHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + SettingsProfileViewModel *viewmodels.SettingsProfileViewModeler + Renderer handlerwebapp.Renderer + Users handlerwebapp.SettingsProfileEditUserService + StdAttrs handlerwebapp.SettingsProfileEditStdAttrsService + Identities *identityservice.Service +} + +func (h *AuthflowV2SettingsIdentityChangePrimaryPhoneHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + + identities, err := h.Identities.LoginID.List(*userID) + if err != nil { + return nil, err + } + + settingsProfileViewModel, err := h.SettingsProfileViewModel.ViewModel(*userID) + if err != nil { + return nil, err + } + viewmodels.Embed(data, *settingsProfileViewModel) + + var phoneIdentities []*identity.LoginID + for _, identity := range identities { + if identity.LoginIDType == model.LoginIDKeyTypePhone { + phoneIdentities = append(phoneIdentities, identity) + } + } + + vm := AuthflowV2SettingsIdentityListPhoneViewModel{ + LoginIDKey: loginIDKey, + PhoneIdentities: phoneIdentities, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityChangePrimaryPhoneHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(r, w) + return err + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityChangePrimaryPhoneHTML, data) + return nil + }) + + ctrl.PostAction("save", func() error { + userID := *session.GetUserID(r.Context()) + m := handlerwebapp.JSONPointerFormToMap(r.Form) + + err := h.Database.WithTx(func() error { + u, err := h.Users.GetRaw(userID) + if err != nil { + return err + } + + attrs, err := stdattrs.T(u.StandardAttributes).MergedWithForm(m) + if err != nil { + return err + } + + err = h.StdAttrs.UpdateStandardAttributes(config.RoleEndUser, userID, attrs) + if err != nil { + return err + } + + return nil + }) + if err != nil { + return err + } + + loginIDKey := r.Form.Get("q_login_id_key") + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityListPhone) + if err != nil { + return err + } + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + redirectURI.RawQuery = q.Encode() + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_edit_email.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_edit_email.go new file mode 100644 index 0000000000..dc70503a64 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_edit_email.go @@ -0,0 +1,153 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsIdentityEditEmailHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_edit_email.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityEditEmailSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id": { "type": "string" }, + "x_identity_id": { "type": "string" } + }, + "required": ["x_login_id", "x_identity_id"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityEditEmailRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityEditEmail) +} + +type AuthflowV2SettingsIdentityEditEmailViewModel struct { + LoginIDKey string + Target *identity.LoginID +} + +type AuthflowV2SettingsIdentityEditEmailHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + AccountManagement accountmanagement.Service + Identities *identityservice.Service +} + +func (h *AuthflowV2SettingsIdentityEditEmailHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + identityID := r.Form.Get("q_identity_id") + + userID := session.GetUserID(r.Context()) + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + target, err := h.Identities.LoginID.Get(*userID, identityID) + if err != nil { + return nil, err + } + + vm := AuthflowV2SettingsIdentityEditEmailViewModel{ + LoginIDKey: loginIDKey, + Target: target, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityEditEmailHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err = h.Database.WithTx(func() error { + data, err = h.GetData(r, w) + if err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityEditEmailHTML, data) + return nil + }) + + ctrl.PostAction("", func() error { + + loginIDKey := r.Form.Get("q_login_id_key") + + err := AuthflowV2SettingsIdentityEditEmailSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + loginID := r.Form.Get("x_login_id") + identityID := r.Form.Get("x_identity_id") + + s := session.GetSession(r.Context()) + output, err := h.AccountManagement.StartUpdateIdentityEmail(s, &accountmanagement.StartUpdateIdentityEmailInput{ + LoginID: loginID, + LoginIDKey: loginIDKey, + IdentityID: identityID, + }) + if err != nil { + return err + } + + var redirectURI *url.URL + if output.NeedVerification { + redirectURI, err = url.Parse(AuthflowV2RouteSettingsIdentityVerifyEmail) + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + q.Set("q_token", output.Token) + + redirectURI.RawQuery = q.Encode() + } else { + redirectURI, err = url.Parse(AuthflowV2RouteSettingsIdentityListEmail) + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + + redirectURI.RawQuery = q.Encode() + } + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_edit_phone.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_edit_phone.go new file mode 100644 index 0000000000..f7de237d3b --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_edit_phone.go @@ -0,0 +1,155 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsIdentityEditPhoneHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_edit_phone.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityEditPhoneSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id": { "type": "string" }, + "x_identity_id": { "type": "string" } + }, + "required": ["x_login_id", "x_identity_id"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityEditPhoneRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityEditPhone) +} + +type AuthflowV2SettingsIdentityEditPhoneViewModel struct { + LoginIDKey string + Target *identity.LoginID +} + +type AuthflowV2SettingsIdentityEditPhoneHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + AuthenticatorConfig *config.AuthenticatorConfig + AccountManagement accountmanagement.Service + Identities *identityservice.Service +} + +func (h *AuthflowV2SettingsIdentityEditPhoneHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + identityID := r.Form.Get("q_identity_id") + + userID := session.GetUserID(r.Context()) + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + target, err := h.Identities.LoginID.Get(*userID, identityID) + if err != nil { + return nil, err + } + + vm := AuthflowV2SettingsIdentityEditPhoneViewModel{ + LoginIDKey: loginIDKey, + Target: target, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityEditPhoneHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err = h.Database.WithTx(func() error { + data, err = h.GetData(r, w) + if err != nil { + return err + } + return nil + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityEditPhoneHTML, data) + return nil + }) + + ctrl.PostAction("", func() error { + + loginIDKey := r.Form.Get("q_login_id_key") + + err := AuthflowV2SettingsIdentityEditPhoneSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + loginID := r.Form.Get("x_login_id") + identityID := r.Form.Get("x_identity_id") + + s := session.GetSession(r.Context()) + output, err := h.AccountManagement.StartUpdateIdentityPhone(s, &accountmanagement.StartUpdateIdentityPhoneInput{ + LoginID: loginID, + LoginIDKey: loginIDKey, + IdentityID: identityID, + }) + if err != nil { + return err + } + + var redirectURI *url.URL + if output.NeedVerification { + redirectURI, err = url.Parse(AuthflowV2RouteSettingsIdentityVerifyPhone) + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + q.Set("q_token", output.Token) + + redirectURI.RawQuery = q.Encode() + } else { + redirectURI, err = url.Parse(AuthflowV2RouteSettingsIdentityListPhone) + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + + redirectURI.RawQuery = q.Encode() + } + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_edit_username.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_edit_username.go new file mode 100644 index 0000000000..bd1386a819 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_edit_username.go @@ -0,0 +1,127 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateSettingsIdentityEditUsernameTemplate = template.RegisterHTML( + "web/authflowv2/settings_identity_edit_username.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityEditUsernameSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id_key": { "type": "string" }, + "x_login_id": { "type": "string" }, + "x_identity_id": { "type": "string" } + }, + "required": ["x_login_id_key", "x_login_id", "x_identity_id"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityEditUsername(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityEditUsername) +} + +type AuthflowV2SettingsIdentityEditUsernameViewModel struct { + Identity *identity.LoginID +} + +type AuthflowV2SettingsIdentityEditUsernameHandler struct { + Database *appdb.Handle + AccountManagement *accountmanagement.Service + Identities *identityservice.Service + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer +} + +func (h *AuthflowV2SettingsIdentityEditUsernameHandler) GetData(w http.ResponseWriter, r *http.Request) (map[string]interface{}, error) { + data := map[string]interface{}{} + baseViewModel := h.BaseViewModel.ViewModel(r, w) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + loginID := r.Form.Get("q_login_id") + usernameIdentity, err := h.Identities.LoginID.Get(*userID, loginID) + if err != nil { + return nil, err + } + + vm := AuthflowV2SettingsIdentityEditUsernameViewModel{ + Identity: usernameIdentity, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityEditUsernameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(w, r) + return err + }) + if err != nil { + return err + } + h.Renderer.RenderHTML(w, r, TemplateSettingsIdentityEditUsernameTemplate, data) + return nil + }) + + ctrl.PostAction("", func() error { + err := AuthflowV2SettingsIdentityEditUsernameSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + identityID := r.Form.Get("x_identity_id") + loginIDKey := r.Form.Get("x_login_id_key") + loginID := r.Form.Get("x_login_id") + resolvedSession := session.GetSession(r.Context()) + _, err = h.AccountManagement.UpdateIdentityUsername(resolvedSession, &accountmanagement.UpdateIdentityUsernameInput{ + IdentityID: identityID, + LoginIDKey: loginIDKey, + LoginID: loginID, + }) + if err != nil { + return err + } + + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityListUsername) + if err != nil { + return err + } + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + redirectURI.RawQuery = q.Encode() + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_list_email.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_list_email.go new file mode 100644 index 0000000000..807d6b37c8 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_list_email.go @@ -0,0 +1,132 @@ +package authflowv2 + +import ( + "net/http" + "sort" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/feature/verification" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsIdentityListEmailHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_list_email.html", + handlerwebapp.SettingsComponents..., +) + +func ConfigureAuthflowV2SettingsIdentityListEmailRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityListEmail) +} + +type AuthflowV2SettingsIdentityListEmailViewModel struct { + LoginIDKey string + PrimaryEmail *identity.LoginID + EmailIdentities []*identity.LoginID + Verifications map[string][]verification.ClaimStatus + CreateDisabled bool +} + +type AuthflowV2SettingsIdentityListEmailHandler struct { + Database *appdb.Handle + LoginIDConfig *config.LoginIDConfig + Identities *identityservice.Service + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Verification handlerwebapp.SettingsVerificationService + SettingsProfileViewModel *viewmodels.SettingsProfileViewModeler + Renderer handlerwebapp.Renderer +} + +func (h *AuthflowV2SettingsIdentityListEmailHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + + identities, err := h.Identities.LoginID.List(*userID) + if err != nil { + return nil, err + } + + settingsProfileViewModel, err := h.SettingsProfileViewModel.ViewModel(*userID) + if err != nil { + return nil, err + } + + var primary *identity.LoginID + var emailIdentities []*identity.LoginID + var emailInfos []*identity.Info + for _, identity := range identities { + if identity.LoginIDType == model.LoginIDKeyTypeEmail { + if loginIDKey == "" || identity.LoginIDKey == loginIDKey { + emailIdentities = append(emailIdentities, identity) + emailInfos = append(emailInfos, identity.ToInfo()) + if identity.LoginID == settingsProfileViewModel.Email { + primary = identity + } + } + } + } + + sort.Slice(emailIdentities, func(i, j int) bool { + return emailIdentities[i].UpdatedAt.Before(emailIdentities[j].UpdatedAt) + }) + + verifications, err := h.Verification.GetVerificationStatuses(emailInfos) + if err != nil { + return nil, err + } + + createDisabled := true + if loginIDConfig, ok := h.LoginIDConfig.GetKeyConfig(loginIDKey); ok { + createDisabled = *loginIDConfig.CreateDisabled + } + + vm := AuthflowV2SettingsIdentityListEmailViewModel{ + LoginIDKey: loginIDKey, + EmailIdentities: emailIdentities, + Verifications: verifications, + CreateDisabled: createDisabled, + PrimaryEmail: primary, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityListEmailHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(r, w) + return err + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityListEmailHTML, data) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_list_phone.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_list_phone.go new file mode 100644 index 0000000000..721d6019c9 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_list_phone.go @@ -0,0 +1,132 @@ +package authflowv2 + +import ( + "net/http" + "sort" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/feature/verification" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsIdentityListPhoneHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_list_phone.html", + handlerwebapp.SettingsComponents..., +) + +func ConfigureAuthflowV2SettingsIdentityListPhoneRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityListPhone) +} + +type AuthflowV2SettingsIdentityListPhoneViewModel struct { + LoginIDKey string + PrimaryPhone *identity.LoginID + PhoneIdentities []*identity.LoginID + Verifications map[string][]verification.ClaimStatus + CreateDisabled bool +} + +type AuthflowV2SettingsIdentityListPhoneHandler struct { + Database *appdb.Handle + LoginIDConfig *config.LoginIDConfig + Identities *identityservice.Service + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Verification handlerwebapp.SettingsVerificationService + SettingsProfileViewModel *viewmodels.SettingsProfileViewModeler + Renderer handlerwebapp.Renderer +} + +func (h *AuthflowV2SettingsIdentityListPhoneHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + + identities, err := h.Identities.LoginID.List(*userID) + if err != nil { + return nil, err + } + + settingsProfileViewModel, err := h.SettingsProfileViewModel.ViewModel(*userID) + if err != nil { + return nil, err + } + + var primary *identity.LoginID + var phoneIdentities []*identity.LoginID + var phoneInfos []*identity.Info + for _, identity := range identities { + if identity.LoginIDType == model.LoginIDKeyTypePhone { + if loginIDKey == "" || identity.LoginIDKey == loginIDKey { + phoneIdentities = append(phoneIdentities, identity) + phoneInfos = append(phoneInfos, identity.ToInfo()) + if identity.LoginID == settingsProfileViewModel.PhoneNumber { + primary = identity + } + } + } + } + + sort.Slice(phoneIdentities, func(i, j int) bool { + return phoneIdentities[i].UpdatedAt.Before(phoneIdentities[j].UpdatedAt) + }) + + verifications, err := h.Verification.GetVerificationStatuses(phoneInfos) + if err != nil { + return nil, err + } + + createDisabled := true + if loginIDConfig, ok := h.LoginIDConfig.GetKeyConfig(loginIDKey); ok { + createDisabled = *loginIDConfig.CreateDisabled + } + + vm := AuthflowV2SettingsIdentityListPhoneViewModel{ + LoginIDKey: loginIDKey, + PhoneIdentities: phoneIdentities, + Verifications: verifications, + CreateDisabled: createDisabled, + PrimaryPhone: primary, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityListPhoneHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(r, w) + return err + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityListPhoneHTML, data) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_list_username.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_list_username.go new file mode 100644 index 0000000000..43106ce536 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_list_username.go @@ -0,0 +1,101 @@ +package authflowv2 + +import ( + "net/http" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateSettingsIdentityListUsernameTemplate = template.RegisterHTML( + "web/authflowv2/settings_identity_list_username.html", + handlerwebapp.SettingsComponents..., +) + +func ConfigureAuthflowV2SettingsIdentityListUsername(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityListUsername) +} + +type AuthflowV2SettingsIdentityListUsernameViewModel struct { + LoginIDKey string + UsernameIdentities []*identity.LoginID // Expect to be all username login id + CreateDisabled bool +} + +type AuthflowV2SettingsIdentityListUsernameHandler struct { + Database *appdb.Handle + LoginIDConfig *config.LoginIDConfig + Identities *identityservice.Service + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer +} + +func (h *AuthflowV2SettingsIdentityListUsernameHandler) GetData(w http.ResponseWriter, r *http.Request) (map[string]interface{}, error) { + loginIDKey := r.Form.Get("q_login_id_key") + data := map[string]interface{}{} + baseViewModel := h.BaseViewModel.ViewModel(r, w) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + + identities, err := h.Identities.LoginID.List(*userID) + if err != nil { + return nil, err + } + + var usernameIdentities []*identity.LoginID + for _, identity := range identities { + if identity.LoginIDType == model.LoginIDKeyTypeUsername { + if loginIDKey == "" || identity.LoginIDKey == loginIDKey { + usernameIdentities = append(usernameIdentities, identity) + } + } + } + + createDisabled := true + if loginIDConfig, ok := h.LoginIDConfig.GetKeyConfig(loginIDKey); ok { + createDisabled = *loginIDConfig.CreateDisabled + } + + vm := AuthflowV2SettingsIdentityListUsernameViewModel{ + LoginIDKey: loginIDKey, + UsernameIdentities: usernameIdentities, + CreateDisabled: createDisabled, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityListUsernameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(w, r) + return err + }) + if err != nil { + return err + } + h.Renderer.RenderHTML(w, r, TemplateSettingsIdentityListUsernameTemplate, data) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_new_username.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_new_username.go new file mode 100644 index 0000000000..058c1110d1 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_new_username.go @@ -0,0 +1,115 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateSettingsIdentityNewUsernameTemplate = template.RegisterHTML( + "web/authflowv2/settings_identity_new_username.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityNewUsernameSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id_key": { "type": "string" }, + "x_login_id": { "type": "string" } + }, + "required": ["x_login_id_key", "x_login_id"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityNewUsername(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityNewUsername) +} + +type AuthflowV2SettingsIdentityNewUsernameViewModel struct { + LoginIDKey string +} + +type AuthflowV2SettingsIdentityNewUsernameHandler struct { + Database *appdb.Handle + AccountManagement *accountmanagement.Service + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer +} + +func (h *AuthflowV2SettingsIdentityNewUsernameHandler) GetData(w http.ResponseWriter, r *http.Request) (map[string]interface{}, error) { + data := map[string]interface{}{} + baseViewModel := h.BaseViewModel.ViewModel(r, w) + viewmodels.Embed(data, baseViewModel) + + loginIDKey := r.Form.Get("q_login_id_key") + vm := AuthflowV2SettingsIdentityNewUsernameViewModel{ + LoginIDKey: loginIDKey, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityNewUsernameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(w, r) + return err + }) + if err != nil { + return err + } + h.Renderer.RenderHTML(w, r, TemplateSettingsIdentityNewUsernameTemplate, data) + return nil + }) + + ctrl.PostAction("", func() error { + err := AuthflowV2SettingsIdentityNewUsernameSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + loginIDKey := r.Form.Get("x_login_id_key") + loginID := r.Form.Get("x_login_id") + resolvedSession := session.GetSession(r.Context()) + _, err = h.AccountManagement.AddIdentityUsername(resolvedSession, &accountmanagement.AddIdentityUsernameInput{ + LoginIDKey: loginIDKey, + LoginID: loginID, + }) + if err != nil { + return err + } + + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityListUsername) + if err != nil { + return err + } + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + redirectURI.RawQuery = q.Encode() + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_verify_email.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_verify_email.go new file mode 100644 index 0000000000..82731480cd --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_verify_email.go @@ -0,0 +1,189 @@ +package authflowv2 + +import ( + "math" + "net/http" + "net/url" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/otp" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/infra/mail" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/clock" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsIdentityVerifyEmailHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_verify_email.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityVerifyEmailSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id_key": { "type": "string" }, + "q_token": { "type": "string" }, + "x_code": { "type": "string" } + }, + "required": ["x_login_id_key", "q_token", "x_code"] + } +`) + +var AuthflowV2SettingsIdentityResendEmailSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "q_token": { "type": "string" } + }, + "required": ["q_token"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityVerifyEmailRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityVerifyEmail) +} + +type AuthflowV2SettingsIdentityVerifyEmailViewModel struct { + LoginIDKey string + LoginID string + Token string + + CodeLength int + MaskedClaimValue string + ResendCooldown int + FailedAttemptRateLimitExceeded bool +} + +type AuthflowV2SettingsIdentityVerifyEmailHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + OTPCodeService handlerwebapp.OTPCodeService + Renderer handlerwebapp.Renderer + AccountManagement accountmanagement.Service + Clock clock.Clock + Config *config.AppConfig + AuthenticatorConfig *config.AuthenticatorConfig +} + +func (h *AuthflowV2SettingsIdentityVerifyEmailHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + tokenString := r.Form.Get("q_token") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + s := session.GetSession(r.Context()) + token, err := h.AccountManagement.GetToken(s, tokenString) + if err != nil { + return nil, err + } + + vm := AuthflowV2SettingsIdentityVerifyEmailViewModel{ + LoginIDKey: loginIDKey, + LoginID: token.Identity.Email, + Token: tokenString, + + CodeLength: 6, + MaskedClaimValue: mail.MaskAddress(token.Identity.Email), + } + + state, err := h.OTPCodeService.InspectState(otp.KindVerification(h.Config, model.AuthenticatorOOBChannelEmail), token.Identity.Email) + if err != nil { + return nil, err + } + cooldown := int(math.Ceil(state.CanResendAt.Sub(h.Clock.NowUTC()).Seconds())) // Use ceil, because int conversion truncates decimal and can lead to Please Wait Before Resending error. + if cooldown < 0 { + vm.ResendCooldown = 0 + } else { + vm.ResendCooldown = cooldown + } + + vm.FailedAttemptRateLimitExceeded = state.TooManyAttempts + + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityVerifyEmailHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityVerifyEmailHTML, data) + return nil + }) + + ctrl.PostAction("submit", func() error { + err := AuthflowV2SettingsIdentityVerifyEmailSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + loginIDKey := r.Form.Get("x_login_id_key") + tokenString := r.Form.Get("q_token") + + code := r.Form.Get("x_code") + + s := session.GetSession(r.Context()) + _, err = h.AccountManagement.ResumeAddOrUpdateIdentityEmail(s, tokenString, &accountmanagement.ResumeAddOrUpdateIdentityEmailInput{ + LoginIDKey: loginIDKey, + Code: code, + }) + if err != nil { + return err + } + + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityListEmail) + if err != nil { + return err + } + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + redirectURI.RawQuery = q.Encode() + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) + + ctrl.PostAction("resend", func() error { + err := AuthflowV2SettingsIdentityResendEmailSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + tokenString := r.Form.Get("q_token") + err = h.AccountManagement.ResendOTPCode(session.GetSession(r.Context()), tokenString) + if err != nil { + return err + } + + result := webapp.Result{} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_verify_phone.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_verify_phone.go new file mode 100644 index 0000000000..cb0ab0b55f --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_verify_phone.go @@ -0,0 +1,194 @@ +package authflowv2 + +import ( + "math" + "net/http" + "net/url" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/otp" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/clock" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/phone" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsIdentityVerifyPhoneHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_verify_phone.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityVerifyPhoneSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id_key": { "type": "string" }, + "x_code": { "type": "string" } + }, + "required": ["x_login_id_key", "x_code"] + } +`) + +var AuthflowV2SettingsIdentityResendPhoneSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "q_token": { "type": "string" } + }, + "required": ["q_token"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityVerifyPhoneRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityVerifyPhone) +} + +type AuthflowV2SettingsIdentityVerifyPhoneViewModel struct { + LoginIDKey string + LoginID string + Token string + + CodeLength int + MaskedClaimValue string + ResendCooldown int + FailedAttemptRateLimitExceeded bool +} + +type AuthflowV2SettingsIdentityVerifyPhoneHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + OTPCodeService handlerwebapp.OTPCodeService + Renderer handlerwebapp.Renderer + AccountManagement accountmanagement.Service + Clock clock.Clock + Config *config.AppConfig + AuthenticatorConfig *config.AuthenticatorConfig +} + +func (h *AuthflowV2SettingsIdentityVerifyPhoneHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + tokenString := r.Form.Get("q_token") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + s := session.GetSession(r.Context()) + token, err := h.AccountManagement.GetToken(s, tokenString) + if err != nil { + return nil, err + } + + var channel model.AuthenticatorOOBChannel + if h.AuthenticatorConfig.OOB.SMS.PhoneOTPMode.IsWhatsappEnabled() { + channel = model.AuthenticatorOOBChannelWhatsapp + } else { + channel = model.AuthenticatorOOBChannelSMS + } + + vm := AuthflowV2SettingsIdentityVerifyPhoneViewModel{ + LoginIDKey: loginIDKey, + LoginID: token.Identity.PhoneNumber, + Token: tokenString, + + CodeLength: 6, + MaskedClaimValue: phone.Mask(token.Identity.PhoneNumber), + } + + state, err := h.OTPCodeService.InspectState(otp.KindVerification(h.Config, channel), token.Identity.PhoneNumber) + if err != nil { + return nil, err + } + cooldown := int(math.Ceil(state.CanResendAt.Sub(h.Clock.NowUTC()).Seconds())) // Use ceil, because int conversion truncates decimal and can lead to Please Wait Before Resending error. + if cooldown < 0 { + vm.ResendCooldown = 0 + } else { + vm.ResendCooldown = cooldown + } + + vm.FailedAttemptRateLimitExceeded = state.TooManyAttempts + + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityVerifyPhoneHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityVerifyPhoneHTML, data) + return nil + }) + + ctrl.PostAction("submit", func() error { + err := AuthflowV2SettingsIdentityVerifyPhoneSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + loginIDKey := r.Form.Get("x_login_id_key") + token := r.Form.Get("q_token") + code := r.Form.Get("x_code") + + s := session.GetSession(r.Context()) + _, err = h.AccountManagement.ResumeAddOrUpdateIdentityPhone(s, token, &accountmanagement.ResumeAddOrUpdateIdentityPhoneInput{ + LoginIDKey: loginIDKey, + Code: code, + }) + if err != nil { + return err + } + + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityListPhone) + if err != nil { + return err + } + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + redirectURI.RawQuery = q.Encode() + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) + + ctrl.PostAction("resend", func() error { + err := AuthflowV2SettingsIdentityResendPhoneSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + tokenString := r.Form.Get("q_token") + err = h.AccountManagement.ResendOTPCode(session.GetSession(r.Context()), tokenString) + if err != nil { + return err + } + + result := webapp.Result{} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_view_email.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_view_email.go new file mode 100644 index 0000000000..fd269ababb --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_view_email.go @@ -0,0 +1,201 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/feature/verification" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsIdentityViewEmailHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_view_email.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityUpdateVerificationEmailSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id": { "type": "string" }, + "x_identity_id": { "type": "string" } + }, + "required": ["x_login_id", "x_identity_id"] + } +`) + +var AuthflowV2SettingsRemoveIdentityEmailSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_identity_id": { "type": "string" } + }, + "required": ["x_identity_id"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityViewEmailRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityViewEmail) +} + +type AuthflowV2SettingsIdentityViewEmailViewModel struct { + LoginIDKey string + EmailIdentity *identity.LoginID + Verified bool + Verifications map[string][]verification.ClaimStatus + UpdateDisabled bool + DeleteDisabled bool +} + +type AuthflowV2SettingsIdentityViewEmailHandler struct { + Database *appdb.Handle + LoginIDConfig *config.LoginIDConfig + Identities *identityservice.Service + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Verification verification.Service + Renderer handlerwebapp.Renderer + AccountManagement accountmanagement.Service +} + +func (h *AuthflowV2SettingsIdentityViewEmailHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + identityID := r.Form.Get("q_identity_id") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + + emailIdentity, err := h.Identities.LoginID.Get(*userID, identityID) + if err != nil { + return nil, err + } + + verified, err := h.AccountManagement.CheckIdentityVerified(emailIdentity.ToInfo()) + if err != nil { + return nil, err + } + + updateDisabled := true + deleteDisabled := true + if loginIDConfig, ok := h.LoginIDConfig.GetKeyConfig(loginIDKey); ok { + updateDisabled = *loginIDConfig.UpdateDisabled + deleteDisabled = *loginIDConfig.DeleteDisabled + } + + vm := AuthflowV2SettingsIdentityViewEmailViewModel{ + LoginIDKey: loginIDKey, + EmailIdentity: emailIdentity, + Verified: verified, + UpdateDisabled: updateDisabled, + DeleteDisabled: deleteDisabled, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityViewEmailHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(r, w) + return err + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityViewEmailHTML, data) + return nil + }) + + ctrl.PostAction("remove", func() error { + err := AuthflowV2SettingsRemoveIdentityEmailSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + IdentityID := r.Form.Get("x_identity_id") + _, err = h.AccountManagement.DeleteIdentityEmail(session.GetSession(r.Context()), &accountmanagement.DeleteIdentityEmailInput{ + IdentityID: IdentityID, + }) + if err != nil { + return err + } + + loginIDKey := r.Form.Get("q_login_id_key") + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityListEmail) + if err != nil { + return err + } + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + redirectURI.RawQuery = q.Encode() + + result := webapp.Result{RedirectURI: redirectURI.String()} + + result.WriteResponse(w, r) + return nil + }) + + ctrl.PostAction("verify", func() error { + loginIDKey := r.Form.Get("q_login_id_key") + + err := AuthflowV2SettingsIdentityUpdateVerificationEmailSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + loginID := r.Form.Get("x_login_id") + identityID := r.Form.Get("x_identity_id") + + s := session.GetSession(r.Context()) + output, err := h.AccountManagement.StartUpdateIdentityEmail(s, &accountmanagement.StartUpdateIdentityEmailInput{ + LoginID: loginID, + LoginIDKey: loginIDKey, + IdentityID: identityID, + }) + if err != nil { + return err + } + + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityVerifyEmail) + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + q.Set("q_token", output.Token) + + redirectURI.RawQuery = q.Encode() + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_view_phone.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_view_phone.go new file mode 100644 index 0000000000..6e4b2529b4 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_view_phone.go @@ -0,0 +1,201 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsIdentityViewPhoneHTML = template.RegisterHTML( + "web/authflowv2/settings_identity_view_phone.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsUpdateIdentityVerificationPhoneSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id": { "type": "string" }, + "x_identity_id": { "type": "string" } + }, + "required": ["x_login_id", "x_identity_id"] + } +`) + +var AuthflowV2SettingsRemoveIdentityPhoneSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_identity_id": { "type": "string" } + }, + "required": ["x_identity_id"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityViewPhoneRoute(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityViewPhone) +} + +type AuthflowV2SettingsIdentityViewPhoneViewModel struct { + LoginIDKey string + PhoneIdentity *identity.LoginID + Verified bool + UpdateDisabled bool + DeleteDisabled bool +} + +type AuthflowV2SettingsIdentityViewPhoneHandler struct { + Database *appdb.Handle + LoginIDConfig *config.LoginIDConfig + Identities *identityservice.Service + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Verification handlerwebapp.SettingsVerificationService + Renderer handlerwebapp.Renderer + AuthenticatorConfig *config.AuthenticatorConfig + AccountManagement accountmanagement.Service +} + +func (h *AuthflowV2SettingsIdentityViewPhoneHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + + loginIDKey := r.Form.Get("q_login_id_key") + identityID := r.Form.Get("q_identity_id") + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + + phoneIdentity, err := h.Identities.LoginID.Get(*userID, identityID) + if err != nil { + return nil, err + } + + verified, err := h.AccountManagement.CheckIdentityVerified(phoneIdentity.ToInfo()) + if err != nil { + return nil, err + } + + updateDisabled := true + deleteDisabled := true + if loginIDConfig, ok := h.LoginIDConfig.GetKeyConfig(loginIDKey); ok { + updateDisabled = *loginIDConfig.UpdateDisabled + deleteDisabled = *loginIDConfig.DeleteDisabled + } + + vm := AuthflowV2SettingsIdentityViewPhoneViewModel{ + LoginIDKey: loginIDKey, + PhoneIdentity: phoneIdentity, + Verified: verified, + UpdateDisabled: updateDisabled, + DeleteDisabled: deleteDisabled, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityViewPhoneHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(r, w) + return err + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsIdentityViewPhoneHTML, data) + return nil + }) + + ctrl.PostAction("remove", func() error { + err := AuthflowV2SettingsRemoveIdentityPhoneSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + removeID := r.Form.Get("x_identity_id") + + _, err = h.AccountManagement.DeleteIdentityPhone(session.GetSession(r.Context()), &accountmanagement.DeleteIdentityPhoneInput{ + IdentityID: removeID, + }) + if err != nil { + return err + } + + loginIDKey := r.Form.Get("q_login_id_key") + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityListPhone) + if err != nil { + return err + } + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + redirectURI.RawQuery = q.Encode() + + result := webapp.Result{RedirectURI: redirectURI.String()} + + result.WriteResponse(w, r) + return nil + }) + + ctrl.PostAction("verify", func() error { + loginIDKey := r.Form.Get("q_login_id_key") + + err := AuthflowV2SettingsUpdateIdentityVerificationPhoneSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + loginID := r.Form.Get("x_login_id") + identityID := r.Form.Get("x_identity_id") + + s := session.GetSession(r.Context()) + output, err := h.AccountManagement.StartUpdateIdentityPhone(s, &accountmanagement.StartUpdateIdentityPhoneInput{ + LoginID: loginID, + LoginIDKey: loginIDKey, + IdentityID: identityID, + }) + if err != nil { + return err + } + + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityVerifyPhone) + + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + q.Set("q_token", output.Token) + + redirectURI.RawQuery = q.Encode() + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_identity_view_username.go b/pkg/auth/handler/webapp/authflowv2/settings_identity_view_username.go new file mode 100644 index 0000000000..3814e759f5 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_identity_view_username.go @@ -0,0 +1,138 @@ +package authflowv2 + +import ( + "net/http" + "net/url" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateSettingsIdentityViewUsernameTemplate = template.RegisterHTML( + "web/authflowv2/settings_identity_view_username.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsIdentityDeleteUsernameSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_login_id_key": { "type": "string" }, + "x_identity_id": { "type": "string" } + }, + "required": ["x_identity_id", "x_login_id_key"] + } +`) + +func ConfigureAuthflowV2SettingsIdentityViewUsername(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsIdentityViewUsername) +} + +type AuthflowV2SettingsIdentityViewUsernameViewModel struct { + LoginIDKey string + Identity *identity.LoginID + UpdateDisabled bool + DeleteDisabled bool +} + +type AuthflowV2SettingsIdentityViewUsernameHandler struct { + Database *appdb.Handle + AccountManagement *accountmanagement.Service + LoginIDConfig *config.LoginIDConfig + Identities *identityservice.Service + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer +} + +func (h *AuthflowV2SettingsIdentityViewUsernameHandler) GetData(w http.ResponseWriter, r *http.Request) (map[string]interface{}, error) { + data := map[string]interface{}{} + baseViewModel := h.BaseViewModel.ViewModel(r, w) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + loginID := r.Form.Get("q_login_id") + usernameIdentity, err := h.Identities.LoginID.Get(*userID, loginID) + if err != nil { + return nil, err + } + + updateDisabled := true + deleteDisabled := true + if loginIDConfig, ok := h.LoginIDConfig.GetKeyConfig(usernameIdentity.LoginIDKey); ok { + updateDisabled = *loginIDConfig.UpdateDisabled + deleteDisabled = *loginIDConfig.DeleteDisabled + } + + vm := AuthflowV2SettingsIdentityViewUsernameViewModel{ + LoginIDKey: usernameIdentity.LoginIDKey, + Identity: usernameIdentity, + UpdateDisabled: updateDisabled, + DeleteDisabled: deleteDisabled, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsIdentityViewUsernameHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(w, r) + return err + }) + if err != nil { + return err + } + h.Renderer.RenderHTML(w, r, TemplateSettingsIdentityViewUsernameTemplate, data) + return nil + }) + + ctrl.PostAction("remove", func() error { + err := AuthflowV2SettingsIdentityDeleteUsernameSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + identityID := r.Form.Get("x_identity_id") + loginIDKey := r.Form.Get("x_login_key") + + resolvedSession := session.GetSession(r.Context()) + _, err = h.AccountManagement.DeleteIdentityUsername(resolvedSession, &accountmanagement.DeleteIdentityUsernameInput{ + IdentityID: identityID, + }) + if err != nil { + return err + } + + redirectURI, err := url.Parse(AuthflowV2RouteSettingsIdentityListUsername) + if err != nil { + return err + } + q := redirectURI.Query() + q.Set("q_login_id_key", loginIDKey) + redirectURI.RawQuery = q.Encode() + result := webapp.Result{RedirectURI: redirectURI.String()} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_mfa.go b/pkg/auth/handler/webapp/authflowv2/settings_mfa.go new file mode 100644 index 0000000000..95aa6f82f1 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_mfa.go @@ -0,0 +1,73 @@ +package authflowv2 + +import ( + "net/http" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/authn/mfa" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsMFAHTML = template.RegisterHTML( + "web/authflowv2/settings_mfa.html", + handlerwebapp.SettingsComponents..., +) + +type AuthflowV2SettingsMFAHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + SettingsViewModel *viewmodels.SettingsViewModeler + Renderer handlerwebapp.Renderer + MFA *mfa.Service +} + +func (h *AuthflowV2SettingsMFAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + userID := session.GetUserID(r.Context()) + + data := map[string]interface{}{} + + err := h.Database.WithTx(func() error { + baseViewModel := h.BaseViewModel.ViewModel(r, w) + viewmodels.Embed(data, baseViewModel) + + viewModelPtr, err := h.SettingsViewModel.ViewModel(*userID) + if err != nil { + return err + } + viewmodels.Embed(data, *viewModelPtr) + return nil + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsMFAHTML, data) + + return nil + }) + + ctrl.PostAction("revoke_device", func() error { + userID := session.GetUserID(r.Context()) + err := h.MFA.InvalidateAllDeviceTokens(*userID) + if err != nil { + return err + } + + result := webapp.Result{} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_mfa_create_password.go b/pkg/auth/handler/webapp/authflowv2/settings_mfa_create_password.go new file mode 100644 index 0000000000..404605eabf --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_mfa_create_password.go @@ -0,0 +1,111 @@ +package authflowv2 + +import ( + "net/http" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + pwd "github.com/authgear/authgear-server/pkg/util/password" + "github.com/authgear/authgear-server/pkg/util/template" + "github.com/authgear/authgear-server/pkg/util/validation" +) + +var TemplateWebSettingsMFACreatePasswordHTML = template.RegisterHTML( + "web/authflowv2/settings_mfa_create_password.html", + handlerwebapp.SettingsComponents..., +) + +var AuthflowV2SettingsMFACreatePasswordSchema = validation.NewSimpleSchema(` + { + "type": "object", + "properties": { + "x_password": { "type": "string" }, + "x_confirm_password": { "type": "string" } + }, + "required": ["x_password", "x_confirm_password"] + } +`) + +func ConfigureAuthflowV2SettingsMFACreatePassword(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsMFACreatePassword) +} + +type AuthflowV2SettingsMFACreatePasswordHandler struct { + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + SettingsViewModel *viewmodels.SettingsViewModeler + PasswordPolicy handlerwebapp.PasswordPolicy + Renderer handlerwebapp.Renderer + + AccountManagementService *accountmanagement.Service +} + +func (h *AuthflowV2SettingsMFACreatePasswordHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := make(map[string]interface{}) + + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + passwordPolicyViewModel := viewmodels.NewPasswordPolicyViewModel( + h.PasswordPolicy.PasswordPolicy(), + h.PasswordPolicy.PasswordRules(), + baseViewModel.RawError, + viewmodels.GetDefaultPasswordPolicyViewModelOptions(), + ) + viewmodels.Embed(data, passwordPolicyViewModel) + + return data, nil +} + +func (h *AuthflowV2SettingsMFACreatePasswordHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return err + } + h.Renderer.RenderHTML(w, r, TemplateWebSettingsMFACreatePasswordHTML, data) + return nil + }) + + ctrl.PostAction("", func() error { + err := AuthflowV2SettingsMFACreatePasswordSchema.Validator().ValidateValue(handlerwebapp.FormToJSON(r.Form)) + if err != nil { + return err + } + + newPassword := r.Form.Get("x_password") + confirmPassword := r.Form.Get("x_confirm_password") + + err = pwd.ConfirmPassword(newPassword, confirmPassword) + if err != nil { + return err + } + + s := session.GetSession(r.Context()) + err = h.AccountManagementService.CreateAdditionalPassword(s, accountmanagement.CreateAdditionalPasswordInput{ + PlainPassword: newPassword, + }) + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: AuthflowV2RouteSettingsMFA} + result.WriteResponse(w, r) + + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_mfa_password.go b/pkg/auth/handler/webapp/authflowv2/settings_mfa_password.go new file mode 100644 index 0000000000..eee8da1650 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_mfa_password.go @@ -0,0 +1,72 @@ +package authflowv2 + +import ( + "net/http" + + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsMFAPasswordHTML = template.RegisterHTML( + "web/authflowv2/settings_mfa_password.html", + handlerwebapp.SettingsComponents..., +) + +type AuthflowV2SettingsMFAPasswordHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + SettingsViewModel *viewmodels.SettingsViewModeler + Renderer handlerwebapp.Renderer +} + +func ConfigureAuthflowV2SettingsMFAPassword(route httproute.Route) httproute.Route { + return route. + WithMethods("OPTIONS", "POST", "GET"). + WithPathPattern(AuthflowV2RouteSettingsMFAPassword) +} + +func (h *AuthflowV2SettingsMFAPasswordHandler) GetData(r *http.Request, w http.ResponseWriter) (map[string]interface{}, error) { + userID := session.GetUserID(r.Context()) + data := map[string]interface{}{} + + baseViewModel := h.BaseViewModel.ViewModel(r, w) + viewmodels.Embed(data, baseViewModel) + + err := h.Database.WithTx(func() error { + viewModelPtr, err := h.SettingsViewModel.ViewModel(*userID) + if err != nil { + return err + } + viewmodels.Embed(data, *viewModelPtr) + return nil + }) + if err != nil { + return nil, err + } + + return data, nil + +} + +func (h *AuthflowV2SettingsMFAPasswordHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return nil + } + h.Renderer.RenderHTML(w, r, TemplateWebSettingsMFAPasswordHTML, data) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_oob_otp.go b/pkg/auth/handler/webapp/authflowv2/settings_oob_otp.go new file mode 100644 index 0000000000..39af3b5846 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_oob_otp.go @@ -0,0 +1,90 @@ +package authflowv2 + +import ( + "net/http" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/lib/authn/authenticator" + authenticatorservice "github.com/authgear/authgear-server/pkg/lib/authn/authenticator/service" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httproute" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsOOBOTPHTML = template.RegisterHTML( + "web/authflowv2/settings_oob_otp.html", + handlerwebapp.SettingsComponents..., +) + +type AuthflowV2SettingsOOBOTPViewModel struct { + OOBOTPType string + OOBOTPAuthenticators []*authenticator.OOBOTP +} + +type AuthflowV2SettingsOOBOTPHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + Authenticators authenticatorservice.Service +} + +func (h *AuthflowV2SettingsOOBOTPHandler) GetData(w http.ResponseWriter, r *http.Request) (map[string]interface{}, error) { + data := map[string]interface{}{} + baseViewModel := h.BaseViewModel.ViewModel(r, w) + viewmodels.Embed(data, baseViewModel) + + oc := httproute.GetParam(r, "channel") + + userID := session.GetUserID(r.Context()) + t, err := model.GetOOBAuthenticatorType(model.AuthenticatorOOBChannel(oc)) + if err != nil { + return nil, err + } + authenticators, err := h.Authenticators.List( + *userID, + authenticator.KeepKind(authenticator.KindSecondary), + authenticator.KeepType(t), + ) + if err != nil { + return nil, err + } + + var OOBOTPAuthenticators []*authenticator.OOBOTP + for _, a := range authenticators { + OOBOTPAuthenticators = append(OOBOTPAuthenticators, a.OOBOTP) + } + vm := AuthflowV2SettingsOOBOTPViewModel{ + OOBOTPType: oc, + OOBOTPAuthenticators: OOBOTPAuthenticators, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsOOBOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(w, r) + return err + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsOOBOTPHTML, data) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_passkey.go b/pkg/auth/handler/webapp/authflowv2/settings_passkey.go new file mode 100644 index 0000000000..e6c3b695cb --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_passkey.go @@ -0,0 +1,157 @@ +package authflowv2 + +import ( + "encoding/json" + "net/http" + + "github.com/go-webauthn/webauthn/protocol" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/accountmanagement" + "github.com/authgear/authgear-server/pkg/lib/authn/identity" + identityservice "github.com/authgear/authgear-server/pkg/lib/authn/identity/service" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/httputil" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateSettingsV2PasskeyHTML = template.RegisterHTML( + "web/authflowv2/settings_passkey.html", + handlerwebapp.SettingsComponents..., +) + +type AuthflowV2SettingsPasskeyViewModel struct { + PasskeyIdentities []*identity.Info + CreationOptionsJSON string +} + +type PasskeyCreationOptionsService interface { + MakeCreationOptions(userID string) (*model.WebAuthnCreationOptions, error) +} + +type AuthflowV2SettingsChangePasskeyHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + Identities identityservice.Service + AccountManagement *accountmanagement.Service + Passkey PasskeyCreationOptionsService +} + +func (h *AuthflowV2SettingsChangePasskeyHandler) GetData(r *http.Request, rw http.ResponseWriter) (map[string]interface{}, error) { + data := map[string]interface{}{} + userID := session.GetUserID(r.Context()) + + // BaseViewModel + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + // PasskeyViewModel + var passkeyIdentities []*identity.Info + var creationOptionsJSON string + err := h.Database.WithTx(func() (err error) { + identities, err := h.Identities.Passkey.List(*userID) + if err != nil { + return err + } + for _, i := range identities { + passkeyIdentities = append(passkeyIdentities, i.ToInfo()) + } + + creationOptions, err := h.Passkey.MakeCreationOptions(*userID) + if err != nil { + return err + } + creationOptionsJSONBytes, err := json.Marshal(creationOptions) + if err != nil { + return err + } + creationOptionsJSON = string(creationOptionsJSONBytes) + return nil + }) + + if err != nil { + return nil, err + } + + passkeyViewModel := AuthflowV2SettingsPasskeyViewModel{ + PasskeyIdentities: passkeyIdentities, + CreationOptionsJSON: creationOptionsJSON, + } + viewmodels.Embed(data, passkeyViewModel) + + return data, nil +} + +func (h *AuthflowV2SettingsChangePasskeyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + data, err := h.GetData(r, w) + if err != nil { + return err + } + h.Renderer.RenderHTML(w, r, TemplateSettingsV2PasskeyHTML, data) + + return nil + }) + + ctrl.PostAction("add", func() error { + attestationResponseStr := r.Form.Get("x_attestation_response") + + var creationResponse protocol.CredentialCreationResponse + err := json.Unmarshal([]byte(attestationResponseStr), &creationResponse) + if err != nil { + return err + } + + s := session.GetSession(r.Context()) + + input := &accountmanagement.AddPasskeyInput{ + CreationResponse: &creationResponse, + } + + _, err = h.AccountManagement.AddPasskey(s, input) + if err != nil { + return err + } + + redirectURI := httputil.HostRelative(r.URL).String() + result := webapp.Result{RedirectURI: redirectURI} + result.WriteResponse(w, r) + + return nil + + }) + + ctrl.PostAction("remove", func() error { + identityID := r.Form.Get("x_identity_id") + + s := session.GetSession(r.Context()) + + input := &accountmanagement.DeletePasskeyInput{ + IdentityID: identityID, + } + + _, err = h.AccountManagement.DeletePasskey(s, input) + if err != nil { + return err + } + + redirectURI := httputil.HostRelative(r.URL).String() + result := webapp.Result{RedirectURI: redirectURI} + result.WriteResponse(w, r) + + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_profile.go b/pkg/auth/handler/webapp/authflowv2/settings_profile.go index 61d27fca5f..131aedac03 100644 --- a/pkg/auth/handler/webapp/authflowv2/settings_profile.go +++ b/pkg/auth/handler/webapp/authflowv2/settings_profile.go @@ -27,7 +27,7 @@ func (h *AuthflowV2SettingsProfileHandler) ServeHTTP(w http.ResponseWriter, r *h http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { userID := session.GetUserID(r.Context()) diff --git a/pkg/auth/handler/webapp/authflowv2/settings_profile_edit.go b/pkg/auth/handler/webapp/authflowv2/settings_profile_edit.go index ce31ba90be..0cd71b9a59 100644 --- a/pkg/auth/handler/webapp/authflowv2/settings_profile_edit.go +++ b/pkg/auth/handler/webapp/authflowv2/settings_profile_edit.go @@ -45,6 +45,10 @@ func init() { "web/authflowv2/settings_profile_edit_zoneinfo.html", handlerwebapp.SettingsComponents..., ) + settingsProfileEditVariantToTemplate["custom_attributes"] = template.RegisterHTML( + "web/authflowv2/settings_profile_edit_custom.html", + handlerwebapp.SettingsComponents..., + ) } var settingsProfileEditVariantToTemplate map[string]*template.HTML @@ -71,6 +75,7 @@ func (h *AuthflowV2SettingsProfileEditHandler) GetData(r *http.Request, rw http. userID := session.GetUserID(r.Context()) data := map[string]interface{}{} + data["Pointer"] = r.Form.Get("pointer") baseViewModel := h.BaseViewModel.ViewModel(r, rw) viewmodels.Embed(data, baseViewModel) @@ -84,7 +89,7 @@ func (h *AuthflowV2SettingsProfileEditHandler) GetData(r *http.Request, rw http. return data, nil } -func (h *AuthflowV2SettingsProfileEditHandler) isAttributeEditable(attributeVariant string) bool { +func (h *AuthflowV2SettingsProfileEditHandler) isAttributeEditable(attributeVariant string, isAlreadyPointer bool) bool { accessControl := h.UserProfileConfig.StandardAttributes.GetAccessControl().MergedWith( h.UserProfileConfig.CustomAttributes.GetAccessControl(), ) @@ -109,7 +114,11 @@ func (h *AuthflowV2SettingsProfileEditHandler) isAttributeEditable(attributeVari } return false default: - return isEditable("/" + attributeVariant) + if isAlreadyPointer { + return isEditable(attributeVariant) + } else { + return isEditable("/" + attributeVariant) + } } } @@ -119,7 +128,7 @@ func (h *AuthflowV2SettingsProfileEditHandler) ServeHTTP(w http.ResponseWriter, http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) @@ -135,7 +144,13 @@ func (h *AuthflowV2SettingsProfileEditHandler) ServeHTTP(w http.ResponseWriter, return nil } - hasPermissionToEdit := h.isAttributeEditable(variant) + hasPermissionToEdit := false + if variant == "custom_attributes" { + attribute := r.Form.Get("pointer") + hasPermissionToEdit = h.isAttributeEditable(attribute, true) + } else { + hasPermissionToEdit = h.isAttributeEditable(variant, false) + } if !hasPermissionToEdit { h.Renderer.RenderHTML(w, r, TemplateSettingsProfileNoPermission, data) diff --git a/pkg/auth/handler/webapp/authflowv2/settings_sessions.go b/pkg/auth/handler/webapp/authflowv2/settings_sessions.go new file mode 100644 index 0000000000..69846f5958 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_sessions.go @@ -0,0 +1,177 @@ +package authflowv2 + +import ( + "net/http" + "time" + + "github.com/authgear/authgear-server/pkg/api/apierrors" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/auth/webapp" + "github.com/authgear/authgear-server/pkg/lib/config" + "github.com/authgear/authgear-server/pkg/lib/oauth" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/lib/sessionlisting" + "github.com/authgear/authgear-server/pkg/util/httputil" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsV2SessionsHTML = template.RegisterHTML( + "web/authflowv2/settings_sessions.html", + handlerwebapp.SettingsComponents..., +) + +type Authorization struct { + ID string + ClientID string + ClientName string + Scope []string + CreatedAt time.Time + HasFullUserInfoAccess bool +} + +type SettingsSessionsViewModel struct { + CurrentSessionID string + Sessions []*sessionlisting.Session + Authorizations []Authorization +} + +type AuthflowV2SettingsSessionsHandler struct { + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + Sessions handlerwebapp.SettingsSessionManager + Authorizations handlerwebapp.SettingsAuthorizationService + OAuthConfig *config.OAuthConfig + SessionListing handlerwebapp.SettingsSessionListingService +} + +func (h *AuthflowV2SettingsSessionsHandler) GetData(r *http.Request, rw http.ResponseWriter, s session.ResolvedSession) (map[string]interface{}, error) { + data := map[string]interface{}{} + + // BaseViewModel + baseViewModel := h.BaseViewModel.ViewModel(r, rw) + viewmodels.Embed(data, baseViewModel) + + // SettingsSessionsViewModel + userID := s.GetAuthenticationInfo().UserID + settingsSessionsViewModel := SettingsSessionsViewModel{} + + ss, err := h.Sessions.List(userID) + if err != nil { + return nil, err + } + + sessionModels, err := h.SessionListing.FilterForDisplay(ss, s) + if err != nil { + return nil, err + } + settingsSessionsViewModel.Sessions = sessionModels + + // Get third party app authorization + clientNameMap := map[string]string{} + for _, c := range h.OAuthConfig.Clients { + clientNameMap[c.ClientID] = c.ClientName + } + filter := oauth.NewKeepThirdPartyAuthorizationFilter(h.OAuthConfig) + authorizations, err := h.Authorizations.ListByUser(userID, filter) + if err != nil { + return nil, err + } + authzs := []Authorization{} + for _, authz := range authorizations { + clientName := clientNameMap[authz.ClientID] + authzs = append(authzs, Authorization{ + ID: authz.ID, + ClientID: authz.ClientID, + ClientName: clientName, + Scope: authz.Scopes, + CreatedAt: authz.CreatedAt, + HasFullUserInfoAccess: authz.IsAuthorized([]string{oauth.FullUserInfoScope}), + }) + } + + settingsSessionsViewModel.Authorizations = authzs + + settingsSessionsViewModel.CurrentSessionID = s.SessionID() + viewmodels.Embed(data, settingsSessionsViewModel) + + return data, nil +} + +func (h *AuthflowV2SettingsSessionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithDBTx() + + currentSession := session.GetSession(r.Context()) + redirectURI := httputil.HostRelative(r.URL).String() + + ctrl.Get(func() error { + data, err := h.GetData(r, w, currentSession) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsV2SessionsHTML, data) + + return nil + }) + + ctrl.PostAction("revoke", func() error { + sessionID := r.Form.Get("x_session_id") + if sessionID == currentSession.SessionID() { + return apierrors.NewInvalid("cannot revoke current session") + } + + s, err := h.Sessions.Get(sessionID) + if err != nil { + return err + } + + err = h.Sessions.RevokeWithEvent(s, true, false) + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: redirectURI} + result.WriteResponse(w, r) + return nil + }) + + ctrl.PostAction("revoke_all", func() error { + userID := currentSession.GetAuthenticationInfo().UserID + err := h.Sessions.TerminateAllExcept(userID, currentSession, false) + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: redirectURI} + result.WriteResponse(w, r) + return nil + }) + + ctrl.PostAction("remove_authorization", func() error { + authorizationID := r.Form.Get("x_authorization_id") + authz, err := h.Authorizations.GetByID(authorizationID) + if err != nil { + return err + } + + if authz.UserID != currentSession.GetAuthenticationInfo().UserID { + return apierrors.NewForbidden("cannot remove authorization") + } + + err = h.Authorizations.Delete(authz) + if err != nil { + return err + } + + result := webapp.Result{RedirectURI: redirectURI} + result.WriteResponse(w, r) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/settings_totp.go b/pkg/auth/handler/webapp/authflowv2/settings_totp.go new file mode 100644 index 0000000000..1760f8b272 --- /dev/null +++ b/pkg/auth/handler/webapp/authflowv2/settings_totp.go @@ -0,0 +1,83 @@ +package authflowv2 + +import ( + "net/http" + + "github.com/authgear/authgear-server/pkg/api/model" + handlerwebapp "github.com/authgear/authgear-server/pkg/auth/handler/webapp" + "github.com/authgear/authgear-server/pkg/auth/handler/webapp/viewmodels" + "github.com/authgear/authgear-server/pkg/lib/authn/authenticator" + authenticatorservice "github.com/authgear/authgear-server/pkg/lib/authn/authenticator/service" + "github.com/authgear/authgear-server/pkg/lib/infra/db/appdb" + "github.com/authgear/authgear-server/pkg/lib/session" + "github.com/authgear/authgear-server/pkg/util/template" +) + +var TemplateWebSettingsTOTPHTML = template.RegisterHTML( + "web/authflowv2/settings_totp.html", + handlerwebapp.SettingsComponents..., +) + +type AuthflowV2SettingsTOTPViewModel struct { + TOTPAuthenticators []*authenticator.TOTP +} + +type AuthflowV2SettingsTOTPHandler struct { + Database *appdb.Handle + ControllerFactory handlerwebapp.ControllerFactory + BaseViewModel *viewmodels.BaseViewModeler + Renderer handlerwebapp.Renderer + Authenticators authenticatorservice.Service +} + +func (h *AuthflowV2SettingsTOTPHandler) GetData(w http.ResponseWriter, r *http.Request) (map[string]interface{}, error) { + data := map[string]interface{}{} + baseViewModel := h.BaseViewModel.ViewModel(r, w) + viewmodels.Embed(data, baseViewModel) + + userID := session.GetUserID(r.Context()) + authenticators, err := h.Authenticators.List( + *userID, + authenticator.KeepKind(authenticator.KindSecondary), + authenticator.KeepType(model.AuthenticatorTypeTOTP), + ) + + if err != nil { + return nil, err + } + + var totpAuthenticators []*authenticator.TOTP + for _, a := range authenticators { + totpAuthenticators = append(totpAuthenticators, a.TOTP) + } + + vm := AuthflowV2SettingsTOTPViewModel{ + TOTPAuthenticators: totpAuthenticators, + } + viewmodels.Embed(data, vm) + + return data, nil +} + +func (h *AuthflowV2SettingsTOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + ctrl, err := h.ControllerFactory.New(r, w) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + defer ctrl.ServeWithoutDBTx() + + ctrl.Get(func() error { + var data map[string]interface{} + err := h.Database.WithTx(func() error { + data, err = h.GetData(w, r) + return err + }) + if err != nil { + return err + } + + h.Renderer.RenderHTML(w, r, TemplateWebSettingsTOTPHTML, data) + return nil + }) +} diff --git a/pkg/auth/handler/webapp/authflowv2/verify_login_link.go b/pkg/auth/handler/webapp/authflowv2/verify_login_link.go index 7016c76090..3204c5efc7 100644 --- a/pkg/auth/handler/webapp/authflowv2/verify_login_link.go +++ b/pkg/auth/handler/webapp/authflowv2/verify_login_link.go @@ -108,7 +108,7 @@ func (h *AuthflowV2VerifyLoginLinkOTPHandler) ServeHTTP(w http.ResponseWriter, r http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() finishWithState := func(state LoginLinkOTPPageQueryState) { url := url.URL{} diff --git a/pkg/auth/handler/webapp/change_password.go b/pkg/auth/handler/webapp/change_password.go index 856f029f79..0c3bae4395 100644 --- a/pkg/auth/handler/webapp/change_password.go +++ b/pkg/auth/handler/webapp/change_password.go @@ -68,7 +68,7 @@ func (h *ForceChangePasswordHandler) ServeHTTP(w http.ResponseWriter, r *http.Re http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { // Ensure there is an ongoing web session. diff --git a/pkg/auth/handler/webapp/change_secondary_password.go b/pkg/auth/handler/webapp/change_secondary_password.go index a37fca5282..268e8b1dac 100644 --- a/pkg/auth/handler/webapp/change_secondary_password.go +++ b/pkg/auth/handler/webapp/change_secondary_password.go @@ -67,7 +67,7 @@ func (h *ForceChangeSecondaryPasswordHandler) ServeHTTP(w http.ResponseWriter, r http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { // Ensure there is an ongoing web session. diff --git a/pkg/auth/handler/webapp/confirm_terminate_other_sessions.go b/pkg/auth/handler/webapp/confirm_terminate_other_sessions.go index e10550853a..6f28bfcd88 100644 --- a/pkg/auth/handler/webapp/confirm_terminate_other_sessions.go +++ b/pkg/auth/handler/webapp/confirm_terminate_other_sessions.go @@ -61,7 +61,7 @@ func (h *ConfirmTerminateOtherSessionsHandler) ServeHTTP(w http.ResponseWriter, http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/confirm_web3_account.go b/pkg/auth/handler/webapp/confirm_web3_account.go index f533af547d..10c432a6c2 100644 --- a/pkg/auth/handler/webapp/confirm_web3_account.go +++ b/pkg/auth/handler/webapp/confirm_web3_account.go @@ -92,7 +92,7 @@ func (h *ConnectWeb3AccountHandler) ServeHTTP(w http.ResponseWriter, r *http.Req http.Redirect(w, r, "/", http.StatusFound) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() opts := webapp.SessionOptions{ RedirectURI: ctrl.RedirectURI(), diff --git a/pkg/auth/handler/webapp/controller.go b/pkg/auth/handler/webapp/controller.go index 9462426eb7..f18d4f7ff7 100644 --- a/pkg/auth/handler/webapp/controller.go +++ b/pkg/auth/handler/webapp/controller.go @@ -151,7 +151,23 @@ func (c *Controller) DeleteSession(id string) error { return c.Page.DeleteSession(id) } -func (c *Controller) Serve() { +func (c *Controller) ServeWithoutDBTx() { + c.serve(serveOption{ + withDBTx: false, + }) +} + +func (c *Controller) ServeWithDBTx() { + c.serve(serveOption{ + withDBTx: true, + }) +} + +type serveOption struct { + withDBTx bool +} + +func (c *Controller) serve(option serveOption) { var err error fns := [](func() error){ func() error { @@ -176,7 +192,7 @@ func (c *Controller) Serve() { http.Error(c.response, "Invalid request method", http.StatusMethodNotAllowed) } - err = c.Database.WithTx(func() error { + handleFunc := func() error { for _, fn := range fns { err := fn() if err != nil { @@ -184,7 +200,13 @@ func (c *Controller) Serve() { } } return nil - }) + } + + if option.withDBTx { + err = c.Database.WithTx(handleFunc) + } else { + err = handleFunc() + } if err != nil { if apierrors.IsAPIError(err) { diff --git a/pkg/auth/handler/webapp/create_passkey.go b/pkg/auth/handler/webapp/create_passkey.go index 3f3067edb7..17f7bf0008 100644 --- a/pkg/auth/handler/webapp/create_passkey.go +++ b/pkg/auth/handler/webapp/create_passkey.go @@ -49,7 +49,7 @@ func (h *CreatePasskeyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/create_password.go b/pkg/auth/handler/webapp/create_password.go index 6b533a50b6..9c00a6209c 100644 --- a/pkg/auth/handler/webapp/create_password.go +++ b/pkg/auth/handler/webapp/create_password.go @@ -103,7 +103,7 @@ func (h *CreatePasswordHandler) ServeHTTP(w http.ResponseWriter, r *http.Request http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/enter_login_id.go b/pkg/auth/handler/webapp/enter_login_id.go index ec3ba27a6f..2081190ca7 100644 --- a/pkg/auth/handler/webapp/enter_login_id.go +++ b/pkg/auth/handler/webapp/enter_login_id.go @@ -140,7 +140,7 @@ func (h *EnterLoginIDHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() userID := ctrl.RequireUserID() diff --git a/pkg/auth/handler/webapp/enter_oob_otp.go b/pkg/auth/handler/webapp/enter_oob_otp.go index ee8052f73d..5ffcde1654 100644 --- a/pkg/auth/handler/webapp/enter_oob_otp.go +++ b/pkg/auth/handler/webapp/enter_oob_otp.go @@ -157,7 +157,7 @@ func (h *EnterOOBOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/enter_password.go b/pkg/auth/handler/webapp/enter_password.go index ee45e73123..221abddf9a 100644 --- a/pkg/auth/handler/webapp/enter_password.go +++ b/pkg/auth/handler/webapp/enter_password.go @@ -114,7 +114,7 @@ func (h *EnterPasswordHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/enter_recovery_code.go b/pkg/auth/handler/webapp/enter_recovery_code.go index 5105f061cf..25e022d374 100644 --- a/pkg/auth/handler/webapp/enter_recovery_code.go +++ b/pkg/auth/handler/webapp/enter_recovery_code.go @@ -64,7 +64,7 @@ func (h *EnterRecoveryCodeHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/enter_totp.go b/pkg/auth/handler/webapp/enter_totp.go index 6d66512fc4..6f86a911f0 100644 --- a/pkg/auth/handler/webapp/enter_totp.go +++ b/pkg/auth/handler/webapp/enter_totp.go @@ -64,7 +64,7 @@ func (h *EnterTOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/error.go b/pkg/auth/handler/webapp/error.go index 12f546221a..04f1c8ae5c 100644 --- a/pkg/auth/handler/webapp/error.go +++ b/pkg/auth/handler/webapp/error.go @@ -38,7 +38,7 @@ func (h *ErrorHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/error_feature_disabled.go b/pkg/auth/handler/webapp/error_feature_disabled.go index 29916fe2d5..68a7fada4a 100644 --- a/pkg/auth/handler/webapp/error_feature_disabled.go +++ b/pkg/auth/handler/webapp/error_feature_disabled.go @@ -39,7 +39,7 @@ func (h *FeatureDisabledHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/forgot_password.go b/pkg/auth/handler/webapp/forgot_password.go index 3b57a7a7d9..c8ac650f01 100644 --- a/pkg/auth/handler/webapp/forgot_password.go +++ b/pkg/auth/handler/webapp/forgot_password.go @@ -72,7 +72,7 @@ func (h *ForgotPasswordHandler) ServeHTTP(w http.ResponseWriter, r *http.Request http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() opts := webapp.SessionOptions{ KeepAfterFinish: true, diff --git a/pkg/auth/handler/webapp/forgot_password_success.go b/pkg/auth/handler/webapp/forgot_password_success.go index bad0ae3b1f..d92c89c1ee 100644 --- a/pkg/auth/handler/webapp/forgot_password_success.go +++ b/pkg/auth/handler/webapp/forgot_password_success.go @@ -53,7 +53,7 @@ func (h *ForgotPasswordSuccessHandler) ServeHTTP(w http.ResponseWriter, r *http. http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/login.go b/pkg/auth/handler/webapp/login.go index 8a33282ce6..00ef028b67 100644 --- a/pkg/auth/handler/webapp/login.go +++ b/pkg/auth/handler/webapp/login.go @@ -99,7 +99,7 @@ func (h *LoginHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() h.FormPrefiller.Prefill(r.Form) diff --git a/pkg/auth/handler/webapp/login_link_otp.go b/pkg/auth/handler/webapp/login_link_otp.go index dc5ac8d8c5..d086a91821 100644 --- a/pkg/auth/handler/webapp/login_link_otp.go +++ b/pkg/auth/handler/webapp/login_link_otp.go @@ -115,7 +115,7 @@ func (h *LoginLinkOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/logout.go b/pkg/auth/handler/webapp/logout.go index bf44103b9a..7ab1228030 100644 --- a/pkg/auth/handler/webapp/logout.go +++ b/pkg/auth/handler/webapp/logout.go @@ -66,7 +66,7 @@ func (h *LogoutHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { baseViewModel := h.BaseViewModel.ViewModel(r, w) diff --git a/pkg/auth/handler/webapp/missing_web3_wallet.go b/pkg/auth/handler/webapp/missing_web3_wallet.go index 1f64c33bda..d6f21097b8 100644 --- a/pkg/auth/handler/webapp/missing_web3_wallet.go +++ b/pkg/auth/handler/webapp/missing_web3_wallet.go @@ -74,7 +74,7 @@ func (h *MissingWeb3WalletHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ http.Redirect(w, r, "/", http.StatusFound) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/not_found.go b/pkg/auth/handler/webapp/not_found.go index 3742e1207a..51d49ecb24 100644 --- a/pkg/auth/handler/webapp/not_found.go +++ b/pkg/auth/handler/webapp/not_found.go @@ -31,7 +31,7 @@ func (h *NotFoundHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/promote.go b/pkg/auth/handler/webapp/promote.go index be38c18348..1ffaaed84e 100644 --- a/pkg/auth/handler/webapp/promote.go +++ b/pkg/auth/handler/webapp/promote.go @@ -94,7 +94,7 @@ func (h *PromoteHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() h.FormPrefiller.Prefill(r.Form) diff --git a/pkg/auth/handler/webapp/prompt_create_passkey.go b/pkg/auth/handler/webapp/prompt_create_passkey.go index ba31dc1ac9..55f6ef2992 100644 --- a/pkg/auth/handler/webapp/prompt_create_passkey.go +++ b/pkg/auth/handler/webapp/prompt_create_passkey.go @@ -43,7 +43,7 @@ func (h *PromptCreatePasskeyHandler) ServeHTTP(w http.ResponseWriter, r *http.Re http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/reauth.go b/pkg/auth/handler/webapp/reauth.go index b9a4257020..ebba4e0dbe 100644 --- a/pkg/auth/handler/webapp/reauth.go +++ b/pkg/auth/handler/webapp/reauth.go @@ -25,7 +25,7 @@ func (h *ReauthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() webSession := webapp.GetSession(r.Context()) userIDHint := "" diff --git a/pkg/auth/handler/webapp/reset_password.go b/pkg/auth/handler/webapp/reset_password.go index 61e1eed3ec..b124c0b234 100644 --- a/pkg/auth/handler/webapp/reset_password.go +++ b/pkg/auth/handler/webapp/reset_password.go @@ -80,7 +80,7 @@ func (h *ResetPasswordHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() opts := webapp.SessionOptions{ KeepAfterFinish: true, diff --git a/pkg/auth/handler/webapp/reset_password_success.go b/pkg/auth/handler/webapp/reset_password_success.go index abc8f8dccb..45d952f5a0 100644 --- a/pkg/auth/handler/webapp/reset_password_success.go +++ b/pkg/auth/handler/webapp/reset_password_success.go @@ -38,7 +38,7 @@ func (h *ResetPasswordSuccessHandler) ServeHTTP(w http.ResponseWriter, r *http.R http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/return.go b/pkg/auth/handler/webapp/return.go index 8496310b4f..07411422cd 100644 --- a/pkg/auth/handler/webapp/return.go +++ b/pkg/auth/handler/webapp/return.go @@ -38,7 +38,7 @@ func (h *ReturnHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/select_account.go b/pkg/auth/handler/webapp/select_account.go index 901e4f81b3..04f8867772 100644 --- a/pkg/auth/handler/webapp/select_account.go +++ b/pkg/auth/handler/webapp/select_account.go @@ -224,9 +224,9 @@ func (h *SelectAccountHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) h.continueFlow(w, r, "/reauth") } - // ctrl.Serve() always write response. + // ctrl.ServeWithDBTx() always write response. // So we have to put http.Redirect before it. - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { // When promote anonymous user, the end-user should not see this page. diff --git a/pkg/auth/handler/webapp/settings.go b/pkg/auth/handler/webapp/settings.go index a4d4008a0e..66d3920a14 100644 --- a/pkg/auth/handler/webapp/settings.go +++ b/pkg/auth/handler/webapp/settings.go @@ -137,7 +137,7 @@ func (h *SettingsHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() redirectURI := httputil.HostRelative(r.URL).String() identityID := r.Form.Get("q_identity_id") diff --git a/pkg/auth/handler/webapp/settings_biometric.go b/pkg/auth/handler/webapp/settings_biometric.go index 4e84a27a50..18c1e6dd47 100644 --- a/pkg/auth/handler/webapp/settings_biometric.go +++ b/pkg/auth/handler/webapp/settings_biometric.go @@ -81,7 +81,7 @@ func (h *SettingsBiometricHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() userID := ctrl.RequireUserID() diff --git a/pkg/auth/handler/webapp/settings_change_password.go b/pkg/auth/handler/webapp/settings_change_password.go index 99773365c6..b231e1607a 100644 --- a/pkg/auth/handler/webapp/settings_change_password.go +++ b/pkg/auth/handler/webapp/settings_change_password.go @@ -60,7 +60,7 @@ func (h *SettingsChangePasswordHandler) ServeHTTP(w http.ResponseWriter, r *http http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/settings_change_secondary_password.go b/pkg/auth/handler/webapp/settings_change_secondary_password.go index cb0fc26ef1..5d75f5726f 100644 --- a/pkg/auth/handler/webapp/settings_change_secondary_password.go +++ b/pkg/auth/handler/webapp/settings_change_secondary_password.go @@ -58,7 +58,7 @@ func (h *SettingsChangeSecondaryPasswordHandler) ServeHTTP(w http.ResponseWriter http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/settings_delete_account.go b/pkg/auth/handler/webapp/settings_delete_account.go index 7de1f6035b..bbb541a28a 100644 --- a/pkg/auth/handler/webapp/settings_delete_account.go +++ b/pkg/auth/handler/webapp/settings_delete_account.go @@ -87,7 +87,7 @@ func (h *SettingsDeleteAccountHandler) ServeHTTP(w http.ResponseWriter, r *http. http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() currentSession := session.GetSession(r.Context()) redirectURI := "/settings/delete_account/success" diff --git a/pkg/auth/handler/webapp/settings_delete_account_success.go b/pkg/auth/handler/webapp/settings_delete_account_success.go index eb9da11072..e22da0995c 100644 --- a/pkg/auth/handler/webapp/settings_delete_account_success.go +++ b/pkg/auth/handler/webapp/settings_delete_account_success.go @@ -63,7 +63,7 @@ func (h *SettingsDeleteAccountSuccessHandler) ServeHTTP(w http.ResponseWriter, r http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() webSession := webapp.GetSession(r.Context()) @@ -78,7 +78,7 @@ func (h *SettingsDeleteAccountSuccessHandler) ServeHTTP(w http.ResponseWriter, r }) ctrl.PostAction("", func() error { - redirectURI := "" + redirectURI := "/login" if webSession != nil && webSession.RedirectURI != "" { // delete account triggered by sdk via settings action // redirect to oauth callback diff --git a/pkg/auth/handler/webapp/settings_identity.go b/pkg/auth/handler/webapp/settings_identity.go index 6874211e68..dcc65f26c9 100644 --- a/pkg/auth/handler/webapp/settings_identity.go +++ b/pkg/auth/handler/webapp/settings_identity.go @@ -78,7 +78,7 @@ func (h *SettingsIdentityHandler) ServeHTTP(w http.ResponseWriter, r *http.Reque http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() redirectURI := httputil.HostRelative(r.URL).String() providerAlias := r.Form.Get("x_provider_alias") diff --git a/pkg/auth/handler/webapp/settings_mfa.go b/pkg/auth/handler/webapp/settings_mfa.go index b6d582a931..bbbeeaa429 100644 --- a/pkg/auth/handler/webapp/settings_mfa.go +++ b/pkg/auth/handler/webapp/settings_mfa.go @@ -44,7 +44,7 @@ func (h *SettingsMFAHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() redirectURI := httputil.HostRelative(r.URL).String() authenticatorID := r.Form.Get("x_authenticator_id") diff --git a/pkg/auth/handler/webapp/settings_oob_otp.go b/pkg/auth/handler/webapp/settings_oob_otp.go index c7e5f7bbf7..11b928ab41 100644 --- a/pkg/auth/handler/webapp/settings_oob_otp.go +++ b/pkg/auth/handler/webapp/settings_oob_otp.go @@ -76,7 +76,7 @@ func (h *SettingsOOBOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request http.Error(w, "404 page not found", http.StatusNotFound) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() redirectURI := httputil.HostRelative(r.URL).String() authenticatorID := r.Form.Get("x_authenticator_id") diff --git a/pkg/auth/handler/webapp/settings_passkey.go b/pkg/auth/handler/webapp/settings_passkey.go index d070f0c4ec..8446dff10c 100644 --- a/pkg/auth/handler/webapp/settings_passkey.go +++ b/pkg/auth/handler/webapp/settings_passkey.go @@ -70,7 +70,7 @@ func (h *SettingsPasskeyHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() redirectURI := httputil.HostRelative(r.URL).String() userID := ctrl.RequireUserID() diff --git a/pkg/auth/handler/webapp/settings_profile.go b/pkg/auth/handler/webapp/settings_profile.go index 5999a14018..f5307c8942 100644 --- a/pkg/auth/handler/webapp/settings_profile.go +++ b/pkg/auth/handler/webapp/settings_profile.go @@ -33,7 +33,7 @@ func (h *SettingsProfileHandler) ServeHTTP(w http.ResponseWriter, r *http.Reques http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { userID := session.GetUserID(r.Context()) diff --git a/pkg/auth/handler/webapp/settings_profile_edit.go b/pkg/auth/handler/webapp/settings_profile_edit.go index 8e4c6cb593..316fb17097 100644 --- a/pkg/auth/handler/webapp/settings_profile_edit.go +++ b/pkg/auth/handler/webapp/settings_profile_edit.go @@ -75,7 +75,7 @@ func (h *SettingsProfileEditHandler) ServeHTTP(w http.ResponseWriter, r *http.Re http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/settings_recovery_code.go b/pkg/auth/handler/webapp/settings_recovery_code.go index cbe87fc807..5f98e582fe 100644 --- a/pkg/auth/handler/webapp/settings_recovery_code.go +++ b/pkg/auth/handler/webapp/settings_recovery_code.go @@ -67,7 +67,7 @@ func (h *SettingsRecoveryCodeHandler) ServeHTTP(w http.ResponseWriter, r *http.R http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() redirectURI := httputil.HostRelative(r.URL).String() userID := ctrl.RequireUserID() diff --git a/pkg/auth/handler/webapp/settings_sessions.go b/pkg/auth/handler/webapp/settings_sessions.go index 6350fc21a9..b764110d97 100644 --- a/pkg/auth/handler/webapp/settings_sessions.go +++ b/pkg/auth/handler/webapp/settings_sessions.go @@ -106,7 +106,7 @@ func (h *SettingsSessionsHandler) ServeHTTP(w http.ResponseWriter, r *http.Reque http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() currentSession := session.GetSession(r.Context()) redirectURI := httputil.HostRelative(r.URL).String() diff --git a/pkg/auth/handler/webapp/settings_totp.go b/pkg/auth/handler/webapp/settings_totp.go index 3f0a83d1bd..0c63cacac4 100644 --- a/pkg/auth/handler/webapp/settings_totp.go +++ b/pkg/auth/handler/webapp/settings_totp.go @@ -63,7 +63,7 @@ func (h *SettingsTOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() redirectURI := httputil.HostRelative(r.URL).String() authenticatorID := r.Form.Get("x_authenticator_id") diff --git a/pkg/auth/handler/webapp/setup_login_link_otp.go b/pkg/auth/handler/webapp/setup_login_link_otp.go index 93e8b6353d..3648088e20 100644 --- a/pkg/auth/handler/webapp/setup_login_link_otp.go +++ b/pkg/auth/handler/webapp/setup_login_link_otp.go @@ -62,7 +62,7 @@ func (h *SetupLoginLinkOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/setup_oob_otp.go b/pkg/auth/handler/webapp/setup_oob_otp.go index 842662c952..cddab916b1 100644 --- a/pkg/auth/handler/webapp/setup_oob_otp.go +++ b/pkg/auth/handler/webapp/setup_oob_otp.go @@ -121,7 +121,7 @@ func (h *SetupOOBOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, "404 page not found", http.StatusNotFound) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/setup_recovery_code.go b/pkg/auth/handler/webapp/setup_recovery_code.go index f4e796e231..5ec13707f6 100644 --- a/pkg/auth/handler/webapp/setup_recovery_code.go +++ b/pkg/auth/handler/webapp/setup_recovery_code.go @@ -72,7 +72,7 @@ func (h *SetupRecoveryCodeHandler) ServeHTTP(w http.ResponseWriter, r *http.Requ http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { graph, err := ctrl.InteractionGet() diff --git a/pkg/auth/handler/webapp/setup_totp.go b/pkg/auth/handler/webapp/setup_totp.go index ca12aaae52..bf866f102c 100644 --- a/pkg/auth/handler/webapp/setup_totp.go +++ b/pkg/auth/handler/webapp/setup_totp.go @@ -134,7 +134,7 @@ func (h *SetupTOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/setup_whatsapp_otp.go b/pkg/auth/handler/webapp/setup_whatsapp_otp.go index f04cc844e4..319b970284 100644 --- a/pkg/auth/handler/webapp/setup_whatsapp_otp.go +++ b/pkg/auth/handler/webapp/setup_whatsapp_otp.go @@ -58,7 +58,7 @@ func (h *SetupWhatsappOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Reque http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/signup.go b/pkg/auth/handler/webapp/signup.go index 41a1c34c1b..719215414f 100644 --- a/pkg/auth/handler/webapp/signup.go +++ b/pkg/auth/handler/webapp/signup.go @@ -86,7 +86,7 @@ func (h *SignupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() h.FormPrefiller.Prefill(r.Form) diff --git a/pkg/auth/handler/webapp/sso_callback.go b/pkg/auth/handler/webapp/sso_callback.go index d61468c70e..f75f635d3e 100644 --- a/pkg/auth/handler/webapp/sso_callback.go +++ b/pkg/auth/handler/webapp/sso_callback.go @@ -54,7 +54,7 @@ func (h *SSOCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() data := InputOAuthCallback{ ProviderAlias: httproute.GetParam(r, "alias"), diff --git a/pkg/auth/handler/webapp/tester.go b/pkg/auth/handler/webapp/tester.go index 009a1d41e5..4c0a69c20e 100644 --- a/pkg/auth/handler/webapp/tester.go +++ b/pkg/auth/handler/webapp/tester.go @@ -271,7 +271,7 @@ func (h *TesterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { token := r.URL.Query().Get("token") diff --git a/pkg/auth/handler/webapp/use_passkey.go b/pkg/auth/handler/webapp/use_passkey.go index ac213df1ab..2cc7c939d1 100644 --- a/pkg/auth/handler/webapp/use_passkey.go +++ b/pkg/auth/handler/webapp/use_passkey.go @@ -49,7 +49,7 @@ func (h *UsePasskeyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/verify_identity.go b/pkg/auth/handler/webapp/verify_identity.go index 343667c1d7..3c1ecd0c04 100644 --- a/pkg/auth/handler/webapp/verify_identity.go +++ b/pkg/auth/handler/webapp/verify_identity.go @@ -157,7 +157,7 @@ func (h *VerifyIdentityHandler) ServeHTTP(w http.ResponseWriter, r *http.Request http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() inputFn := func() (input interface{}, err error) { err = VerifyIdentitySchema.Validator().ValidateValue(FormToJSON(r.Form)) diff --git a/pkg/auth/handler/webapp/verify_identity_success.go b/pkg/auth/handler/webapp/verify_identity_success.go index 886850db26..27235d2b49 100644 --- a/pkg/auth/handler/webapp/verify_identity_success.go +++ b/pkg/auth/handler/webapp/verify_identity_success.go @@ -38,7 +38,7 @@ func (h *VerifyIdentitySuccessHandler) ServeHTTP(w http.ResponseWriter, r *http. http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { data, err := h.GetData(r, w) diff --git a/pkg/auth/handler/webapp/verify_login_link.go b/pkg/auth/handler/webapp/verify_login_link.go index 4dac937207..225639fa86 100644 --- a/pkg/auth/handler/webapp/verify_login_link.go +++ b/pkg/auth/handler/webapp/verify_login_link.go @@ -87,7 +87,7 @@ func (h *VerifyLoginLinkOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Req http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() finishWithState := func(state LoginLinkOTPPageQueryState) { url := url.URL{} diff --git a/pkg/auth/handler/webapp/viewmodels/settings.go b/pkg/auth/handler/webapp/viewmodels/settings.go index 048ae4ed2c..b9dcaea51b 100644 --- a/pkg/auth/handler/webapp/viewmodels/settings.go +++ b/pkg/auth/handler/webapp/viewmodels/settings.go @@ -9,6 +9,7 @@ import ( type SettingsViewModel struct { Authenticators []*authenticator.Info + NumberOfDeviceTokens int HasDeviceTokens bool ListRecoveryCodesAllowed bool ShowBiometric bool @@ -38,7 +39,7 @@ type SettingsAuthenticatorService interface { } type SettingsMFAService interface { - HasDeviceTokens(userID string) (bool, error) + CountDeviceTokens(userID string) (int, error) } type SettingsViewModeler struct { @@ -60,10 +61,11 @@ func (m *SettingsViewModeler) ViewModel(userID string) (*SettingsViewModel, erro authenticator.KeepPrimaryAuthenticatorCanHaveMFA, )) > 0 - hasDeviceTokens, err := m.MFA.HasDeviceTokens(userID) + numberOfDeviceTokens, err := m.MFA.CountDeviceTokens(userID) if err != nil { return nil, err } + hasDeviceTokens := numberOfDeviceTokens > 0 hasSecondaryTOTP := false hasSecondaryOOBOTPEmail := false @@ -148,6 +150,7 @@ func (m *SettingsViewModeler) ViewModel(userID string) (*SettingsViewModel, erro viewModel := &SettingsViewModel{ Authenticators: authenticators, + NumberOfDeviceTokens: numberOfDeviceTokens, HasDeviceTokens: hasDeviceTokens, ListRecoveryCodesAllowed: !*m.Authentication.RecoveryCode.Disabled && m.Authentication.RecoveryCode.ListEnabled, ShowBiometric: showBiometric, diff --git a/pkg/auth/handler/webapp/wechat_auth.go b/pkg/auth/handler/webapp/wechat_auth.go index c38d90fe1c..f4cb094563 100644 --- a/pkg/auth/handler/webapp/wechat_auth.go +++ b/pkg/auth/handler/webapp/wechat_auth.go @@ -96,7 +96,7 @@ func (h *WechatAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/handler/webapp/wechat_callback.go b/pkg/auth/handler/webapp/wechat_callback.go index 6ba1b6900d..7a2b2c5549 100644 --- a/pkg/auth/handler/webapp/wechat_callback.go +++ b/pkg/auth/handler/webapp/wechat_callback.go @@ -58,7 +58,7 @@ func (h *WechatCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() stateToken := r.Form.Get("state") code := r.Form.Get("code") diff --git a/pkg/auth/handler/webapp/whatsapp_otp.go b/pkg/auth/handler/webapp/whatsapp_otp.go index b7867766c9..17e50574c4 100644 --- a/pkg/auth/handler/webapp/whatsapp_otp.go +++ b/pkg/auth/handler/webapp/whatsapp_otp.go @@ -125,7 +125,7 @@ func (h *WhatsappOTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusBadRequest) return } - defer ctrl.Serve() + defer ctrl.ServeWithDBTx() ctrl.Get(func() error { session, err := ctrl.InteractionSession() diff --git a/pkg/auth/routes.go b/pkg/auth/routes.go index 517a195544..f33e4fad36 100644 --- a/pkg/auth/routes.go +++ b/pkg/auth/routes.go @@ -439,7 +439,10 @@ func NewRouter(p *deps.RootProvider, configSource *configsource.ConfigSource) *h router.Add(webapphandler.ConfigureForgotPasswordSuccessRoute(webappSuccessPageRoute), p.Handler(newWebAppForgotPasswordSuccessHandler)) router.Add(webapphandler.ConfigureResetPasswordSuccessRoute(webappSuccessPageRoute), p.Handler(newWebAppResetPasswordSuccessHandler)) - router.Add(webapphandler.ConfigureSettingsDeleteAccountSuccessRoute(webappSuccessPageRoute), p.Handler(newWebAppSettingsDeleteAccountSuccessHandler)) + router.Add(webapphandler.ConfigureSettingsDeleteAccountSuccessRoute(webappSuccessPageRoute), &webapphandler.SettingsImplementationSwitcherHandler{ + SettingV1: p.Handler(newWebAppSettingsDeleteAccountSuccessHandler), + SettingV2: p.Handler(newWebAppAuthflowV2SettingsDeleteAccountSuccessHandler), + }) router.Add(webapphandler.ConfigureLogoutRoute(webappAuthenticatedRoute), p.Handler(newWebAppLogoutHandler)) router.Add(webapphandler.ConfigureEnterLoginIDRoute(webappAuthenticatedRoute), p.Handler(newWebAppEnterLoginIDHandler)) @@ -456,17 +459,62 @@ func NewRouter(p *deps.RootProvider, configSource *configsource.ConfigSource) *h SettingV1: p.Handler(newWebAppSettingsProfileEditHandler), SettingV2: p.Handler(newWebAppAuthflowV2SettingsProfileEditHandler), }) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityChangePrimaryEmailRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityChangePrimaryEmailHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityAddEmailRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityAddEmailHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityEditEmailRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityEditEmailHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityListEmailRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityListEmailHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityVerifyEmailRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityVerifyEmailHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityViewEmailRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityViewEmailHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityAddPhoneRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityAddPhoneHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityChangePrimaryPhoneRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityChangePrimaryPhoneHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityEditPhoneRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityEditPhoneHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityListPhoneRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityListPhoneHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityViewPhoneRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityViewPhoneHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityVerifyPhoneRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityVerifyPhoneHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityListUsername(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityListUsernameHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityNewUsername(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityNewUsernameHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityViewUsername(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityViewUsernameHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsIdentityEditUsername(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsIdentityEditUsernameHandler)) router.Add(webapphandler.ConfigureSettingsIdentityRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsIdentityHandler)) - router.Add(webapphandler.ConfigureSettingsBiometricRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsBiometricHandler)) - router.Add(webapphandler.ConfigureSettingsMFARoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsMFAHandler)) - router.Add(webapphandler.ConfigureSettingsTOTPRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsTOTPHandler)) - router.Add(webapphandler.ConfigureSettingsPasskeyRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsPasskeyHandler)) - router.Add(webapphandler.ConfigureSettingsOOBOTPRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsOOBOTPHandler)) + router.Add(webapphandler.ConfigureSettingsBiometricRoute(webappSettingsSubRoutesRoute), &webapphandler.SettingsImplementationSwitcherHandler{ + SettingV1: p.Handler(newWebAppSettingsBiometricHandler), + SettingV2: p.Handler(newWebAppAuthflowV2SettingsBiometricHandler), + }) + router.Add(webapphandler.ConfigureSettingsMFARoute(webappSettingsSubRoutesRoute), &webapphandler.SettingsImplementationSwitcherHandler{ + SettingV1: p.Handler(newWebAppSettingsMFAHandler), + SettingV2: p.Handler(newWebAppAuthflowV2SettingsMFAHandler), + }) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsMFACreatePassword(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsMFACreatePasswordHandler)) + router.Add(webapphandlerauthflowv2.ConfigureAuthflowV2SettingsMFAPassword(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsMFAPasswordHandler)) + router.Add(webapphandler.ConfigureSettingsTOTPRoute(webappSettingsSubRoutesRoute), &webapphandler.SettingsImplementationSwitcherHandler{ + SettingV1: p.Handler(newWebAppSettingsTOTPHandler), + SettingV2: p.Handler(newWebAppAuthflowV2SettingsTOTPHandler), + }) + router.Add(webapphandler.ConfigureSettingsPasskeyRoute(webappSettingsSubRoutesRoute), &webapphandler.SettingsImplementationSwitcherHandler{ + SettingV1: p.Handler(newWebAppSettingsPasskeyHandler), + SettingV2: p.Handler(newWebAppAuthflowV2SettingsChangePasskeyHandler), + }) + router.Add(webapphandler.ConfigureSettingsOOBOTPRoute(webappSettingsSubRoutesRoute), &webapphandler.SettingsImplementationSwitcherHandler{ + SettingV1: p.Handler(newWebAppSettingsOOBOTPHandler), + SettingV2: p.Handler(newWebAppAuthflowV2SettingsOOBOTPHandler), + }) router.Add(webapphandler.ConfigureSettingsRecoveryCodeRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsRecoveryCodeHandler)) - router.Add(webapphandler.ConfigureSettingsSessionsRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsSessionsHandler)) - router.Add(webapphandler.ConfigureSettingsChangePasswordRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsChangePasswordHandler)) + router.Add(webapphandler.ConfigureSettingsSessionsRoute(webappSettingsSubRoutesRoute), &webapphandler.SettingsImplementationSwitcherHandler{ + SettingV1: p.Handler(newWebAppSettingsSessionsHandler), + SettingV2: p.Handler(newWebAppAuthflowV2SettingsSessionsHandler), + }) + router.Add(webapphandler.ConfigureSettingsChangePasswordRoute(webappSettingsSubRoutesRoute), &webapphandler.SettingsImplementationSwitcherHandler{ + SettingV1: p.Handler(newWebAppSettingsChangePasswordHandler), + SettingV2: p.Handler(newWebAppAuthflowV2SettingsChangePasswordHandler), + }) + router.Add(webapphandler.ConfigureSettingsChangeSecondaryPasswordRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsChangeSecondaryPasswordHandler)) - router.Add(webapphandler.ConfigureSettingsDeleteAccountRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppSettingsDeleteAccountHandler)) + router.Add(webapphandler.ConfigureSettingsDeleteAccountRoute(webappSettingsSubRoutesRoute), &webapphandler.SettingsImplementationSwitcherHandler{ + SettingV1: p.Handler(newWebAppSettingsDeleteAccountHandler), + SettingV2: p.Handler(newWebAppAuthflowV2SettingsDeleteAccountHandler), + }) + + router.Add(webapphandlerauthflowv2.ConfigureSettingsV2AdvancedSettingsRoute(webappSettingsSubRoutesRoute), p.Handler(newWebAppAuthflowV2SettingsAdvancedSettingsHandler)) router.Add(webapphandler.ConfigureTesterRoute(webappTesterRouter), p.Handler(newWebAppTesterHandler)) diff --git a/pkg/auth/wire_gen.go b/pkg/auth/wire_gen.go index 7c3d6f1520..c2bbebdc9f 100644 --- a/pkg/auth/wire_gen.go +++ b/pkg/auth/wire_gen.go @@ -44395,6 +44395,7 @@ func newWebAppAuthflowV2SettingsHandler(p *deps.RequestProvider) http.Handler { SettingsProfileViewModel: settingsProfileViewModeler, Identities: serviceService, Renderer: responseRenderer, + AccountDeletion: accountDeletionConfig, } return authflowV2SettingsHandler } @@ -49141,10 +49142,10 @@ func newWebAppSettingsBiometricHandler(p *deps.RequestProvider) http.Handler { return settingsBiometricHandler } -func newWebAppSettingsMFAHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsBiometricHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider - factory := appProvider.LoggerFactory handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config @@ -50068,24 +50069,44 @@ func newWebAppSettingsMFAHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - biometricConfig := identityConfig.Biometric - settingsViewModeler := &viewmodels.SettingsViewModeler{ - Authenticators: service3, - MFA: mfaService, - Authentication: authenticationConfig, - Biometric: biometricConfig, + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, } - settingsMFAHandler := &webapp.SettingsMFAHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - SettingsViewModel: settingsViewModeler, - Renderer: responseRenderer, - MFA: mfaService, + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, } - return settingsMFAHandler + accountmanagementService := &accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsBiometricHandler := &authflowv2.AuthflowV2SettingsBiometricHandler{ + Database: handle, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Identities: serviceService, + BiometricProvider: biometricProvider, + AccountManagementService: accountmanagementService, + } + return authflowV2SettingsBiometricHandler } -func newWebAppSettingsTOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppSettingsMFAHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -51012,19 +51033,27 @@ func newWebAppSettingsTOTPHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - settingsTOTPHandler := &webapp.SettingsTOTPHandler{ + biometricConfig := identityConfig.Biometric + settingsViewModeler := &viewmodels.SettingsViewModeler{ + Authenticators: service3, + MFA: mfaService, + Authentication: authenticationConfig, + Biometric: biometricConfig, + } + settingsMFAHandler := &webapp.SettingsMFAHandler{ ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, + SettingsViewModel: settingsViewModeler, Renderer: responseRenderer, - Authenticators: service3, + MFA: mfaService, } - return settingsTOTPHandler + return settingsMFAHandler } -func newWebAppSettingsPasskeyHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsMFAHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider - factory := appProvider.LoggerFactory handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config @@ -51948,16 +51977,25 @@ func newWebAppSettingsPasskeyHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - settingsPasskeyHandler := &webapp.SettingsPasskeyHandler{ + biometricConfig := identityConfig.Biometric + settingsViewModeler := &viewmodels.SettingsViewModeler{ + Authenticators: service3, + MFA: mfaService, + Authentication: authenticationConfig, + Biometric: biometricConfig, + } + authflowV2SettingsMFAHandler := &authflowv2.AuthflowV2SettingsMFAHandler{ + Database: handle, ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, + SettingsViewModel: settingsViewModeler, Renderer: responseRenderer, - Identities: serviceService, + MFA: mfaService, } - return settingsPasskeyHandler + return authflowV2SettingsMFAHandler } -func newWebAppSettingsOOBOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsMFACreatePasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -52884,19 +52922,53 @@ func newWebAppSettingsOOBOTPHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - settingsOOBOTPHandler := &webapp.SettingsOOBOTPHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - Authenticators: service3, + biometricConfig := identityConfig.Biometric + settingsViewModeler := &viewmodels.SettingsViewModeler{ + Authenticators: service3, + MFA: mfaService, + Authentication: authenticationConfig, + Biometric: biometricConfig, } - return settingsOOBOTPHandler + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := &accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsMFACreatePasswordHandler := &authflowv2.AuthflowV2SettingsMFACreatePasswordHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + SettingsViewModel: settingsViewModeler, + PasswordPolicy: passwordChecker, + Renderer: responseRenderer, + AccountManagementService: accountmanagementService, + } + return authflowV2SettingsMFACreatePasswordHandler } -func newWebAppSettingsRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsMFAPasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider - factory := appProvider.LoggerFactory handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config @@ -53820,17 +53892,24 @@ func newWebAppSettingsRecoveryCodeHandler(p *deps.RequestProvider) http.Handler LoggerFactory: factory, ControllerDeps: controllerDeps, } - settingsRecoveryCodeHandler := &webapp.SettingsRecoveryCodeHandler{ + biometricConfig := identityConfig.Biometric + settingsViewModeler := &viewmodels.SettingsViewModeler{ + Authenticators: service3, + MFA: mfaService, + Authentication: authenticationConfig, + Biometric: biometricConfig, + } + authflowV2SettingsMFAPasswordHandler := &authflowv2.AuthflowV2SettingsMFAPasswordHandler{ + Database: handle, ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, + SettingsViewModel: settingsViewModeler, Renderer: responseRenderer, - Authentication: authenticationConfig, - MFA: mfaService, } - return settingsRecoveryCodeHandler + return authflowV2SettingsMFAPasswordHandler } -func newWebAppSettingsSessionsHandler(p *deps.RequestProvider) http.Handler { +func newWebAppSettingsTOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -54757,42 +54836,19 @@ func newWebAppSettingsSessionsHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: resolver, - OfflineGrants: store, - } - authorizationService := &oauth2.AuthorizationService{ - AppID: appID, - Store: authorizationStore, - Clock: clockClock, - OAuthSessionManager: sessionManager, - OfflineGrantService: oauthOfflineGrantService, - OfflineGrantStore: store, - } - sessionListingService := &sessionlisting.SessionListingService{ - OAuthConfig: oAuthConfig, - IDPSessions: idpsessionProvider, - OfflineGrants: oauthOfflineGrantService, - } - settingsSessionsHandler := &webapp.SettingsSessionsHandler{ + settingsTOTPHandler := &webapp.SettingsTOTPHandler{ ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, Renderer: responseRenderer, - Sessions: manager2, - Authorizations: authorizationService, - OAuthConfig: oAuthConfig, - SessionListing: sessionListingService, + Authenticators: service3, } - return settingsSessionsHandler + return settingsTOTPHandler } -func newWebAppForceChangePasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsTOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider - factory := appProvider.LoggerFactory handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config @@ -55716,24 +55772,31 @@ func newWebAppForceChangePasswordHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - changePasswordViewModeler := &viewmodels.ChangePasswordViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, + service4 := service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, } - forceChangePasswordHandler := &webapp.ForceChangePasswordHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - ChangePasswordViewModel: changePasswordViewModeler, - Renderer: responseRenderer, - PasswordPolicy: passwordChecker, + authflowV2SettingsTOTPHandler := &authflowv2.AuthflowV2SettingsTOTPHandler{ + Database: handle, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Authenticators: service4, } - return forceChangePasswordHandler + return authflowV2SettingsTOTPHandler } -func newWebAppSettingsChangePasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsOOBOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider - factory := appProvider.LoggerFactory handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config @@ -56657,16 +56720,28 @@ func newWebAppSettingsChangePasswordHandler(p *deps.RequestProvider) http.Handle LoggerFactory: factory, ControllerDeps: controllerDeps, } - settingsChangePasswordHandler := &webapp.SettingsChangePasswordHandler{ + service4 := service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + authflowV2SettingsOOBOTPHandler := &authflowv2.AuthflowV2SettingsOOBOTPHandler{ + Database: handle, ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, Renderer: responseRenderer, - PasswordPolicy: passwordChecker, + Authenticators: service4, } - return settingsChangePasswordHandler + return authflowV2SettingsOOBOTPHandler } -func newWebAppForceChangeSecondaryPasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppSettingsPasskeyHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -57593,24 +57668,19 @@ func newWebAppForceChangeSecondaryPasswordHandler(p *deps.RequestProvider) http. LoggerFactory: factory, ControllerDeps: controllerDeps, } - changePasswordViewModeler := viewmodels.ChangePasswordViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - } - forceChangeSecondaryPasswordHandler := &webapp.ForceChangeSecondaryPasswordHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - ChangePasswordViewModel: changePasswordViewModeler, - Renderer: responseRenderer, - PasswordPolicy: passwordChecker, + settingsPasskeyHandler := &webapp.SettingsPasskeyHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Identities: serviceService, } - return forceChangeSecondaryPasswordHandler + return settingsPasskeyHandler } -func newWebAppSettingsChangeSecondaryPasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsChangePasskeyHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider - factory := appProvider.LoggerFactory handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config @@ -58534,16 +58604,63 @@ func newWebAppSettingsChangeSecondaryPasswordHandler(p *deps.RequestProvider) ht LoggerFactory: factory, ControllerDeps: controllerDeps, } - settingsChangeSecondaryPasswordHandler := &webapp.SettingsChangeSecondaryPasswordHandler{ + service4 := service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := &accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + authflowV2SettingsChangePasskeyHandler := &authflowv2.AuthflowV2SettingsChangePasskeyHandler{ + Database: handle, ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, Renderer: responseRenderer, - PasswordPolicy: passwordChecker, + Identities: service4, + AccountManagement: accountmanagementService, + Passkey: creationOptionsService, } - return settingsChangeSecondaryPasswordHandler + return authflowV2SettingsChangePasskeyHandler } -func newWebAppSettingsDeleteAccountHandler(p *deps.RequestProvider) http.Handler { +func newWebAppSettingsOOBOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -59470,27 +59587,16 @@ func newWebAppSettingsDeleteAccountHandler(p *deps.RequestProvider) http.Handler LoggerFactory: factory, ControllerDeps: controllerDeps, } - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - settingsDeleteAccountHandler := &webapp.SettingsDeleteAccountHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - AccountDeletion: accountDeletionConfig, - Clock: clockClock, - Users: userFacade, - Cookies: cookieManager, - OAuthSessions: oauthsessionStoreRedis, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - AuthenticationInfoService: authenticationinfoStoreRedis, + settingsOOBOTPHandler := &webapp.SettingsOOBOTPHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Authenticators: service3, } - return settingsDeleteAccountHandler + return settingsOOBOTPHandler } -func newWebAppSettingsDeleteAccountSuccessHandler(p *deps.RequestProvider) http.Handler { +func newWebAppSettingsRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -60417,19 +60523,17 @@ func newWebAppSettingsDeleteAccountSuccessHandler(p *deps.RequestProvider) http. LoggerFactory: factory, ControllerDeps: controllerDeps, } - settingsDeleteAccountSuccessHandler := &webapp.SettingsDeleteAccountSuccessHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - AccountDeletion: accountDeletionConfig, - Clock: clockClock, - UIInfoResolver: uiService, - AuthenticationInfoService: authenticationinfoStoreRedis, + settingsRecoveryCodeHandler := &webapp.SettingsRecoveryCodeHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Authentication: authenticationConfig, + MFA: mfaService, } - return settingsDeleteAccountSuccessHandler + return settingsRecoveryCodeHandler } -func newWebAppAccountStatusHandler(p *deps.RequestProvider) http.Handler { +func newWebAppSettingsSessionsHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -61356,15 +61460,39 @@ func newWebAppAccountStatusHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - accountStatusHandler := &webapp.AccountStatusHandler{ + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + authorizationService := &oauth2.AuthorizationService{ + AppID: appID, + Store: authorizationStore, + Clock: clockClock, + OAuthSessionManager: sessionManager, + OfflineGrantService: oauthOfflineGrantService, + OfflineGrantStore: store, + } + sessionListingService := &sessionlisting.SessionListingService{ + OAuthConfig: oAuthConfig, + IDPSessions: idpsessionProvider, + OfflineGrants: oauthOfflineGrantService, + } + settingsSessionsHandler := &webapp.SettingsSessionsHandler{ ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, Renderer: responseRenderer, + Sessions: manager2, + Authorizations: authorizationService, + OAuthConfig: oAuthConfig, + SessionListing: sessionListingService, } - return accountStatusHandler + return settingsSessionsHandler } -func newWebAppLogoutHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsSessionsHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -62291,23 +62419,6 @@ func newWebAppLogoutHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - samlConfig := appConfig.SAML - samlslosessionStoreRedis := &samlslosession.StoreRedis{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - } - samlEnvironmentConfig := environmentConfig.SAML - samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) - samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } oauthOfflineGrantService := &oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, @@ -62315,55 +62426,32 @@ func newWebAppLogoutHandler(p *deps.RequestProvider) http.Handler { ClientResolver: resolver, OfflineGrants: store, } - samlService := &saml.Service{ - Clock: clockClock, - AppID: appID, - SAMLEnvironmentConfig: samlEnvironmentConfig, - SAMLConfig: samlConfig, - SAMLIdpSigningMaterials: samlIdpSigningMaterials, - SAMLSpSigningMaterials: samlSpSigningMaterials, - Endpoints: endpointsEndpoints, - UserInfoProvider: idTokenIssuer, - IDPSessionProvider: idpsessionProvider, - OfflineGrantSessionProvider: oauthOfflineGrantService, - } - samlBindingHTTPPostWriter := &samlbinding.SAMLBindingHTTPPostWriter{} - samlBindingHTTPRedirectWriter := &samlbinding.SAMLBindingHTTPRedirectWriter{ - Signer: samlService, - } - sloService := &saml.SLOService{ - SAMLService: samlService, - BindingHTTPPostWriter: samlBindingHTTPPostWriter, - BindingHTTPRedirectWriter: samlBindingHTTPRedirectWriter, + authorizationService := &oauth2.AuthorizationService{ + AppID: appID, + Store: authorizationStore, + Clock: clockClock, + OAuthSessionManager: sessionManager, + OfflineGrantService: oauthOfflineGrantService, + OfflineGrantStore: store, } - logoutHandler := &webapp.LogoutHandler{ - ControllerFactory: controllerFactory, - Database: handle, - TrustProxy: trustProxy, - OAuth: oAuthConfig, - UIConfig: uiConfig, - SAMLConfig: samlConfig, - SessionManager: manager2, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - OAuthClientResolver: resolver, - SAMLSLOSessionService: samlslosessionStoreRedis, - SAMLSLOService: sloService, + sessionListingService := &sessionlisting.SessionListingService{ + OAuthConfig: oAuthConfig, + IDPSessions: idpsessionProvider, + OfflineGrants: oauthOfflineGrantService, } - return logoutHandler -} - -func newWebAppAppStaticAssetsHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - appContext := appProvider.AppContext - manager := appContext.Resources - appStaticAssetsHandler := &webapp.AppStaticAssetsHandler{ - Resources: manager, + authflowV2SettingsSessionsHandler := &authflowv2.AuthflowV2SettingsSessionsHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Sessions: manager2, + Authorizations: authorizationService, + OAuthConfig: oAuthConfig, + SessionListing: sessionListingService, } - return appStaticAssetsHandler + return authflowV2SettingsSessionsHandler } -func newWebAppReturnHandler(p *deps.RequestProvider) http.Handler { +func newWebAppForceChangePasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -63290,15 +63378,21 @@ func newWebAppReturnHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - returnHandler := &webapp.ReturnHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + changePasswordViewModeler := &viewmodels.ChangePasswordViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, } - return returnHandler + forceChangePasswordHandler := &webapp.ForceChangePasswordHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + ChangePasswordViewModel: changePasswordViewModeler, + Renderer: responseRenderer, + PasswordPolicy: passwordChecker, + } + return forceChangePasswordHandler } -func newWebAppErrorHandler(p *deps.RequestProvider) http.Handler { +func newWebAppSettingsChangePasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -64225,28 +64319,50 @@ func newWebAppErrorHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - errorHandler := &webapp.ErrorHandler{ + settingsChangePasswordHandler := &webapp.SettingsChangePasswordHandler{ ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, Renderer: responseRenderer, + PasswordPolicy: passwordChecker, } - return errorHandler + return settingsChangePasswordHandler } -func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsChangePasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI httpHost := deps.ProvideHTTPHost(request, trustProxy) httpProto := deps.ProvideHTTPProto(request, trustProxy) - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - uiConfig := appConfig.UI globalUIImplementation := environmentConfig.UIImplementation globalUISettingsImplementation := environmentConfig.UISettingsImplementation uiImplementationService := &web.UIImplementationService{ @@ -64259,45 +64375,46 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { HTTPProto: httpProto, UIImplementationService: uiImplementationService, } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue featureConfig := config.FeatureConfig - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + redisLogger := redis.NewLogger(factory) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) - store := &user.Store{ + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, - AppID: appID, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -64361,19 +64478,20 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { } store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -64411,14 +64529,14 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -64533,17 +64651,17 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -64569,7 +64687,7 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -64613,14 +64731,14 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -64637,7 +64755,7 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -64710,16 +64828,16 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -64728,26 +64846,11 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, - } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, + Database: handle, } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -64775,7 +64878,7 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -64790,21 +64893,21 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -64826,12 +64929,27 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -64840,32 +64958,21 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -64877,7 +64984,7 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -64885,19 +64992,15 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -64936,23 +65039,15 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -64960,8 +65055,28 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -64980,257 +65095,104 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, + Redis: appredisHandle, AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, Config: appConfig, FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, + OAuthClientResolver: resolver, + OfflineGrants: store, Identities: identityFacade, + Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, OTPSender: messageSender, - Verification: workflowVerificationFacade, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, ForgotPassword: forgotpasswordService, ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, + Users: userProvider, + StdAttrsService: stdattrsService, Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, - AppID: appID, - Context: contextContext, - } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, - } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, - } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, - ErrorRenderer: errorRenderer, + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } uiFeatureConfig := featureConfig.UI forgotPasswordConfig := appConfig.ForgotPassword googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection flashMessage := &httputil.FlashMessage{ Cookies: cookieManager, } @@ -65255,34 +65217,114 @@ func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { SupportedLanguageTags: supportedLanguageTags, AuthUISentryDSN: authUISentryDSN, AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, + OAuthClientResolver: resolver, Logger: baseLogger, } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2ErrorHandler := &authflowv2.AuthflowV2ErrorHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - return authflowV2ErrorHandler + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := &accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsChangePasswordHandler := &authflowv2.AuthflowV2SettingsChangePasswordHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + AccountManagementService: accountmanagementService, + PasswordPolicy: passwordChecker, + } + return authflowV2SettingsChangePasswordHandler } -func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler { +func newWebAppForceChangeSecondaryPasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI httpHost := deps.ProvideHTTPHost(request, trustProxy) httpProto := deps.ProvideHTTPProto(request, trustProxy) - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - uiConfig := appConfig.UI globalUIImplementation := environmentConfig.UIImplementation globalUISettingsImplementation := environmentConfig.UISettingsImplementation uiImplementationService := &web.UIImplementationService{ @@ -65295,45 +65337,46 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler HTTPProto: httpProto, UIImplementationService: uiImplementationService, } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - contextContext := deps.ProvideRequestContext(request) - featureConfig := config.FeatureConfig - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) - secretConfig := config.SecretConfig + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) - store := &user.Store{ + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, - AppID: appID, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -65397,19 +65440,20 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler } store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -65447,14 +65491,14 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -65569,17 +65613,17 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -65605,7 +65649,7 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -65649,14 +65693,14 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -65673,7 +65717,7 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -65746,16 +65790,16 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -65764,26 +65808,11 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, - } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, + Database: handle, } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -65811,7 +65840,7 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -65826,21 +65855,21 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -65862,12 +65891,27 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -65876,32 +65920,21 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -65913,7 +65946,7 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -65921,19 +65954,15 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler Clock: clockClock, Random: idpsessionRand, } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -65972,23 +66001,15 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -65996,8 +66017,28 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -66016,257 +66057,104 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, + Redis: appredisHandle, AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, Config: appConfig, FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, + OAuthClientResolver: resolver, + OfflineGrants: store, Identities: identityFacade, + Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, OTPSender: messageSender, - Verification: workflowVerificationFacade, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, ForgotPassword: forgotpasswordService, ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, + Users: userProvider, + StdAttrsService: stdattrsService, Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, - AppID: appID, - Context: contextContext, - } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, - } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, - } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, - ErrorRenderer: errorRenderer, + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } uiFeatureConfig := featureConfig.UI forgotPasswordConfig := appConfig.ForgotPassword googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection flashMessage := &httputil.FlashMessage{ Cookies: cookieManager, } @@ -66291,48 +66179,86 @@ func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler SupportedLanguageTags: supportedLanguageTags, AuthUISentryDSN: authUISentryDSN, AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, + OAuthClientResolver: resolver, Logger: baseLogger, } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - csrfErrorInstructionHandler := &webapp.CSRFErrorInstructionHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - return csrfErrorInstructionHandler -} - -func newWebAppNotFoundHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - factory := appProvider.LoggerFactory - handle := appProvider.AppDatabase - appredisHandle := appProvider.Redis - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - appID := appConfig.ID - serviceLogger := webapp2.NewServiceLogger(factory) - request := p.Request - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: appredisHandle, + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - authenticationConfig := appConfig.Authentication - cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + changePasswordViewModeler := viewmodels.ChangePasswordViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + } + forceChangeSecondaryPasswordHandler := &webapp.ForceChangeSecondaryPasswordHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + ChangePasswordViewModel: changePasswordViewModeler, + Renderer: responseRenderer, + PasswordPolicy: passwordChecker, + } + return forceChangeSecondaryPasswordHandler +} + +func newWebAppSettingsChangeSecondaryPasswordHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, RedisHandle: appredisHandle, Cookies: cookieManager, } @@ -67232,15 +67158,16 @@ func newWebAppNotFoundHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - notFoundHandler := &webapp.NotFoundHandler{ + settingsChangeSecondaryPasswordHandler := &webapp.SettingsChangeSecondaryPasswordHandler{ ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, Renderer: responseRenderer, + PasswordPolicy: passwordChecker, } - return notFoundHandler + return settingsChangeSecondaryPasswordHandler } -func newWebAppAuthflowV2NotFoundHandler(p *deps.RequestProvider) http.Handler { +func newWebAppSettingsDeleteAccountHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -68167,45 +68094,40 @@ func newWebAppAuthflowV2NotFoundHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - authflowV2NotFoundHandler := &authflowv2.AuthflowV2NotFoundHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, } - return authflowV2NotFoundHandler -} - -func newWebAppWebsocketHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - appID := appConfig.ID - factory := appProvider.LoggerFactory - handle := appProvider.Redis - publisher := webapp.NewPublisher(appID, handle) - websocketHandler := &webapp.WebsocketHandler{ - AppID: appID, - LoggerFactory: factory, - RedisHandle: handle, - Publisher: publisher, + settingsDeleteAccountHandler := &webapp.SettingsDeleteAccountHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + AccountDeletion: accountDeletionConfig, + Clock: clockClock, + Users: userFacade, + Cookies: cookieManager, + OAuthSessions: oauthsessionStoreRedis, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + AuthenticationInfoService: authenticationinfoStoreRedis, } - return websocketHandler + return settingsDeleteAccountHandler } -func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsDeleteAccountHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - serviceLogger := webapp2.NewServiceLogger(factory) - request := p.Request + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig appID := appConfig.ID - handle := appProvider.Redis + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request sessionStoreRedis := &webapp2.SessionStoreRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } sessionCookieDef := webapp2.NewSessionCookieDef() signedUpCookieDef := webapp2.NewSignedUpCookieDef() @@ -68220,7 +68142,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle errorService := &webapp2.ErrorService{ AppID: appID, Cookie: errorTokenCookieDef, - RedisHandle: handle, + RedisHandle: appredisHandle, Cookies: cookieManager, } oAuthConfig := appConfig.OAuth @@ -68249,8 +68171,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle logger := interaction.NewLogger(factory) remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) clockClock := _wireSystemClockValue featureConfig := config.FeatureConfig redisLogger := redis.NewLogger(factory) @@ -68259,7 +68180,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) store := &redis.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -68343,7 +68264,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle } store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -68394,14 +68315,14 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -68516,17 +68437,17 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -68552,7 +68473,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -68693,11 +68614,11 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -68711,11 +68632,11 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, + Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -68743,7 +68664,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -68765,7 +68686,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -68823,7 +68744,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, @@ -68837,7 +68758,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle CookieDef: cookieDef2, } eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -68849,7 +68770,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -68909,7 +68830,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -68925,7 +68846,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ Context: contextContext, AppID: appID, - Redis: handle, + Redis: appredisHandle, } oAuthProviderFactory := &sso.OAuthProviderFactory{ IdentityConfig: identityConfig, @@ -68937,7 +68858,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle } webappoauthStore := &webappoauth.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } mfaFacade := &facade.MFAFacade{ @@ -68967,7 +68888,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -68977,7 +68898,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } manager2 := &session.Manager{ @@ -68987,7 +68908,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle } oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } interactionContext := &interaction.Context{ @@ -69030,7 +68951,7 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle MFADeviceTokenCookie: cookieDef, } interactionStoreRedis := &interaction.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } interactionService := &interaction.Service{ @@ -69054,38 +68975,105 @@ func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handle OAuthClientResolver: resolver, Graph: interactionService, } - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, } - passkeyCreationOptionsHandler := &webapp.PasskeyCreationOptionsHandler{ - Page: webappService2, - Database: appdbHandle, - JSON: jsonResponseWriter, - Passkey: creationOptionsService, + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, } - return passkeyCreationOptionsHandler + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + authflowV2SettingsDeleteAccountHandler := &authflowv2.AuthflowV2SettingsDeleteAccountHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Clock: clockClock, + Cookies: cookieManager, + Users: userFacade, + Sessions: sessionStoreRedis, + OAuthSessions: oauthsessionStoreRedis, + AccountDeletion: accountDeletionConfig, + AuthenticationInfoService: authenticationinfoStoreRedis, + } + return authflowV2SettingsDeleteAccountHandler } -func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler { +func newWebAppSettingsDeleteAccountSuccessHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - serviceLogger := webapp2.NewServiceLogger(factory) - request := p.Request + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig appID := appConfig.ID - handle := appProvider.Redis + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request sessionStoreRedis := &webapp2.SessionStoreRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } sessionCookieDef := webapp2.NewSessionCookieDef() signedUpCookieDef := webapp2.NewSignedUpCookieDef() @@ -69100,7 +69088,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler errorService := &webapp2.ErrorService{ AppID: appID, Cookie: errorTokenCookieDef, - RedisHandle: handle, + RedisHandle: appredisHandle, Cookies: cookieManager, } oAuthConfig := appConfig.OAuth @@ -69129,8 +69117,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler logger := interaction.NewLogger(factory) remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) clockClock := _wireSystemClockValue featureConfig := config.FeatureConfig redisLogger := redis.NewLogger(factory) @@ -69139,7 +69126,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) store := &redis.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -69223,7 +69210,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler } store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -69274,14 +69261,14 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -69396,17 +69383,17 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -69432,7 +69419,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -69573,11 +69560,11 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -69591,11 +69578,11 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, + Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -69623,7 +69610,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -69645,7 +69632,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -69703,7 +69690,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, @@ -69717,7 +69704,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler CookieDef: cookieDef2, } eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -69729,7 +69716,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -69789,7 +69776,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -69805,7 +69792,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ Context: contextContext, AppID: appID, - Redis: handle, + Redis: appredisHandle, } oAuthProviderFactory := &sso.OAuthProviderFactory{ IdentityConfig: identityConfig, @@ -69817,7 +69804,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler } webappoauthStore := &webappoauth.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } mfaFacade := &facade.MFAFacade{ @@ -69847,7 +69834,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -69857,7 +69844,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } manager2 := &session.Manager{ @@ -69867,7 +69854,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler } oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } interactionContext := &interaction.Context{ @@ -69910,7 +69897,7 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler MFADeviceTokenCookie: cookieDef, } interactionStoreRedis := &interaction.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } interactionService := &interaction.Service{ @@ -69934,25 +69921,85 @@ func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler OAuthClientResolver: resolver, Graph: interactionService, } - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, } - passkeyRequestOptionsHandler := &webapp.PasskeyRequestOptionsHandler{ - Page: webappService2, - Database: appdbHandle, - JSON: jsonResponseWriter, - Passkey: requestOptionsService, + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, } - return passkeyRequestOptionsHandler + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + settingsDeleteAccountSuccessHandler := &webapp.SettingsDeleteAccountSuccessHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + AccountDeletion: accountDeletionConfig, + Clock: clockClock, + UIInfoResolver: uiService, + AuthenticationInfoService: authenticationinfoStoreRedis, + } + return settingsDeleteAccountSuccessHandler } -func newWebAppConnectWeb3AccountHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsDeleteAccountSuccessHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -70879,25 +70926,19 @@ func newWebAppConnectWeb3AccountHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - authenticationViewModeler := &viewmodels.AuthenticationViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - } - alternativeStepsViewModeler := &viewmodels.AlternativeStepsViewModeler{ - AuthenticationConfig: authenticationConfig, - } - connectWeb3AccountHandler := &webapp.ConnectWeb3AccountHandler{ + authflowV2SettingsDeleteAccountSuccessHandler := &authflowv2.AuthflowV2SettingsDeleteAccountSuccessHandler{ ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, - AuthenticationViewModel: authenticationViewModeler, - AlternativeStepsViewModel: alternativeStepsViewModeler, Renderer: responseRenderer, - AuthenticationConfig: authenticationConfig, + AccountDeletion: accountDeletionConfig, + Clock: clockClock, + UIInfoResolver: uiService, + AuthenticationInfoService: authenticationinfoStoreRedis, } - return connectWeb3AccountHandler + return authflowV2SettingsDeleteAccountSuccessHandler } -func newWebAppMissingWeb3WalletHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsAdvancedSettingsHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -71824,16 +71865,15 @@ func newWebAppMissingWeb3WalletHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - missingWeb3WalletHandler := &webapp.MissingWeb3WalletHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - AuthenticationConfig: authenticationConfig, + authflowV2SettingsAdvancedSettingsHandler := &authflowv2.AuthflowV2SettingsAdvancedSettingsHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, } - return missingWeb3WalletHandler + return authflowV2SettingsAdvancedSettingsHandler } -func newWebAppFeatureDisabledHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAccountStatusHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory handle := appProvider.AppDatabase @@ -72760,23 +72800,23 @@ func newWebAppFeatureDisabledHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - featureDisabledHandler := &webapp.FeatureDisabledHandler{ + accountStatusHandler := &webapp.AccountStatusHandler{ ControllerFactory: controllerFactory, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return featureDisabledHandler + return accountStatusHandler } -func newWebAppTesterHandler(p *deps.RequestProvider) http.Handler { +func newWebAppLogoutHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider + factory := appProvider.LoggerFactory + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig appID := appConfig.ID - factory := appProvider.LoggerFactory - handle := appProvider.AppDatabase - appredisHandle := appProvider.Redis serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request sessionStoreRedis := &webapp2.SessionStoreRedis{ @@ -73695,30 +73735,15 @@ func newWebAppTesterHandler(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - globalredisHandle := appProvider.GlobalRedis - testerStore := &tester.TesterStore{ + samlConfig := appConfig.SAML + samlslosessionStoreRedis := &samlslosession.StoreRedis{ Context: contextContext, - Redis: globalredisHandle, - } - appDomains := appContext.Domains - oAuthFeatureConfig := featureConfig.OAuth - oAuthClientCredentials := deps.ProvideOAuthClientCredentials(secretConfig) - tokenHandlerLogger := handler.NewTokenHandlerLogger(factory) - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: resolver, - OfflineGrants: store, - } - authorizationService := &oauth2.AuthorizationService{ - AppID: appID, - Store: authorizationStore, - Clock: clockClock, - OAuthSessionManager: sessionManager, - OfflineGrantService: oauthOfflineGrantService, - OfflineGrantStore: store, + Redis: appredisHandle, + AppID: appID, } + samlEnvironmentConfig := environmentConfig.SAML + samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) + samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) idTokenIssuer := &oidc.IDTokenIssuer{ Secrets: oAuthKeyMaterials, @@ -73727,190 +73752,148 @@ func newWebAppTesterHandler(p *deps.RequestProvider) http.Handler { RolesAndGroups: queries, Clock: clockClock, } - facadeIdentityFacade := &facade.IdentityFacade{ - Coordinator: coordinator, - } - accessTokenEncoding := oauth2.AccessTokenEncoding{ - Secrets: oAuthKeyMaterials, - Clock: clockClock, - IDTokenIssuer: idTokenIssuer, - BaseURL: endpointsEndpoints, - Events: eventService, - Identities: facadeIdentityFacade, - } - accessGrantService := &oauth2.AccessGrantService{ - AppID: appID, - AccessGrants: store, - AccessTokenIssuer: accessTokenEncoding, - Clock: clockClock, - } - preAuthenticatedURLTokenServiceImpl := &handler.PreAuthenticatedURLTokenServiceImpl{ - Clock: clockClock, - PreAuthenticatedURLTokens: store, - AccessGrantService: accessGrantService, - OfflineGrantService: oauthOfflineGrantService, - } - oauthAccessTokenEncoding := &oauth2.AccessTokenEncoding{ - Secrets: oAuthKeyMaterials, - Clock: clockClock, - IDTokenIssuer: idTokenIssuer, - BaseURL: endpointsEndpoints, - Events: eventService, - Identities: facadeIdentityFacade, - } - tokenGenerator := _wireTokenGeneratorValue - oauthAccessGrantService := oauth2.AccessGrantService{ - AppID: appID, - AccessGrants: store, - AccessTokenIssuer: accessTokenEncoding, - Clock: clockClock, - } - tokenService := &handler.TokenService{ - RemoteIP: remoteIP, - UserAgentString: userAgentString, - AppID: appID, - Config: oAuthConfig, - Authorizations: authorizationStore, - OfflineGrants: store, - AccessGrants: store, - OfflineGrantService: offlineGrantService, - AccessEvents: eventProvider, - AccessTokenIssuer: oauthAccessTokenEncoding, - GenerateToken: tokenGenerator, - Clock: clockClock, - Users: userQueries, - AccessGrantService: oauthAccessGrantService, - } - app2appProvider := &app2app.Provider{ - Clock: clockClock, - } - codeGrantService := handler.CodeGrantService{ - AppID: appID, - CodeGenerator: tokenGenerator, - Clock: clockClock, - CodeGrants: store, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, + samlService := &saml.Service{ + Clock: clockClock, + AppID: appID, + SAMLEnvironmentConfig: samlEnvironmentConfig, + SAMLConfig: samlConfig, + SAMLIdpSigningMaterials: samlIdpSigningMaterials, + SAMLSpSigningMaterials: samlSpSigningMaterials, + Endpoints: endpointsEndpoints, + UserInfoProvider: idTokenIssuer, + IDPSessionProvider: idpsessionProvider, + OfflineGrantSessionProvider: oauthOfflineGrantService, } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: resolver, + samlBindingHTTPPostWriter := &samlbinding.SAMLBindingHTTPPostWriter{} + samlBindingHTTPRedirectWriter := &samlbinding.SAMLBindingHTTPRedirectWriter{ + Signer: samlService, } - scopesValidator := _wireScopesValidatorValue - tokenHandler := &handler.TokenHandler{ - Context: contextContext, - AppID: appID, - AppDomains: appDomains, - HTTPProto: httpProto, - HTTPOrigin: httpOrigin, - OAuthFeatureConfig: oAuthFeatureConfig, - IdentityFeatureConfig: identityFeatureConfig, - OAuthClientCredentials: oAuthClientCredentials, - Logger: tokenHandlerLogger, - Authorizations: authorizationService, - CodeGrants: store, - SettingsActionGrantStore: store, - IDPSessions: idpsessionProvider, - OfflineGrants: store, - AppSessionTokens: store, - OfflineGrantService: oauthOfflineGrantService, - PreAuthenticatedURLTokenService: preAuthenticatedURLTokenServiceImpl, - Graphs: interactionService, - IDTokenIssuer: idTokenIssuer, - Clock: clockClock, - TokenService: tokenService, - Events: eventService, - SessionManager: manager2, - App2App: app2appProvider, - Challenges: challengeProvider, - CodeGrantService: codeGrantService, - ClientResolver: resolver, - UIInfoResolver: uiInfoResolver, - RemoteIP: remoteIP, - UserAgentString: userAgentString, - ValidateScopes: scopesValidator, + sloService := &saml.SLOService{ + SAMLService: samlService, + BindingHTTPPostWriter: samlBindingHTTPPostWriter, + BindingHTTPRedirectWriter: samlBindingHTTPRedirectWriter, } - appSessionTokenService := &oauth2.AppSessionTokenService{ - AppSessions: store, - AppSessionTokens: store, - OfflineGrantService: oauthOfflineGrantService, - Cookies: cookieManager, - Clock: clockClock, + logoutHandler := &webapp.LogoutHandler{ + ControllerFactory: controllerFactory, + Database: handle, + TrustProxy: trustProxy, + OAuth: oAuthConfig, + UIConfig: uiConfig, + SAMLConfig: samlConfig, + SessionManager: manager2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + OAuthClientResolver: resolver, + SAMLSLOSessionService: samlslosessionStoreRedis, + SAMLSLOService: sloService, } - testerHandler := &webapp.TesterHandler{ - AppID: appID, - ControllerFactory: controllerFactory, - OauthEndpointsProvider: endpointsEndpoints, - TesterEndpointsProvider: endpointsEndpoints, - TesterService: testerStore, - TesterTokenIssuer: tokenHandler, - OAuthClientResolver: resolver, - AppSessionTokenService: appSessionTokenService, - CookieManager: cookieManager, - Renderer: responseRenderer, - BaseViewModel: baseViewModeler, - UserInfoProvider: idTokenIssuer, - OfflineGrants: oauthOfflineGrantService, + return logoutHandler +} + +func newWebAppAppStaticAssetsHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + appContext := appProvider.AppContext + manager := appContext.Resources + appStaticAssetsHandler := &webapp.AppStaticAssetsHandler{ + Resources: manager, } - return testerHandler + return appStaticAssetsHandler } -func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { +func newWebAppReturnHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, - } + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig httpConfig := appConfig.HTTP cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) - featureConfig := config.FeatureConfig + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) clockClock := _wireSystemClockValue - remoteIP := deps.ProvideRemoteIP(request, trustProxy) + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - handle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) - store := &user.Store{ + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, - AppID: appID, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -73922,7 +73905,6 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID - uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -73973,7 +73955,6 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, Redis: appredisHandle, @@ -73981,16 +73962,14 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources @@ -74231,14 +74210,14 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -74255,7 +74234,7 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -74337,7 +74316,7 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -74348,22 +74327,7 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { Service: elasticsearchService, Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, - } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ Redis: appredisHandle, AppID: appID, @@ -74408,7 +74372,7 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp @@ -74422,7 +74386,7 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -74444,12 +74408,27 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -74464,24 +74443,13 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ Redis: appredisHandle, AppID: appID, @@ -74503,31 +74471,15 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -74569,13 +74521,11 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { authenticatorFacade := facade.AuthenticatorFacade{ Coordinator: coordinator, } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, } messageSender := &otp.MessageSender{ AppID: appID, @@ -74584,8 +74534,28 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -74604,190 +74574,261 @@ func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, Redis: appredisHandle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - workflowStoreImpl := &workflow.StoreImpl{ - Redis: appredisHandle, - AppID: appID, - Context: contextContext, + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - eventStoreImpl := workflow.NewEventStore(appID, appredisHandle, workflowStoreImpl) - dependencies := &workflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Captcha: captchaProvider, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - WorkflowEvents: eventStoreImpl, - OfflineGrants: redisStore, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } - workflowServiceLogger := workflow.NewServiceLogger(factory) - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - workflowService := &workflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: workflowServiceLogger, - Store: workflowStoreImpl, - Database: handle, - UIInfoResolver: uiService, + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, } - workflowNewHandler := &api.WorkflowNewHandler{ - JSON: jsonResponseWriter, - Cookies: cookieManager, - Workflows: workflowService, - OAuthSessions: oauthsessionStoreRedis, - UIInfoResolver: uiInfoResolver, + returnHandler := &webapp.ReturnHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, } - return workflowNewHandler + return returnHandler } -func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { +func newWebAppErrorHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, - } - request := p.Request - contextContext := deps.ProvideRequestContext(request) + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - featureConfig := config.FeatureConfig - clockClock := _wireSystemClockValue + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - handle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) - store := &user.Store{ + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, - AppID: appID, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -74799,7 +74840,6 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID - uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -74850,7 +74890,6 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, Redis: appredisHandle, @@ -74858,16 +74897,14 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources @@ -75108,14 +75145,14 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -75132,7 +75169,7 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -75214,7 +75251,7 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -75225,22 +75262,7 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { Service: elasticsearchService, Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, - } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ Redis: appredisHandle, AppID: appID, @@ -75285,7 +75307,7 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp @@ -75299,7 +75321,7 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -75321,12 +75343,27 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -75341,26 +75378,13 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { Logger: storeRedisLogger, } sessionConfig := appConfig.Session - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ Redis: appredisHandle, AppID: appID, @@ -75382,31 +75406,15 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -75448,13 +75456,11 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { authenticatorFacade := facade.AuthenticatorFacade{ Coordinator: coordinator, } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, } messageSender := &otp.MessageSender{ AppID: appID, @@ -75463,8 +75469,28 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -75483,132 +75509,220 @@ func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, Redis: appredisHandle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - workflowStoreImpl := &workflow.StoreImpl{ - Redis: appredisHandle, - AppID: appID, - Context: contextContext, + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - eventStoreImpl := workflow.NewEventStore(appID, appredisHandle, workflowStoreImpl) - dependencies := &workflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Captcha: captchaProvider, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - WorkflowEvents: eventStoreImpl, - OfflineGrants: redisStore, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } - workflowServiceLogger := workflow.NewServiceLogger(factory) - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - workflowService := &workflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: workflowServiceLogger, - Store: workflowStoreImpl, + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ Database: handle, - UIInfoResolver: uiService, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, } - workflowGetHandler := &api.WorkflowGetHandler{ - JSON: jsonResponseWriter, - Workflows: workflowService, - Cookies: cookieManager, + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, } - return workflowGetHandler + errorHandler := &webapp.ErrorHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return errorHandler } -func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2ErrorHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, - } + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) request := p.Request - contextContext := deps.ProvideRequestContext(request) + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - featureConfig := config.FeatureConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } clockClock := _wireSystemClockValue - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - handle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, @@ -75639,7 +75753,6 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID - uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -75690,10 +75803,9 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -75706,9 +75818,6 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { engine := &template.Engine{ Resolver: resolver, } - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -75746,14 +75855,14 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -75868,17 +75977,17 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -75904,7 +76013,7 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -76045,11 +76154,11 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: handle, + Database: appdbHandle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -76063,9 +76172,9 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: handle, + Database: appdbHandle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) userCommands := &user.Commands{ RawCommands: rawCommands, RawQueries: rawQueries, @@ -76082,7 +76191,7 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { Queries: userQueries, } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -76110,7 +76219,7 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: appredisHandle, + Redis: handle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -76132,7 +76241,7 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -76175,14 +76284,12 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, @@ -76193,7 +76300,7 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { redisLogger := redis.NewLogger(factory) redisStore := &redis.Store{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -76202,7 +76309,7 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { } oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -76214,7 +76321,7 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: appredisHandle, + Redis: handle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -76222,18 +76329,6 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -76285,6 +76380,12 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } authenticatorFacade := facade.AuthenticatorFacade{ Coordinator: coordinator, } @@ -76348,6 +76449,11 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { DenoHook: accountMigrationDenoHook, WebHook: accountMigrationWebHook, } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } captchaConfig := appConfig.Captcha providerLogger := captcha.NewProviderLogger(factory) deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) @@ -76358,6 +76464,51 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { Logger: providerLogger, CloudflareClient: cloudflareClient, } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, @@ -76365,129 +76516,249 @@ func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - workflowStoreImpl := &workflow.StoreImpl{ - Redis: appredisHandle, + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, AppID: appID, Context: contextContext, } - eventStoreImpl := workflow.NewEventStore(appID, appredisHandle, workflowStoreImpl) - dependencies := &workflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Captcha: captchaProvider, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - WorkflowEvents: eventStoreImpl, - OfflineGrants: redisStore, - } - workflowServiceLogger := workflow.NewServiceLogger(factory) uiService := &authenticationinfo.UIService{ EndpointsProvider: endpointsEndpoints, } - workflowService := &workflow.Service{ + authenticationflowService := &authenticationflow.Service{ ContextDoNotUseDirectly: contextContext, Deps: dependencies, - Logger: workflowServiceLogger, - Store: workflowStoreImpl, - Database: handle, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, } - workflowInputHandler := &api.WorkflowInputHandler{ - JSON: jsonResponseWriter, - Workflows: workflowService, - Cookies: cookieManager, + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, } - return workflowInputHandler -} - -func newAPIWorkflowWebsocketHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - appID := appConfig.ID - handle := appProvider.Redis - request := p.Request - contextContext := deps.ProvideRequestContext(request) - storeImpl := &workflow.StoreImpl{ + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, Redis: handle, AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ Context: contextContext, + Redis: handle, + AppID: appID, } - eventStoreImpl := workflow.NewEventStore(appID, handle, storeImpl) - factory := appProvider.LoggerFactory - httpConfig := appConfig.HTTP - oAuthConfig := appConfig.OAuth - samlConfig := appConfig.SAML - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - corsAllowedOrigins := environmentConfig.CORSAllowedOrigins - corsMatcher := &middleware.CORSMatcher{ - Config: httpConfig, - OAuthConfig: oAuthConfig, - SAMLConfig: samlConfig, - CORSAllowedOrigins: corsAllowedOrigins, + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - workflowWebsocketHandler := &api.WorkflowWebsocketHandler{ - Events: eventStoreImpl, - LoggerFactory: factory, - RedisHandle: handle, - OriginMatcher: corsMatcher, + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, } - return workflowWebsocketHandler + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2ErrorHandler := &authflowv2.AuthflowV2ErrorHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2ErrorHandler } -func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { +func newWebAppCSRFErrorInstructionHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, - } + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) request := p.Request rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue httpConfig := appConfig.HTTP cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() contextContext := deps.ProvideRequestContext(request) featureConfig := config.FeatureConfig - clockClock := _wireSystemClockValue remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - handle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, @@ -76518,7 +76789,6 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID - uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -76569,10 +76839,9 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -76585,9 +76854,6 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { engine := &template.Engine{ Resolver: resolver, } - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -76625,14 +76891,14 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -76747,17 +77013,17 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -76783,7 +77049,7 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -76924,11 +77190,11 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: handle, + Database: appdbHandle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -76942,9 +77208,9 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: handle, + Database: appdbHandle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) userCommands := &user.Commands{ RawCommands: rawCommands, RawQueries: rawQueries, @@ -76961,7 +77227,7 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { Queries: userQueries, } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -76989,7 +77255,7 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: appredisHandle, + Redis: handle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -77011,7 +77277,7 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -77054,7 +77320,7 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, @@ -77070,7 +77336,7 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { redisLogger := redis.NewLogger(factory) redisStore := &redis.Store{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -77079,7 +77345,7 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { } oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -77091,7 +77357,7 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: appredisHandle, + Redis: handle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -77099,18 +77365,6 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -77162,6 +77416,12 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } authenticatorFacade := facade.AuthenticatorFacade{ Coordinator: coordinator, } @@ -77225,6 +77485,11 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { DenoHook: accountMigrationDenoHook, WebHook: accountMigrationWebHook, } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } captchaConfig := appConfig.Captcha providerLogger := captcha.NewProviderLogger(factory) deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) @@ -77235,6 +77500,51 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { Logger: providerLogger, CloudflareClient: cloudflareClient, } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, @@ -77242,74 +77552,97 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - workflowStoreImpl := &workflow.StoreImpl{ - Redis: appredisHandle, + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, AppID: appID, Context: contextContext, } - eventStoreImpl := workflow.NewEventStore(appID, appredisHandle, workflowStoreImpl) - dependencies := &workflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Captcha: captchaProvider, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - WorkflowEvents: eventStoreImpl, - OfflineGrants: redisStore, - } - workflowServiceLogger := workflow.NewServiceLogger(factory) uiService := &authenticationinfo.UIService{ EndpointsProvider: endpointsEndpoints, } - workflowService := &workflow.Service{ + authenticationflowService := &authenticationflow.Service{ ContextDoNotUseDirectly: contextContext, Deps: dependencies, - Logger: workflowServiceLogger, - Store: workflowStoreImpl, - Database: handle, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, } oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, AppID: appID, } promptResolver := &oauth2.PromptResolver{ Clock: clockClock, } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } oauthOfflineGrantService := &oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, @@ -77331,65 +77664,178 @@ func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { Cookies: cookieManager, ClientResolver: oauthclientResolver, } - workflowV2Handler := &api.WorkflowV2Handler{ - JSON: jsonResponseWriter, - Cookies: cookieManager, - Workflows: workflowService, - OAuthSessions: oauthsessionStoreRedis, - UIInfoResolver: uiInfoResolver, + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, } - return workflowV2Handler + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + csrfErrorInstructionHandler := &webapp.CSRFErrorInstructionHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return csrfErrorInstructionHandler } -func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handler { +func newWebAppNotFoundHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - handle := appProvider.Redis - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, - } + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig httpConfig := appConfig.HTTP cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) - featureConfig := config.FeatureConfig + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) clockClock := _wireSystemClockValue - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) - store := &user.Store{ + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, - AppID: appID, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -77401,7 +77847,6 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID - uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -77454,19 +77899,20 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl } store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -77504,14 +77950,14 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -77626,17 +78072,17 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -77662,7 +78108,7 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -77706,14 +78152,14 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -77730,7 +78176,7 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -77803,16 +78249,16 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -77821,26 +78267,11 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, - } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, + Database: handle, } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -77868,7 +78299,7 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -77883,21 +78314,21 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -77919,12 +78350,27 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -77933,32 +78379,21 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -77970,7 +78405,7 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -77978,31 +78413,15 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl Clock: clockClock, Random: idpsessionRand, } - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -78041,23 +78460,15 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -78065,8 +78476,28 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -78085,266 +78516,261 @@ func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handl OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, + Redis: appredisHandle, AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, Config: appConfig, FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, + OAuthClientResolver: resolver, + OfflineGrants: store, Identities: identityFacade, + Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, OTPSender: messageSender, - Verification: workflowVerificationFacade, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, ForgotPassword: forgotpasswordService, ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, + Users: userProvider, + StdAttrsService: stdattrsService, Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, - AppID: appID, - Context: contextContext, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - authenticationFlowV1CreateHandler := &api.AuthenticationFlowV1CreateHandler{ + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ LoggerFactory: factory, - RedisHandle: handle, - JSON: jsonResponseWriter, - Cookies: cookieManager, - Workflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - UIInfoResolver: uiInfoResolver, + ControllerDeps: controllerDeps, } - return authenticationFlowV1CreateHandler + notFoundHandler := &webapp.NotFoundHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return notFoundHandler } -func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2NotFoundHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - handle := appProvider.Redis - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, - } + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig httpConfig := appConfig.HTTP cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) - featureConfig := config.FeatureConfig + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) clockClock := _wireSystemClockValue - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) - store := &user.Store{ + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, - AppID: appID, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -78356,7 +78782,6 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID - uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -78409,19 +78834,20 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle } store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -78459,14 +78885,14 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -78581,17 +79007,17 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -78617,7 +79043,7 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -78661,14 +79087,14 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -78685,7 +79111,7 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -78758,16 +79184,16 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -78776,26 +79202,11 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, - } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, + Database: handle, } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -78823,7 +79234,7 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -78838,21 +79249,21 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -78874,12 +79285,27 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -78888,32 +79314,21 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -78925,7 +79340,7 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -78933,31 +79348,15 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle Clock: clockClock, Random: idpsessionRand, } - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -78996,23 +79395,15 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -79020,8 +79411,28 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -79040,233 +79451,279 @@ func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handle OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, + Redis: appredisHandle, AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, Config: appConfig, FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, + OAuthClientResolver: resolver, + OfflineGrants: store, Identities: identityFacade, + Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, OTPSender: messageSender, - Verification: workflowVerificationFacade, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, ForgotPassword: forgotpasswordService, ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, + Users: userProvider, + StdAttrsService: stdattrsService, Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, - AppID: appID, - Context: contextContext, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } - authenticationFlowV1InputHandler := &api.AuthenticationFlowV1InputHandler{ - LoggerFactory: factory, - RedisHandle: handle, - JSON: jsonResponseWriter, - Cookies: cookieManager, - Workflows: authenticationflowService, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - return authenticationFlowV1InputHandler + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + authflowV2NotFoundHandler := &authflowv2.AuthflowV2NotFoundHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2NotFoundHandler } -func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler { +func newWebAppWebsocketHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID factory := appProvider.LoggerFactory handle := appProvider.Redis - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, + publisher := webapp.NewPublisher(appID, handle) + websocketHandler := &webapp.WebsocketHandler{ + AppID: appID, + LoggerFactory: factory, + RedisHandle: handle, + Publisher: publisher, } + return websocketHandler +} + +func newWebAppPasskeyCreationOptionsHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request - contextContext := deps.ProvideRequestContext(request) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - featureConfig := config.FeatureConfig - clockClock := _wireSystemClockValue + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) - secretConfig := config.SecretConfig - databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - appID := appConfig.ID - sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) - store := &user.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -79278,7 +79735,6 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID - uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -79336,14 +79792,15 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -79583,14 +80040,14 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -79607,7 +80064,7 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -79689,7 +80146,7 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -79700,22 +80157,7 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler Service: elasticsearchService, Database: appdbHandle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, - } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ Redis: handle, AppID: appID, @@ -79760,7 +80202,7 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp @@ -79774,7 +80216,7 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -79796,12 +80238,27 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -79816,26 +80273,13 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler Logger: storeRedisLogger, } sessionConfig := appConfig.Session - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ Redis: handle, AppID: appID, @@ -79857,31 +80301,15 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler Clock: clockClock, Random: idpsessionRand, } - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -79920,23 +80348,15 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, Redis: handle, AppID: appID, Clock: clockClock, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -79944,8 +80364,28 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -79964,291 +80404,207 @@ func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ Redis: handle, AppID: appID, Clock: clockClock, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - AppID: appID, Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, + AppID: appID, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, Redis: handle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, Config: appConfig, FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, + OAuthClientResolver: resolver, + OfflineGrants: store, Identities: identityFacade, + Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, OTPSender: messageSender, - Verification: workflowVerificationFacade, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, ForgotPassword: forgotpasswordService, ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, + Users: userProvider, + StdAttrsService: stdattrsService, Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, - AppID: appID, - Context: contextContext, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: handle, + AppID: appID, } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, } - authenticationFlowV1GetHandler := &api.AuthenticationFlowV1GetHandler{ - LoggerFactory: factory, - RedisHandle: handle, - JSON: jsonResponseWriter, - Workflows: authenticationflowService, + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } - return authenticationFlowV1GetHandler -} - -func newAPIAuthenticationFlowV1WebsocketHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - factory := appProvider.LoggerFactory - handle := appProvider.Redis - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - httpConfig := appConfig.HTTP - oAuthConfig := appConfig.OAuth - samlConfig := appConfig.SAML - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - corsAllowedOrigins := environmentConfig.CORSAllowedOrigins - corsMatcher := &middleware.CORSMatcher{ - Config: httpConfig, - OAuthConfig: oAuthConfig, - SAMLConfig: samlConfig, - CORSAllowedOrigins: corsAllowedOrigins, + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, } - appID := appConfig.ID - request := p.Request - contextContext := deps.ProvideRequestContext(request) - storeImpl := &authenticationflow.StoreImpl{ - Redis: handle, - AppID: appID, - Context: contextContext, + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, } - websocketEventStore := authenticationflow.NewWebsocketEventStore(appID, handle, storeImpl) - authenticationFlowV1WebsocketHandler := &api.AuthenticationFlowV1WebsocketHandler{ - LoggerFactory: factory, - RedisHandle: handle, - OriginMatcher: corsMatcher, - Events: websocketEventStore, + passkeyCreationOptionsHandler := &webapp.PasskeyCreationOptionsHandler{ + Page: webappService2, + Database: appdbHandle, + JSON: jsonResponseWriter, + Passkey: creationOptionsService, } - return authenticationFlowV1WebsocketHandler + return passkeyCreationOptionsHandler } -func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) http.Handler { +func newWebAppPasskeyRequestOptionsHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, - } - handle := appProvider.AppDatabase + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request - contextContext := deps.ProvideRequestContext(request) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig appID := appConfig.ID - appredisHandle := appProvider.Redis - clockClock := _wireSystemClockValue - redisStore := &accountmanagement.RedisStore{ - Context: contextContext, - AppID: appID, - Redis: appredisHandle, - Clock: clockClock, - } - identityConfig := appConfig.Identity - secretConfig := config.SecretConfig - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - loginIDConfig := identityConfig.LoginID - normalizerFactory := &loginid.NormalizerFactory{ - Config: loginIDConfig, - } - normalizer := &stdattrs.Normalizer{ - LoginIDNormalizerFactory: normalizerFactory, + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: appredisHandle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } trustProxy := environmentConfig.TrustProxy - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) - localizationConfig := appConfig.Localization - databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) - storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - store := &user.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, } - rawQueries := &user.RawQueries{ - Store: store, + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, } - authenticationConfig := appConfig.Authentication + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + clockClock := _wireSystemClockValue featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ SQLBuilder: sqlBuilderApp, @@ -80258,7 +80614,7 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - uiConfig := appConfig.UI + loginIDConfig := identityConfig.LoginID manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -80269,6 +80625,9 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt Config: loginIDConfig, TypeCheckerFactory: typeCheckerFactory, } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } provider := &loginid.Provider{ Store: loginidStore, Config: loginIDConfig, @@ -80308,21 +80667,19 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt } store2 := &passkey2.Store{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources @@ -80361,14 +80718,14 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -80396,6 +80753,9 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } ldapProvider := &ldap.Provider{ Store: ldapStore, Clock: clockClock, @@ -80480,17 +80840,17 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -80516,7 +80876,7 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -80560,14 +80920,14 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -80584,7 +80944,7 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -80657,16 +81017,16 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: handle, + Database: appdbHandle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -80675,11 +81035,11 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: handle, + Database: appdbHandle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -80707,7 +81067,7 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: appredisHandle, + Redis: handle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -80722,21 +81082,21 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -80759,7 +81119,7 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt Translation: translationService, } rawCommands := &user.RawCommands{ - Store: store, + Store: userStore, Clock: clockClock, } userCommands := &user.Commands{ @@ -80778,7 +81138,7 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -80787,34 +81147,21 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - store5 := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -80826,7 +81173,7 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: appredisHandle, + Redis: handle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -80834,31 +81181,15 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt Clock: clockClock, Random: idpsessionRand, } - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: store5, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: store5, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -80894,62 +81225,31 @@ func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) htt Clock: clockClock, PasswordGenerator: generator, } - identityFacade := &facade.IdentityFacade{ + identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } - accountmanagementService := &accountmanagement.Service{ - Database: handle, - Store: redisStore, - OAuthProvider: oAuthProviderFactory, - Identities: identityFacade, - Events: eventService, - } - accountManagementV1IdentificationHandler := &api.AccountManagementV1IdentificationHandler{ - JSON: jsonResponseWriter, - Service: accountmanagementService, - } - return accountManagementV1IdentificationHandler -} - -func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - factory := appProvider.LoggerFactory - jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) - jsonResponseWriter := &httputil.JSONResponseWriter{ - Logger: jsonResponseWriterLogger, + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, } - handle := appProvider.AppDatabase - request := p.Request - contextContext := deps.ProvideRequestContext(request) - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - appID := appConfig.ID - appredisHandle := appProvider.Redis - clockClock := _wireSystemClockValue - redisStore := &accountmanagement.RedisStore{ + anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, + Redis: handle, AppID: appID, - Redis: appredisHandle, Clock: clockClock, } - identityConfig := appConfig.Identity - secretConfig := config.SecretConfig - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - loginIDConfig := identityConfig.LoginID - normalizerFactory := &loginid.NormalizerFactory{ - Config: loginIDConfig, - } - normalizer := &stdattrs.Normalizer{ - LoginIDNormalizerFactory: normalizerFactory, + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, } - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ Context: contextContext, AppID: appID, - Redis: appredisHandle, + Redis: handle, } oAuthProviderFactory := &sso.OAuthProviderFactory{ IdentityConfig: identityConfig, @@ -80959,27 +81259,231 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider HTTPClient: oAuthHTTPClient, SimpleStoreRedisFactory: simpleStoreRedisFactory, } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: handle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + passkeyRequestOptionsHandler := &webapp.PasskeyRequestOptionsHandler{ + Page: webappService2, + Database: appdbHandle, + JSON: jsonResponseWriter, + Passkey: requestOptionsService, + } + return passkeyRequestOptionsHandler +} + +func newWebAppConnectWeb3AccountHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization - databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - store := &user.Store{ + userStore := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, AppID: appID, } rawQueries := &user.RawQueries{ - Store: store, + Store: userStore, } - authenticationConfig := appConfig.Authentication - featureConfig := config.FeatureConfig + identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ SQLBuilder: sqlBuilderApp, @@ -80989,7 +81493,7 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - uiConfig := appConfig.UI + loginIDConfig := identityConfig.LoginID manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -81000,6 +81504,9 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Config: loginIDConfig, TypeCheckerFactory: typeCheckerFactory, } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } provider := &loginid.Provider{ Store: loginidStore, Config: loginIDConfig, @@ -81044,16 +81551,14 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources @@ -81127,6 +81632,9 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } ldapProvider := &ldap.Provider{ Store: ldapStore, Clock: clockClock, @@ -81291,14 +81799,14 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -81315,7 +81823,7 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -81397,7 +81905,7 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -81408,7 +81916,7 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Service: elasticsearchService, Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ Redis: appredisHandle, AppID: appID, @@ -81453,7 +81961,7 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp @@ -81467,7 +81975,7 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -81490,7 +81998,7 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Translation: translationService, } rawCommands := &user.RawCommands{ - Store: store, + Store: userStore, Clock: clockClock, } userCommands := &user.Commands{ @@ -81509,7 +82017,7 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -81524,26 +82032,13 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Logger: storeRedisLogger, } sessionConfig := appConfig.Session - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - store5 := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ Redis: appredisHandle, AppID: appID, @@ -81565,31 +82060,15 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Clock: clockClock, Random: idpsessionRand, } - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: store5, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: store5, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -81625,37 +82104,278 @@ func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider Clock: clockClock, PasswordGenerator: generator, } - identityFacade := &facade.IdentityFacade{ + identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } - accountmanagementService := &accountmanagement.Service{ - Database: handle, - Store: redisStore, - OAuthProvider: oAuthProviderFactory, - Identities: identityFacade, - Events: eventService, + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, } - accountManagementV1IdentificationOAuthHandler := &api.AccountManagementV1IdentificationOAuthHandler{ - JSON: jsonResponseWriter, - Service: accountmanagementService, + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, } - return accountManagementV1IdentificationOAuthHandler + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + authenticationViewModeler := &viewmodels.AuthenticationViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + } + alternativeStepsViewModeler := &viewmodels.AlternativeStepsViewModeler{ + AuthenticationConfig: authenticationConfig, + } + connectWeb3AccountHandler := &webapp.ConnectWeb3AccountHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + AuthenticationViewModel: authenticationViewModeler, + AlternativeStepsViewModel: alternativeStepsViewModeler, + Renderer: responseRenderer, + AuthenticationConfig: authenticationConfig, + } + return connectWeb3AccountHandler } -func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { +func newWebAppMissingWeb3WalletHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI httpHost := deps.ProvideHTTPHost(request, trustProxy) httpProto := deps.ProvideHTTPProto(request, trustProxy) - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - uiConfig := appConfig.UI globalUIImplementation := environmentConfig.UIImplementation globalUISettingsImplementation := environmentConfig.UISettingsImplementation uiImplementationService := &web.UIImplementationService{ @@ -81668,45 +82388,46 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { HTTPProto: httpProto, UIImplementationService: uiImplementationService, } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue featureConfig := config.FeatureConfig - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + redisLogger := redis.NewLogger(factory) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) - store := &user.Store{ + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, - AppID: appID, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -81770,19 +82491,20 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { } store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -81820,14 +82542,14 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -81942,17 +82664,17 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -81978,7 +82700,7 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -82022,14 +82744,14 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -82046,7 +82768,7 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -82119,16 +82841,16 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -82137,26 +82859,11 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, - } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, + Database: handle, } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -82184,7 +82891,7 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -82199,21 +82906,21 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -82235,12 +82942,27 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -82249,32 +82971,21 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -82286,7 +82997,7 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -82294,19 +83005,15 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -82345,23 +83052,15 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -82369,8 +83068,28 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -82389,257 +83108,104 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, + Redis: appredisHandle, AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, Config: appConfig, FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, + OAuthClientResolver: resolver, + OfflineGrants: store, Identities: identityFacade, + Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, OTPSender: messageSender, - Verification: workflowVerificationFacade, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, ForgotPassword: forgotpasswordService, ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, + Users: userProvider, + StdAttrsService: stdattrsService, Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, - AppID: appID, - Context: contextContext, - } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, - } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, - } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, - ErrorRenderer: errorRenderer, + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } uiFeatureConfig := featureConfig.UI forgotPasswordConfig := appConfig.ForgotPassword googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection flashMessage := &httputil.FlashMessage{ Cookies: cookieManager, } @@ -82664,59 +83230,88 @@ func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { SupportedLanguageTags: supportedLanguageTags, AuthUISentryDSN: authUISentryDSN, AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, + OAuthClientResolver: resolver, Logger: baseLogger, } - authflowViewModeler := &viewmodels.AuthflowViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - Identity: identityConfig, - } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - analyticredisHandle := appProvider.AnalyticRedis - meterStoreRedisLogger := meter.NewStoreRedisLogger(factory) - writeStoreRedis := &meter.WriteStoreRedis{ - Context: contextContext, - Redis: analyticredisHandle, - AppID: appID, - Clock: clockClock, - Logger: meterStoreRedisLogger, + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - meterService := &meter.Service{ - Counter: writeStoreRedis, + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - tutorialCookie := &httputil.TutorialCookie{ - Cookies: cookieManager, + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, } - authflowLoginHandler := &webapp.AuthflowLoginHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - AuthflowViewModel: authflowViewModeler, - Renderer: responseRenderer, - MeterService: meterService, - TutorialCookie: tutorialCookie, - ErrorService: errorService, - Endpoints: endpointsEndpoints, + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, } - return authflowLoginHandler + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + missingWeb3WalletHandler := &webapp.MissingWeb3WalletHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + AuthenticationConfig: authenticationConfig, + } + return missingWeb3WalletHandler } -func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { +func newWebAppFeatureDisabledHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI httpHost := deps.ProvideHTTPHost(request, trustProxy) httpProto := deps.ProvideHTTPProto(request, trustProxy) - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - uiConfig := appConfig.UI globalUIImplementation := environmentConfig.UIImplementation globalUISettingsImplementation := environmentConfig.UISettingsImplementation uiImplementationService := &web.UIImplementationService{ @@ -82729,45 +83324,46 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { HTTPProto: httpProto, UIImplementationService: uiImplementationService, } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue featureConfig := config.FeatureConfig - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + redisLogger := redis.NewLogger(factory) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) - store := &user.Store{ + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, - AppID: appID, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -82831,19 +83427,20 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { } store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -82881,14 +83478,14 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -83003,17 +83600,17 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -83039,7 +83636,7 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -83083,14 +83680,14 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -83107,7 +83704,7 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -83180,16 +83777,16 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -83198,26 +83795,11 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, - } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, + Database: handle, } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -83245,7 +83827,7 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -83260,21 +83842,21 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -83296,12 +83878,27 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -83310,32 +83907,21 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -83347,7 +83933,7 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -83355,19 +83941,15 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -83406,23 +83988,15 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -83430,8 +84004,28 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -83450,257 +84044,104 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, + Redis: appredisHandle, AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, Config: appConfig, FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, + OAuthClientResolver: resolver, + OfflineGrants: store, Identities: identityFacade, + Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, OTPSender: messageSender, - Verification: workflowVerificationFacade, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, ForgotPassword: forgotpasswordService, ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, + Users: userProvider, + StdAttrsService: stdattrsService, Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, - AppID: appID, - Context: contextContext, - } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, - } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, - } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, - ErrorRenderer: errorRenderer, + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } uiFeatureConfig := featureConfig.UI forgotPasswordConfig := appConfig.ForgotPassword googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection flashMessage := &httputil.FlashMessage{ Cookies: cookieManager, } @@ -83725,71 +84166,87 @@ func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { SupportedLanguageTags: supportedLanguageTags, AuthUISentryDSN: authUISentryDSN, AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, + OAuthClientResolver: resolver, Logger: baseLogger, } - authflowViewModeler := &viewmodels.AuthflowViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - Identity: identityConfig, - } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - analyticredisHandle := appProvider.AnalyticRedis - meterStoreRedisLogger := meter.NewStoreRedisLogger(factory) - writeStoreRedis := &meter.WriteStoreRedis{ - Context: contextContext, - Redis: analyticredisHandle, - AppID: appID, - Clock: clockClock, - Logger: meterStoreRedisLogger, - } - meterService := &meter.Service{ - Counter: writeStoreRedis, + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - tutorialCookie := &httputil.TutorialCookie{ - Cookies: cookieManager, + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, } - internalAuthflowV2SignupLoginHandler := authflowv2.InternalAuthflowV2SignupLoginHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - AuthflowViewModel: authflowViewModeler, - Renderer: responseRenderer, - MeterService: meterService, - TutorialCookie: tutorialCookie, - Endpoints: endpointsEndpoints, + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, } - authflowV2LoginHandler := &authflowv2.AuthflowV2LoginHandler{ - SignupLoginHandler: internalAuthflowV2SignupLoginHandler, - UIConfig: uiConfig, - AuthenticationConfig: authenticationConfig, - Controller: authflowController, - BaseViewModel: baseViewModeler, - AuthflowViewModel: authflowViewModeler, - Renderer: responseRenderer, - MeterService: meterService, - TutorialCookie: tutorialCookie, - ErrorService: errorService, - Endpoints: endpointsEndpoints, + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, } - return authflowV2LoginHandler + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + featureDisabledHandler := &webapp.FeatureDisabledHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return featureDisabledHandler } -func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { +func newWebAppTesterHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + serviceLogger := webapp2.NewServiceLogger(factory) request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI httpHost := deps.ProvideHTTPHost(request, trustProxy) httpProto := deps.ProvideHTTPProto(request, trustProxy) - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - uiConfig := appConfig.UI globalUIImplementation := environmentConfig.UIImplementation globalUISettingsImplementation := environmentConfig.UISettingsImplementation uiImplementationService := &web.UIImplementationService{ @@ -83802,45 +84259,46 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { HTTPProto: httpProto, UIImplementationService: uiImplementationService, } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue featureConfig := config.FeatureConfig - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + redisLogger := redis.NewLogger(factory) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) - store := &user.Store{ + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, - AppID: appID, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - rawQueries := &user.RawQueries{ - Store: store, } userAgentString := deps.ProvideUserAgentString(request) - logger := event.NewLogger(factory) + eventLogger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - authenticationConfig := appConfig.Authentication + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -83904,19 +84362,20 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { } store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -83954,14 +84413,14 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -84076,17 +84535,17 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -84112,7 +84571,7 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -84156,14 +84615,14 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -84180,7 +84639,7 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -84253,16 +84712,16 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: store, + UserStore: userStore, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -84271,26 +84730,11 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, - } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, + Database: handle, } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -84318,7 +84762,7 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -84333,21 +84777,21 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - serviceLogger := whatsapp.NewServiceLogger(factory) + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: serviceLogger, + Logger: whatsappServiceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -84369,12 +84813,27 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { Sender: sender, Translation: translationService, } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -84383,32 +84842,21 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef := session.NewSessionCookieDef(sessionConfig) + cookieDef2 := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, + CookieDef: cookieDef2, } - oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -84420,7 +84868,7 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -84428,19 +84876,15 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + ClientResolver: resolver, + OfflineGrants: store, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store, Config: oAuthConfig, Service: offlineGrantService, } @@ -84479,23 +84923,15 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -84503,8 +84939,28 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -84523,226 +84979,139 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { OTPSender: messageSender, PasswordSender: sender2, } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } challengeProvider := &challenge.Provider{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, + Redis: appredisHandle, AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, Config: appConfig, FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, + OAuthClientResolver: resolver, + OfflineGrants: store, Identities: identityFacade, + Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, OTPSender: messageSender, - Verification: workflowVerificationFacade, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, ForgotPassword: forgotpasswordService, ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, + Users: userProvider, + StdAttrsService: stdattrsService, Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, - AppID: appID, - Context: contextContext, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, } + publisher := webapp.NewPublisher(appID, appredisHandle) authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, @@ -84753,135 +85122,220 @@ func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { AuthflowV1Navigator: authflowNavigator, AuthflowV2Navigator: authflowV2Navigator, } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, + TesterEndpointsProvider: endpointsEndpoints, ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, + globalredisHandle := appProvider.GlobalRedis + testerStore := &tester.TesterStore{ + Context: contextContext, + Redis: globalredisHandle, } - authflowViewModeler := &viewmodels.AuthflowViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - Identity: identityConfig, + appDomains := appContext.Domains + oAuthFeatureConfig := featureConfig.OAuth + oAuthClientCredentials := deps.ProvideOAuthClientCredentials(secretConfig) + tokenHandlerLogger := handler.NewTokenHandlerLogger(factory) + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, + authorizationService := &oauth2.AuthorizationService{ + AppID: appID, + Store: authorizationStore, + Clock: clockClock, + OAuthSessionManager: sessionManager, + OfflineGrantService: oauthOfflineGrantService, + OfflineGrantStore: store, } - analyticredisHandle := appProvider.AnalyticRedis - meterStoreRedisLogger := meter.NewStoreRedisLogger(factory) - writeStoreRedis := &meter.WriteStoreRedis{ - Context: contextContext, - Redis: analyticredisHandle, - AppID: appID, - Clock: clockClock, - Logger: meterStoreRedisLogger, + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, } - meterService := &meter.Service{ - Counter: writeStoreRedis, + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, } - tutorialCookie := &httputil.TutorialCookie{ - Cookies: cookieManager, + accessTokenEncoding := oauth2.AccessTokenEncoding{ + Secrets: oAuthKeyMaterials, + Clock: clockClock, + IDTokenIssuer: idTokenIssuer, + BaseURL: endpointsEndpoints, + Events: eventService, + Identities: facadeIdentityFacade, } - authflowSignupHandler := &webapp.AuthflowSignupHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - AuthflowViewModel: authflowViewModeler, - Renderer: responseRenderer, - MeterService: meterService, - TutorialCookie: tutorialCookie, - Endpoints: endpointsEndpoints, + accessGrantService := &oauth2.AccessGrantService{ + AppID: appID, + AccessGrants: store, + AccessTokenIssuer: accessTokenEncoding, + Clock: clockClock, } - return authflowSignupHandler + preAuthenticatedURLTokenServiceImpl := &handler.PreAuthenticatedURLTokenServiceImpl{ + Clock: clockClock, + PreAuthenticatedURLTokens: store, + AccessGrantService: accessGrantService, + OfflineGrantService: oauthOfflineGrantService, + } + oauthAccessTokenEncoding := &oauth2.AccessTokenEncoding{ + Secrets: oAuthKeyMaterials, + Clock: clockClock, + IDTokenIssuer: idTokenIssuer, + BaseURL: endpointsEndpoints, + Events: eventService, + Identities: facadeIdentityFacade, + } + tokenGenerator := _wireTokenGeneratorValue + oauthAccessGrantService := oauth2.AccessGrantService{ + AppID: appID, + AccessGrants: store, + AccessTokenIssuer: accessTokenEncoding, + Clock: clockClock, + } + tokenService := &handler.TokenService{ + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Config: oAuthConfig, + Authorizations: authorizationStore, + OfflineGrants: store, + AccessGrants: store, + OfflineGrantService: offlineGrantService, + AccessEvents: eventProvider, + AccessTokenIssuer: oauthAccessTokenEncoding, + GenerateToken: tokenGenerator, + Clock: clockClock, + Users: userQueries, + AccessGrantService: oauthAccessGrantService, + } + app2appProvider := &app2app.Provider{ + Clock: clockClock, + } + codeGrantService := handler.CodeGrantService{ + AppID: appID, + CodeGenerator: tokenGenerator, + Clock: clockClock, + CodeGrants: store, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: resolver, + } + scopesValidator := _wireScopesValidatorValue + tokenHandler := &handler.TokenHandler{ + Context: contextContext, + AppID: appID, + AppDomains: appDomains, + HTTPProto: httpProto, + HTTPOrigin: httpOrigin, + OAuthFeatureConfig: oAuthFeatureConfig, + IdentityFeatureConfig: identityFeatureConfig, + OAuthClientCredentials: oAuthClientCredentials, + Logger: tokenHandlerLogger, + Authorizations: authorizationService, + CodeGrants: store, + SettingsActionGrantStore: store, + IDPSessions: idpsessionProvider, + OfflineGrants: store, + AppSessionTokens: store, + OfflineGrantService: oauthOfflineGrantService, + PreAuthenticatedURLTokenService: preAuthenticatedURLTokenServiceImpl, + Graphs: interactionService, + IDTokenIssuer: idTokenIssuer, + Clock: clockClock, + TokenService: tokenService, + Events: eventService, + SessionManager: manager2, + App2App: app2appProvider, + Challenges: challengeProvider, + CodeGrantService: codeGrantService, + ClientResolver: resolver, + UIInfoResolver: uiInfoResolver, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + ValidateScopes: scopesValidator, + } + appSessionTokenService := &oauth2.AppSessionTokenService{ + AppSessions: store, + AppSessionTokens: store, + OfflineGrantService: oauthOfflineGrantService, + Cookies: cookieManager, + Clock: clockClock, + } + testerHandler := &webapp.TesterHandler{ + AppID: appID, + ControllerFactory: controllerFactory, + OauthEndpointsProvider: endpointsEndpoints, + TesterEndpointsProvider: endpointsEndpoints, + TesterService: testerStore, + TesterTokenIssuer: tokenHandler, + OAuthClientResolver: resolver, + AppSessionTokenService: appSessionTokenService, + CookieManager: cookieManager, + Renderer: responseRenderer, + BaseViewModel: baseViewModeler, + UserInfoProvider: idTokenIssuer, + OfflineGrants: oauthOfflineGrantService, + } + return testerHandler } -func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { +func newAPIWorkflowNewHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } request := p.Request rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - clockClock := _wireSystemClockValue httpConfig := appConfig.HTTP cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() contextContext := deps.ProvideRequestContext(request) featureConfig := config.FeatureConfig + clockClock := _wireSystemClockValue remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + handle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, @@ -84912,6 +85366,7 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -84962,9 +85417,10 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } + appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -84977,6 +85433,9 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { engine := &template.Engine{ Resolver: resolver, } + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -85014,14 +85473,14 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -85136,17 +85595,17 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -85172,7 +85631,7 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -85313,11 +85772,11 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -85331,9 +85790,9 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, + Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) userCommands := &user.Commands{ RawCommands: rawCommands, RawQueries: rawQueries, @@ -85350,7 +85809,7 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { Queries: userQueries, } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -85378,7 +85837,7 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -85400,7 +85859,7 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -85443,7 +85902,7 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, @@ -85459,7 +85918,7 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { redisLogger := redis.NewLogger(factory) redisStore := &redis.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -85468,7 +85927,7 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { } oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -85480,7 +85939,7 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -85488,6 +85947,18 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -85539,12 +86010,6 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } - anonymousStoreRedis := &anonymous.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - Clock: clockClock, - } authenticatorFacade := facade.AuthenticatorFacade{ Coordinator: coordinator, } @@ -85608,11 +86073,6 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { DenoHook: accountMigrationDenoHook, WebHook: accountMigrationWebHook, } - challengeProvider := &challenge.Provider{ - Redis: handle, - AppID: appID, - Clock: clockClock, - } captchaConfig := appConfig.Captcha providerLogger := captcha.NewProviderLogger(factory) deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) @@ -85623,51 +86083,6 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { Logger: providerLogger, CloudflareClient: cloudflareClient, } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, - } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, - } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, @@ -85675,97 +86090,74 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - AnonymousIdentities: anonymousProvider, - AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, + workflowStoreImpl := &workflow.StoreImpl{ + Redis: appredisHandle, AppID: appID, Context: contextContext, } + eventStoreImpl := workflow.NewEventStore(appID, appredisHandle, workflowStoreImpl) + dependencies := &workflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Captcha: captchaProvider, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + WorkflowEvents: eventStoreImpl, + OfflineGrants: redisStore, + } + workflowServiceLogger := workflow.NewServiceLogger(factory) uiService := &authenticationinfo.UIService{ EndpointsProvider: endpointsEndpoints, } - authenticationflowService := &authenticationflow.Service{ + workflowService := &workflow.Service{ ContextDoNotUseDirectly: contextContext, Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, + Logger: workflowServiceLogger, + Store: workflowStoreImpl, + Database: handle, UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, } oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } promptResolver := &oauth2.PromptResolver{ Clock: clockClock, } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } oauthOfflineGrantService := &oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, @@ -85787,166 +86179,40 @@ func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { Cookies: cookieManager, ClientResolver: oauthclientResolver, } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, - } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, - ErrorRenderer: errorRenderer, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - authflowViewModeler := &viewmodels.AuthflowViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - Identity: identityConfig, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - analyticredisHandle := appProvider.AnalyticRedis - meterStoreRedisLogger := meter.NewStoreRedisLogger(factory) - writeStoreRedis := &meter.WriteStoreRedis{ - Context: contextContext, - Redis: analyticredisHandle, - AppID: appID, - Clock: clockClock, - Logger: meterStoreRedisLogger, - } - meterService := &meter.Service{ - Counter: writeStoreRedis, - } - tutorialCookie := &httputil.TutorialCookie{ - Cookies: cookieManager, - } - internalAuthflowV2SignupLoginHandler := authflowv2.InternalAuthflowV2SignupLoginHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - AuthflowViewModel: authflowViewModeler, - Renderer: responseRenderer, - MeterService: meterService, - TutorialCookie: tutorialCookie, - Endpoints: endpointsEndpoints, - } - authflowV2SignupHandler := &authflowv2.AuthflowV2SignupHandler{ - SignupLoginHandler: internalAuthflowV2SignupLoginHandler, - AuthenticationConfig: authenticationConfig, - UIConfig: uiConfig, + workflowNewHandler := &api.WorkflowNewHandler{ + JSON: jsonResponseWriter, + Cookies: cookieManager, + Workflows: workflowService, + OAuthSessions: oauthsessionStoreRedis, + UIInfoResolver: uiInfoResolver, } - return authflowV2SignupHandler + return workflowNewHandler } -func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { +func newAPIWorkflowGetHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } request := p.Request - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - contextContext := deps.ProvideRequestContext(request) featureConfig := config.FeatureConfig + clockClock := _wireSystemClockValue + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + handle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, @@ -85977,6 +86243,7 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -86027,9 +86294,10 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } + appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -86042,6 +86310,9 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { engine := &template.Engine{ Resolver: resolver, } + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -86079,14 +86350,14 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -86201,17 +86472,17 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -86237,7 +86508,7 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -86378,11 +86649,11 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -86396,9 +86667,9 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, + Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) userCommands := &user.Commands{ RawCommands: rawCommands, RawQueries: rawQueries, @@ -86415,7 +86686,7 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { Queries: userQueries, } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -86443,7 +86714,7 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -86465,7 +86736,7 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -86508,12 +86779,14 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, @@ -86524,7 +86797,7 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { redisLogger := redis.NewLogger(factory) redisStore := &redis.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -86533,7 +86806,7 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { } oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -86545,7 +86818,7 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -86553,6 +86826,18 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -86604,12 +86889,6 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } - anonymousStoreRedis := &anonymous.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - Clock: clockClock, - } authenticatorFacade := facade.AuthenticatorFacade{ Coordinator: coordinator, } @@ -86673,11 +86952,6 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { DenoHook: accountMigrationDenoHook, WebHook: accountMigrationWebHook, } - challengeProvider := &challenge.Provider{ - Redis: handle, - AppID: appID, - Clock: clockClock, - } captchaConfig := appConfig.Captcha providerLogger := captcha.NewProviderLogger(factory) deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) @@ -86688,51 +86962,6 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { Logger: providerLogger, CloudflareClient: cloudflareClient, } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, - } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, - } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, @@ -86740,256 +86969,90 @@ func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - AnonymousIdentities: anonymousProvider, - AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, + workflowStoreImpl := &workflow.StoreImpl{ + Redis: appredisHandle, AppID: appID, Context: contextContext, } + eventStoreImpl := workflow.NewEventStore(appID, appredisHandle, workflowStoreImpl) + dependencies := &workflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Captcha: captchaProvider, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + WorkflowEvents: eventStoreImpl, + OfflineGrants: redisStore, + } + workflowServiceLogger := workflow.NewServiceLogger(factory) uiService := &authenticationinfo.UIService{ EndpointsProvider: endpointsEndpoints, } - authenticationflowService := &authenticationflow.Service{ + workflowService := &workflow.Service{ ContextDoNotUseDirectly: contextContext, Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, + Logger: workflowServiceLogger, + Store: workflowStoreImpl, + Database: handle, UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, - } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, - ErrorRenderer: errorRenderer, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - authflowViewModeler := &viewmodels.AuthflowViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - Identity: identityConfig, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - authflowPromoteHandler := &webapp.AuthflowPromoteHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - AuthflowViewModel: authflowViewModeler, - Renderer: responseRenderer, - Endpoints: endpointsEndpoints, + workflowGetHandler := &api.WorkflowGetHandler{ + JSON: jsonResponseWriter, + Workflows: workflowService, + Cookies: cookieManager, } - return authflowPromoteHandler + return workflowGetHandler } -func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { +func newAPIWorkflowInputHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } request := p.Request - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - contextContext := deps.ProvideRequestContext(request) featureConfig := config.FeatureConfig + clockClock := _wireSystemClockValue + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + handle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, @@ -87020,6 +87083,7 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -87070,9 +87134,10 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } + appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -87085,6 +87150,9 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { engine := &template.Engine{ Resolver: resolver, } + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -87122,14 +87190,14 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -87244,17 +87312,17 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -87280,7 +87348,7 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -87421,11 +87489,11 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -87439,9 +87507,9 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, + Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) userCommands := &user.Commands{ RawCommands: rawCommands, RawQueries: rawQueries, @@ -87458,7 +87526,7 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { Queries: userQueries, } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -87486,7 +87554,7 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -87508,7 +87576,7 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -87551,12 +87619,14 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, @@ -87567,7 +87637,7 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { redisLogger := redis.NewLogger(factory) redisStore := &redis.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -87576,7 +87646,7 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { } oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -87588,7 +87658,7 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -87596,6 +87666,18 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -87647,12 +87729,6 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } - anonymousStoreRedis := &anonymous.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - Clock: clockClock, - } authenticatorFacade := facade.AuthenticatorFacade{ Coordinator: coordinator, } @@ -87716,11 +87792,6 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { DenoHook: accountMigrationDenoHook, WebHook: accountMigrationWebHook, } - challengeProvider := &challenge.Provider{ - Redis: handle, - AppID: appID, - Clock: clockClock, - } captchaConfig := appConfig.Captcha providerLogger := captcha.NewProviderLogger(factory) deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) @@ -87731,51 +87802,6 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { Logger: providerLogger, CloudflareClient: cloudflareClient, } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, - } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, - } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, @@ -87783,256 +87809,129 @@ func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - AnonymousIdentities: anonymousProvider, - AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, + workflowStoreImpl := &workflow.StoreImpl{ + Redis: appredisHandle, AppID: appID, Context: contextContext, } + eventStoreImpl := workflow.NewEventStore(appID, appredisHandle, workflowStoreImpl) + dependencies := &workflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Captcha: captchaProvider, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + WorkflowEvents: eventStoreImpl, + OfflineGrants: redisStore, + } + workflowServiceLogger := workflow.NewServiceLogger(factory) uiService := &authenticationinfo.UIService{ EndpointsProvider: endpointsEndpoints, } - authenticationflowService := &authenticationflow.Service{ + workflowService := &workflow.Service{ ContextDoNotUseDirectly: contextContext, Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, + Logger: workflowServiceLogger, + Store: workflowStoreImpl, + Database: handle, UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, + workflowInputHandler := &api.WorkflowInputHandler{ + JSON: jsonResponseWriter, + Workflows: workflowService, + Cookies: cookieManager, } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, + return workflowInputHandler +} + +func newAPIWorkflowWebsocketHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + handle := appProvider.Redis + request := p.Request + contextContext := deps.ProvideRequestContext(request) + storeImpl := &workflow.StoreImpl{ Redis: handle, AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, - ErrorRenderer: errorRenderer, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - authflowViewModeler := &viewmodels.AuthflowViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - Identity: identityConfig, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, + eventStoreImpl := workflow.NewEventStore(appID, handle, storeImpl) + factory := appProvider.LoggerFactory + httpConfig := appConfig.HTTP + oAuthConfig := appConfig.OAuth + samlConfig := appConfig.SAML + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + corsAllowedOrigins := environmentConfig.CORSAllowedOrigins + corsMatcher := &middleware.CORSMatcher{ + Config: httpConfig, + OAuthConfig: oAuthConfig, + SAMLConfig: samlConfig, + CORSAllowedOrigins: corsAllowedOrigins, } - authflowV2PromoteHandler := &authflowv2.AuthflowV2PromoteHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - AuthflowViewModel: authflowViewModeler, - Renderer: responseRenderer, - Endpoints: endpointsEndpoints, + workflowWebsocketHandler := &api.WorkflowWebsocketHandler{ + Events: eventStoreImpl, + LoggerFactory: factory, + RedisHandle: handle, + OriginMatcher: corsMatcher, } - return authflowV2PromoteHandler + return workflowWebsocketHandler } -func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler { +func newAPIWorkflowV2Handler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } request := p.Request rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - clockClock := _wireSystemClockValue httpConfig := appConfig.HTTP cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() contextContext := deps.ProvideRequestContext(request) featureConfig := config.FeatureConfig + clockClock := _wireSystemClockValue remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + handle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, @@ -88063,6 +87962,7 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -88113,9 +88013,10 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } + appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -88128,6 +88029,9 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler engine := &template.Engine{ Resolver: resolver, } + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -88165,14 +88069,14 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -88287,17 +88191,17 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -88323,7 +88227,7 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -88464,11 +88368,11 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -88482,9 +88386,9 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, + Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) userCommands := &user.Commands{ RawCommands: rawCommands, RawQueries: rawQueries, @@ -88501,7 +88405,7 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler Queries: userQueries, } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -88529,7 +88433,7 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -88551,7 +88455,7 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -88594,7 +88498,7 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, @@ -88610,7 +88514,7 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler redisLogger := redis.NewLogger(factory) redisStore := &redis.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -88619,7 +88523,7 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler } oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -88631,7 +88535,7 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -88639,6 +88543,18 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -88690,12 +88606,6 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } - anonymousStoreRedis := &anonymous.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - Clock: clockClock, - } authenticatorFacade := facade.AuthenticatorFacade{ Coordinator: coordinator, } @@ -88759,11 +88669,6 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler DenoHook: accountMigrationDenoHook, WebHook: accountMigrationWebHook, } - challengeProvider := &challenge.Provider{ - Redis: handle, - AppID: appID, - Clock: clockClock, - } captchaConfig := appConfig.Captcha providerLogger := captcha.NewProviderLogger(factory) deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) @@ -88774,51 +88679,6 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler Logger: providerLogger, CloudflareClient: cloudflareClient, } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, - } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, - } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, @@ -88826,97 +88686,74 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - AnonymousIdentities: anonymousProvider, - AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, + workflowStoreImpl := &workflow.StoreImpl{ + Redis: appredisHandle, AppID: appID, Context: contextContext, } + eventStoreImpl := workflow.NewEventStore(appID, appredisHandle, workflowStoreImpl) + dependencies := &workflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Captcha: captchaProvider, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + WorkflowEvents: eventStoreImpl, + OfflineGrants: redisStore, + } + workflowServiceLogger := workflow.NewServiceLogger(factory) uiService := &authenticationinfo.UIService{ EndpointsProvider: endpointsEndpoints, } - authenticationflowService := &authenticationflow.Service{ + workflowService := &workflow.Service{ ContextDoNotUseDirectly: contextContext, Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, + Logger: workflowServiceLogger, + Store: workflowStoreImpl, + Database: handle, UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, } oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } promptResolver := &oauth2.PromptResolver{ Clock: clockClock, } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } oauthOfflineGrantService := &oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, @@ -88938,134 +88775,43 @@ func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler Cookies: cookieManager, ClientResolver: oauthclientResolver, } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, - } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, - ErrorRenderer: errorRenderer, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - authflowEnterPasswordHandler := &webapp.AuthflowEnterPasswordHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + workflowV2Handler := &api.WorkflowV2Handler{ + JSON: jsonResponseWriter, + Cookies: cookieManager, + Workflows: workflowService, + OAuthSessions: oauthsessionStoreRedis, + UIInfoResolver: uiInfoResolver, } - return authflowEnterPasswordHandler + return workflowV2Handler } -func newWebAppAuthflowV2EnterPasswordHandler(p *deps.RequestProvider) http.Handler { +func newAPIAuthenticationFlowV1CreateHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + handle := appProvider.Redis + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } request := p.Request rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - clockClock := _wireSystemClockValue httpConfig := appConfig.HTTP cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() contextContext := deps.ProvideRequestContext(request) featureConfig := config.FeatureConfig + clockClock := _wireSystemClockValue remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) appdbHandle := appProvider.AppDatabase sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) @@ -89099,6 +88845,7 @@ func newWebAppAuthflowV2EnterPasswordHandler(p *deps.RequestProvider) http.Handl SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -89675,6 +89422,18 @@ func newWebAppAuthflowV2EnterPasswordHandler(p *deps.RequestProvider) http.Handl Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -89945,11 +89704,6 @@ func newWebAppAuthflowV2EnterPasswordHandler(p *deps.RequestProvider) http.Handl Redis: handle, AppID: appID, } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } promptResolver := &oauth2.PromptResolver{ Clock: clockClock, } @@ -89974,138 +89728,45 @@ func newWebAppAuthflowV2EnterPasswordHandler(p *deps.RequestProvider) http.Handl Cookies: cookieManager, ClientResolver: oauthclientResolver, } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, - } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, - ErrorRenderer: errorRenderer, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ - AppConfig: appConfig, - } - authflowV2EnterPasswordHandler := &authflowv2.AuthflowV2EnterPasswordHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, + authenticationFlowV1CreateHandler := &api.AuthenticationFlowV1CreateHandler{ + LoggerFactory: factory, + RedisHandle: handle, + JSON: jsonResponseWriter, + Cookies: cookieManager, + Workflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + UIInfoResolver: uiInfoResolver, } - return authflowV2EnterPasswordHandler + return authenticationFlowV1CreateHandler } -func newWebAppAuthflowEnterOOBOTPHandler(p *deps.RequestProvider) http.Handler { +func newAPIAuthenticationFlowV1InputHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + handle := appProvider.Redis + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } request := p.Request rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - clockClock := _wireSystemClockValue httpConfig := appConfig.HTTP cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() contextContext := deps.ProvideRequestContext(request) featureConfig := config.FeatureConfig + clockClock := _wireSystemClockValue remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) appdbHandle := appProvider.AppDatabase sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) @@ -90139,6 +89800,7 @@ func newWebAppAuthflowEnterOOBOTPHandler(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -90715,6 +90377,18 @@ func newWebAppAuthflowEnterOOBOTPHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -90980,170 +90654,41 @@ func newWebAppAuthflowEnterOOBOTPHandler(p *deps.RequestProvider) http.Handler { UIInfoResolver: uiService, OAuthClientResolver: oauthclientResolver, } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, - } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, - ErrorRenderer: errorRenderer, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - authflowEnterOOBOTPHandler := &webapp.AuthflowEnterOOBOTPHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - FlashMessage: flashMessage, - Clock: clockClock, + authenticationFlowV1InputHandler := &api.AuthenticationFlowV1InputHandler{ + LoggerFactory: factory, + RedisHandle: handle, + JSON: jsonResponseWriter, + Cookies: cookieManager, + Workflows: authenticationflowService, } - return authflowEnterOOBOTPHandler + return authenticationFlowV1InputHandler } -func newWebAppAuthflowV2EnterOOBOTPHandler(p *deps.RequestProvider) http.Handler { +func newAPIAuthenticationFlowV1GetHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + handle := appProvider.Redis + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } request := p.Request - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - contextContext := deps.ProvideRequestContext(request) featureConfig := config.FeatureConfig + clockClock := _wireSystemClockValue + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) appdbHandle := appProvider.AppDatabase sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) @@ -91177,6 +90722,7 @@ func newWebAppAuthflowV2EnterOOBOTPHandler(p *deps.RequestProvider) http.Handler SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -91714,6 +91260,8 @@ func newWebAppAuthflowV2EnterOOBOTPHandler(p *deps.RequestProvider) http.Handler Logger: storeRedisLogger, } sessionConfig := appConfig.Session + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, @@ -91753,6 +91301,18 @@ func newWebAppAuthflowV2EnterOOBOTPHandler(p *deps.RequestProvider) http.Handler Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -92018,179 +91578,71 @@ func newWebAppAuthflowV2EnterOOBOTPHandler(p *deps.RequestProvider) http.Handler UIInfoResolver: uiService, OAuthClientResolver: oauthclientResolver, } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, + authenticationFlowV1GetHandler := &api.AuthenticationFlowV1GetHandler{ + LoggerFactory: factory, + RedisHandle: handle, + JSON: jsonResponseWriter, + Workflows: authenticationflowService, } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, + return authenticationFlowV1GetHandler +} + +func newAPIAuthenticationFlowV1WebsocketHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + handle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + httpConfig := appConfig.HTTP + oAuthConfig := appConfig.OAuth + samlConfig := appConfig.SAML + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + corsAllowedOrigins := environmentConfig.CORSAllowedOrigins + corsMatcher := &middleware.CORSMatcher{ + Config: httpConfig, + OAuthConfig: oAuthConfig, + SAMLConfig: samlConfig, + CORSAllowedOrigins: corsAllowedOrigins, } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, + appID := appConfig.ID + request := p.Request + contextContext := deps.ProvideRequestContext(request) + storeImpl := &authenticationflow.StoreImpl{ Redis: handle, AppID: appID, + Context: contextContext, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, - } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, - ErrorRenderer: errorRenderer, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ - AppConfig: appConfig, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - authflowV2EnterOOBOTPHandler := &authflowv2.AuthflowV2EnterOOBOTPHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, - Renderer: responseRenderer, - FlashMessage: flashMessage, - Clock: clockClock, - AuthenticatorConfig: authenticatorConfig, - IdentityConfig: identityConfig, + websocketEventStore := authenticationflow.NewWebsocketEventStore(appID, handle, storeImpl) + authenticationFlowV1WebsocketHandler := &api.AuthenticationFlowV1WebsocketHandler{ + LoggerFactory: factory, + RedisHandle: handle, + OriginMatcher: corsMatcher, + Events: websocketEventStore, } - return authflowV2EnterOOBOTPHandler + return authenticationFlowV1WebsocketHandler } -func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handler { +func newAPIAccountManagementV1IdentificationHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) - request := p.Request - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } + handle := appProvider.AppDatabase appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - contextContext := deps.ProvideRequestContext(request) - featureConfig := config.FeatureConfig - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + request := p.Request + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, @@ -92204,6 +91656,10 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle rawQueries := &user.RawQueries{ Store: store, } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + remoteIP := deps.ProvideRemoteIP(request, trustProxy) userAgentString := deps.ProvideUserAgentString(request) logger := event.NewLogger(factory) localizationConfig := appConfig.Localization @@ -92211,6 +91667,7 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) authenticationConfig := appConfig.Authentication identityConfig := appConfig.Identity + featureConfig := config.FeatureConfig identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ SQLBuilder: sqlBuilderApp, @@ -92221,6 +91678,7 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -92271,9 +91729,10 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } + appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -92286,6 +91745,9 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle engine := &template.Engine{ Resolver: resolver, } + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -92323,14 +91785,14 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -92445,17 +91907,17 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -92481,7 +91943,7 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -92622,11 +92084,11 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -92640,9 +92102,9 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, + Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) userCommands := &user.Commands{ RawCommands: rawCommands, RawQueries: rawQueries, @@ -92658,8 +92120,29 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle Commands: userCommands, Queries: userQueries, } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -92687,7 +92170,7 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -92709,7 +92192,7 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -92752,12 +92235,14 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, @@ -92766,9 +92251,9 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle CookieDef: cookieDef, } redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ + store5 := &redis.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -92777,7 +92262,7 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle } oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -92789,7 +92274,7 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -92797,6 +92282,18 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -92806,10 +92303,10 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle Clock: clockClock, IDPSessions: idpsessionProvider, ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + OfflineGrants: store5, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store5, Config: oAuthConfig, Service: offlineGrantService, } @@ -92845,26 +92342,9 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle Clock: clockClock, PasswordGenerator: generator, } - identityFacade := facade.IdentityFacade{ - Coordinator: coordinator, - } - anonymousStoreRedis := &anonymous.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - Clock: clockClock, - } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } - mfaFacade := &facade.MFAFacade{ + identityFacade := &facade.IdentityFacade{ Coordinator: coordinator, } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -92872,361 +92352,59 @@ func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handle Sender: sender, WhatsappService: whatsappService, } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, - } - forgotpasswordLogger := forgotpassword.NewLogger(factory) - sender2 := forgotpassword.Sender{ - AppConfg: appConfig, - Identities: serviceService, - Sender: sender, - Translation: translationService, - } - forgotpasswordService := &forgotpassword.Service{ - Logger: forgotpasswordLogger, - Config: appConfig, - FeatureConfig: featureConfig, - Identities: serviceService, - Authenticators: authenticatorFacade, - OTPCodes: otpService, - OTPSender: messageSender, - PasswordSender: sender2, - } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, - } - challengeProvider := &challenge.Provider{ - Redis: handle, - AppID: appID, - Clock: clockClock, - } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, - } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, - } - manager2 := &session.Manager{ - IDPSessions: idpsessionManager, - AccessTokenSessions: sessionManager, - Events: eventService, + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: handle, - AppID: appID, - } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - AnonymousIdentities: anonymousProvider, - AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, + Redis: appredisHandle, AppID: appID, - Context: contextContext, } uiService := &authenticationinfo.UIService{ EndpointsProvider: endpointsEndpoints, } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, - } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, - } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, - ErrorRenderer: errorRenderer, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, + accountmanagementService := &accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: identityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, } - authflowCreatePasswordHandler := &webapp.AuthflowCreatePasswordHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + accountManagementV1IdentificationHandler := &api.AccountManagementV1IdentificationHandler{ + JSON: jsonResponseWriter, + Service: accountmanagementService, } - return authflowCreatePasswordHandler + return accountManagementV1IdentificationHandler } -func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Handler { +func newAPIAccountManagementV1IdentificationOAuthHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) - request := p.Request - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) + jsonResponseWriterLogger := httputil.NewJSONResponseWriterLogger(factory) + jsonResponseWriter := &httputil.JSONResponseWriter{ + Logger: jsonResponseWriterLogger, + } + handle := appProvider.AppDatabase appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - clockClock := _wireSystemClockValue - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - appID := appConfig.ID - handle := appProvider.Redis - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: handle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - contextContext := deps.ProvideRequestContext(request) - featureConfig := config.FeatureConfig - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - appdbHandle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + request := p.Request + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, @@ -93240,6 +92418,10 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand rawQueries := &user.RawQueries{ Store: store, } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + remoteIP := deps.ProvideRemoteIP(request, trustProxy) userAgentString := deps.ProvideUserAgentString(request) logger := event.NewLogger(factory) localizationConfig := appConfig.Localization @@ -93247,6 +92429,7 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) authenticationConfig := appConfig.Authentication identityConfig := appConfig.Identity + featureConfig := config.FeatureConfig identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ SQLBuilder: sqlBuilderApp, @@ -93257,6 +92440,7 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -93307,9 +92491,10 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } + appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -93322,6 +92507,9 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand engine := &template.Engine{ Resolver: resolver, } + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -93359,14 +92547,14 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -93481,17 +92669,17 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -93517,7 +92705,7 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: handle, + Redis: appredisHandle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -93658,11 +92846,11 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: appdbHandle, + Database: handle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -93676,9 +92864,9 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: appdbHandle, + Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) userCommands := &user.Commands{ RawCommands: rawCommands, RawQueries: rawQueries, @@ -93694,8 +92882,29 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand Commands: userCommands, Queries: userQueries, } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -93723,7 +92932,7 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: handle, + Redis: appredisHandle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -93745,7 +92954,7 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, } @@ -93788,12 +92997,14 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, @@ -93802,9 +93013,9 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand CookieDef: cookieDef, } redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ + store5 := &redis.Store{ Context: contextContext, - Redis: handle, + Redis: appredisHandle, AppID: appID, Logger: redisLogger, SQLBuilder: sqlBuilderApp, @@ -93813,7 +93024,7 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand } oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: handle, + Redis: appredisHandle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -93825,7 +93036,7 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: handle, + Redis: appredisHandle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -93833,6 +93044,18 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } oauthclientResolver := &oauthclient.Resolver{ OAuthConfig: oAuthConfig, TesterEndpoints: endpointsEndpoints, @@ -93842,10 +93065,10 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand Clock: clockClock, IDPSessions: idpsessionProvider, ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + OfflineGrants: store5, } sessionManager := &oauth2.SessionManager{ - Store: redisStore, + Store: store5, Config: oAuthConfig, Service: offlineGrantService, } @@ -93881,349 +93104,51 @@ func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Hand Clock: clockClock, PasswordGenerator: generator, } - identityFacade := facade.IdentityFacade{ + identityFacade := &facade.IdentityFacade{ Coordinator: coordinator, } - anonymousStoreRedis := &anonymous.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - Clock: clockClock, + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, } authenticatorFacade := facade.AuthenticatorFacade{ Coordinator: coordinator, } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, - } - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } - messageSender := &otp.MessageSender{ - AppID: appID, - Translation: translationService, - Endpoints: endpointsEndpoints, - Sender: sender, - WhatsappService: whatsappService, - } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, - } - forgotpasswordLogger := forgotpassword.NewLogger(factory) - sender2 := forgotpassword.Sender{ - AppConfg: appConfig, - Identities: serviceService, - Sender: sender, - Translation: translationService, - } - forgotpasswordService := &forgotpassword.Service{ - Logger: forgotpasswordLogger, - Config: appConfig, - FeatureConfig: featureConfig, - Identities: serviceService, - Authenticators: authenticatorFacade, - OTPCodes: otpService, - OTPSender: messageSender, - PasswordSender: sender2, - } - accountMigrationConfig := appConfig.AccountMigration - accountMigrationHookConfig := accountMigrationConfig.Hook - hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) - denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) - accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ - DenoHook: denoHook, - Client: hookDenoClient, - Logger: denoMiddlewareLogger, - } - hookWebHookImpl := &hook.WebHookImpl{ - Logger: webHookLogger, - Secret: webhookKeyMaterials, - } - hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) - webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) - accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ - WebHook: hookWebHookImpl, - Client: hookHTTPClient, - Logger: webhookMiddlewareLogger, - } - accountmigrationService := &accountmigration.Service{ - Config: accountMigrationHookConfig, - DenoHook: accountMigrationDenoHook, - WebHook: accountMigrationWebHook, - } - challengeProvider := &challenge.Provider{ - Redis: handle, - AppID: appID, - Clock: clockClock, - } - captchaConfig := appConfig.Captcha - providerLogger := captcha.NewProviderLogger(factory) - deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) - cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) - captchaProvider := &captcha.Provider{ - RemoteIP: remoteIP, - Config: captchaConfig, - Logger: providerLogger, - CloudflareClient: cloudflareClient, - } - botProtectionConfig := appConfig.BotProtection - botprotectionProviderLogger := botprotection.NewProviderLogger(factory) - botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) - botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) - recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) - botprotectionProvider := &botprotection.Provider{ - RemoteIP: remoteIP, - Config: botProtectionConfig, - Logger: botprotectionProviderLogger, - CloudflareClient: botprotectionCloudflareClient, - RecaptchaV2Client: recaptchaV2Client, - Events: eventService, - } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: handle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - requestOptionsService := &passkey2.RequestOptionsService{ - ConfigService: configService, - IdentityService: serviceService, - Store: store2, - } - creationOptionsService := &passkey2.CreationOptionsService{ - ConfigService: configService, - UserService: userQueries, - IdentityService: serviceService, - Store: store2, - } - ldapConfig := identityConfig.LDAP - ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) - clientFactory := &ldap2.ClientFactory{ - Config: ldapConfig, - SecretConfig: ldapServerUserCredentials, - } - manager2 := &session.Manager{ - IDPSessions: idpsessionManager, - AccessTokenSessions: sessionManager, - Events: eventService, - } authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: handle, - AppID: appID, - } - mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - dependencies := &authenticationflow.Dependencies{ - Config: appConfig, - FeatureConfig: featureConfig, - Clock: clockClock, - RemoteIP: remoteIP, - HTTPOrigin: httpOrigin, - HTTPRequest: request, - Users: userProvider, - Identities: identityFacade, - AnonymousIdentities: anonymousProvider, - AnonymousUserPromotionCodeStore: anonymousStoreRedis, - Authenticators: authenticatorFacade, - MFA: mfaFacade, - StdAttrsService: stdattrsService, - CustomAttrsService: customattrsService, - OTPCodes: otpService, - OTPSender: messageSender, - Verification: workflowVerificationFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - AccountMigrations: accountmigrationService, - Challenges: challengeProvider, - Captcha: captchaProvider, - BotProtection: botprotectionProvider, - OAuthProviderFactory: oAuthProviderFactory, - PasskeyRequestOptionsService: requestOptionsService, - PasskeyCreationOptionsService: creationOptionsService, - PasskeyService: passkeyService, - LoginIDs: provider, - LDAP: ldapProvider, - LDAPClientFactory: clientFactory, - IDPSessions: idpsessionProvider, - Sessions: manager2, - AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef, - MFADeviceTokenCookie: mfaCookieDef, - UserFacade: userFacade, - Cookies: cookieManager, - Events: eventService, - RateLimiter: limiter, - OfflineGrants: redisStore, - IDTokens: idTokenIssuer, - } - authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) - authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: handle, + Redis: appredisHandle, AppID: appID, - Context: contextContext, } uiService := &authenticationinfo.UIService{ EndpointsProvider: endpointsEndpoints, } - authenticationflowService := &authenticationflow.Service{ - ContextDoNotUseDirectly: contextContext, - Deps: dependencies, - Logger: authenticationflowServiceLogger, - Store: authenticationflowStoreImpl, - Database: appdbHandle, - UIConfig: uiConfig, - UIInfoResolver: uiService, - OAuthClientResolver: oauthclientResolver, - } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - promptResolver := &oauth2.PromptResolver{ - Clock: clockClock, - } - oauthOfflineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - idTokenHintResolver := &oidc.IDTokenHintResolver{ - Issuer: idTokenIssuer, - Sessions: idpsessionProvider, - OfflineGrantService: oauthOfflineGrantService, - } - uiInfoResolver := &oidc.UIInfoResolver{ - Config: oAuthConfig, - EndpointsProvider: endpointsEndpoints, - PromptResolver: promptResolver, - IDTokenHintResolver: idTokenHintResolver, - Clock: clockClock, - Cookies: cookieManager, - ClientResolver: oauthclientResolver, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: handle, - AppID: appID, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, - } - authflowController := &webapp.AuthflowController{ - Logger: authflowControllerLogger, - TesterEndpointsProvider: endpointsEndpoints, - TrustProxy: trustProxy, - Clock: clockClock, - Cookies: cookieManager, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - Authflows: authenticationflowService, - OAuthSessions: oauthsessionStoreRedis, - SAMLSessions: samlsessionStoreRedis, - UIInfoResolver: uiInfoResolver, - UIConfig: uiConfig, - OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, - ErrorRenderer: errorRenderer, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ - AppConfig: appConfig, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, + accountmanagementService := &accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: identityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, } - authflowV2CreatePasswordHandler := &authflowv2.AuthflowV2CreatePasswordHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, - Renderer: responseRenderer, - FeatureConfig: featureConfig, - AuthenticatorConfig: authenticatorConfig, + accountManagementV1IdentificationOAuthHandler := &api.AccountManagementV1IdentificationOAuthHandler{ + JSON: jsonResponseWriter, + Service: accountmanagementService, } - return authflowV2CreatePasswordHandler + return accountManagementV1IdentificationOAuthHandler } -func newWebAppAuthflowEnterTOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowLoginHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -95248,18 +94173,43 @@ func newWebAppAuthflowEnterTOTPHandler(p *deps.RequestProvider) http.Handler { OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + authflowViewModeler := &viewmodels.AuthflowViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + Identity: identityConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowEnterTOTPHandler := &webapp.AuthflowEnterTOTPHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + analyticredisHandle := appProvider.AnalyticRedis + meterStoreRedisLogger := meter.NewStoreRedisLogger(factory) + writeStoreRedis := &meter.WriteStoreRedis{ + Context: contextContext, + Redis: analyticredisHandle, + AppID: appID, + Clock: clockClock, + Logger: meterStoreRedisLogger, } - return authflowEnterTOTPHandler + meterService := &meter.Service{ + Counter: writeStoreRedis, + } + tutorialCookie := &httputil.TutorialCookie{ + Cookies: cookieManager, + } + authflowLoginHandler := &webapp.AuthflowLoginHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + AuthflowViewModel: authflowViewModeler, + Renderer: responseRenderer, + MeterService: meterService, + TutorialCookie: tutorialCookie, + ErrorService: errorService, + Endpoints: endpointsEndpoints, + } + return authflowLoginHandler } -func newWebAppAuthflowV2EnterTOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2LoginHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -96284,22 +95234,55 @@ func newWebAppAuthflowV2EnterTOTPHandler(p *deps.RequestProvider) http.Handler { OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } - inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ - AppConfig: appConfig, + authflowViewModeler := &viewmodels.AuthflowViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + Identity: identityConfig, } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2EnterTOTPHandler := &authflowv2.AuthflowV2EnterTOTPHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, - Renderer: responseRenderer, + analyticredisHandle := appProvider.AnalyticRedis + meterStoreRedisLogger := meter.NewStoreRedisLogger(factory) + writeStoreRedis := &meter.WriteStoreRedis{ + Context: contextContext, + Redis: analyticredisHandle, + AppID: appID, + Clock: clockClock, + Logger: meterStoreRedisLogger, } - return authflowV2EnterTOTPHandler + meterService := &meter.Service{ + Counter: writeStoreRedis, + } + tutorialCookie := &httputil.TutorialCookie{ + Cookies: cookieManager, + } + internalAuthflowV2SignupLoginHandler := authflowv2.InternalAuthflowV2SignupLoginHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + AuthflowViewModel: authflowViewModeler, + Renderer: responseRenderer, + MeterService: meterService, + TutorialCookie: tutorialCookie, + Endpoints: endpointsEndpoints, + } + authflowV2LoginHandler := &authflowv2.AuthflowV2LoginHandler{ + SignupLoginHandler: internalAuthflowV2SignupLoginHandler, + UIConfig: uiConfig, + AuthenticationConfig: authenticationConfig, + Controller: authflowController, + BaseViewModel: baseViewModeler, + AuthflowViewModel: authflowViewModeler, + Renderer: responseRenderer, + MeterService: meterService, + TutorialCookie: tutorialCookie, + ErrorService: errorService, + Endpoints: endpointsEndpoints, + } + return authflowV2LoginHandler } -func newWebAppAuthflowSetupTOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowSignupHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -97324,18 +96307,42 @@ func newWebAppAuthflowSetupTOTPHandler(p *deps.RequestProvider) http.Handler { OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + authflowViewModeler := &viewmodels.AuthflowViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + Identity: identityConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowSetupTOTPHandler := &webapp.AuthflowSetupTOTPHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + analyticredisHandle := appProvider.AnalyticRedis + meterStoreRedisLogger := meter.NewStoreRedisLogger(factory) + writeStoreRedis := &meter.WriteStoreRedis{ + Context: contextContext, + Redis: analyticredisHandle, + AppID: appID, + Clock: clockClock, + Logger: meterStoreRedisLogger, } - return authflowSetupTOTPHandler + meterService := &meter.Service{ + Counter: writeStoreRedis, + } + tutorialCookie := &httputil.TutorialCookie{ + Cookies: cookieManager, + } + authflowSignupHandler := &webapp.AuthflowSignupHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + AuthflowViewModel: authflowViewModeler, + Renderer: responseRenderer, + MeterService: meterService, + TutorialCookie: tutorialCookie, + Endpoints: endpointsEndpoints, + } + return authflowSignupHandler } -func newWebAppAuthflowV2SetupTOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SignupHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -98360,18 +97367,47 @@ func newWebAppAuthflowV2SetupTOTPHandler(p *deps.RequestProvider) http.Handler { OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + authflowViewModeler := &viewmodels.AuthflowViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + Identity: identityConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2SetupTOTPHandler := &authflowv2.AuthflowV2SetupTOTPHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + analyticredisHandle := appProvider.AnalyticRedis + meterStoreRedisLogger := meter.NewStoreRedisLogger(factory) + writeStoreRedis := &meter.WriteStoreRedis{ + Context: contextContext, + Redis: analyticredisHandle, + AppID: appID, + Clock: clockClock, + Logger: meterStoreRedisLogger, } - return authflowV2SetupTOTPHandler + meterService := &meter.Service{ + Counter: writeStoreRedis, + } + tutorialCookie := &httputil.TutorialCookie{ + Cookies: cookieManager, + } + internalAuthflowV2SignupLoginHandler := authflowv2.InternalAuthflowV2SignupLoginHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + AuthflowViewModel: authflowViewModeler, + Renderer: responseRenderer, + MeterService: meterService, + TutorialCookie: tutorialCookie, + Endpoints: endpointsEndpoints, + } + authflowV2SignupHandler := &authflowv2.AuthflowV2SignupHandler{ + SignupLoginHandler: internalAuthflowV2SignupLoginHandler, + AuthenticationConfig: authenticationConfig, + UIConfig: uiConfig, + } + return authflowV2SignupHandler } -func newWebAppAuthflowViewRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowPromoteHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -99396,18 +98432,25 @@ func newWebAppAuthflowViewRecoveryCodeHandler(p *deps.RequestProvider) http.Hand OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + authflowViewModeler := &viewmodels.AuthflowViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + Identity: identityConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowViewRecoveryCodeHandler := &webapp.AuthflowViewRecoveryCodeHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + authflowPromoteHandler := &webapp.AuthflowPromoteHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + AuthflowViewModel: authflowViewModeler, + Renderer: responseRenderer, + Endpoints: endpointsEndpoints, } - return authflowViewRecoveryCodeHandler + return authflowPromoteHandler } -func newWebAppAuthflowV2ViewRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2PromoteHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -100432,18 +99475,25 @@ func newWebAppAuthflowV2ViewRecoveryCodeHandler(p *deps.RequestProvider) http.Ha OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + authflowViewModeler := &viewmodels.AuthflowViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + Identity: identityConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2ViewRecoveryCodeHandler := &authflowv2.AuthflowV2ViewRecoveryCodeHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + authflowV2PromoteHandler := &authflowv2.AuthflowV2PromoteHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + AuthflowViewModel: authflowViewModeler, + Renderer: responseRenderer, + Endpoints: endpointsEndpoints, } - return authflowV2ViewRecoveryCodeHandler + return authflowV2PromoteHandler } -func newWebAppAuthflowWhatsappOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowEnterPasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -101471,17 +100521,15 @@ func newWebAppAuthflowWhatsappOTPHandler(p *deps.RequestProvider) http.Handler { responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowWhatsappOTPHandler := &webapp.AuthflowWhatsappOTPHandler{ + authflowEnterPasswordHandler := &webapp.AuthflowEnterPasswordHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, - FlashMessage: flashMessage, - Clock: clockClock, } - return authflowWhatsappOTPHandler + return authflowEnterPasswordHandler } -func newWebAppAuthflowOOBOTPLinkHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2EnterPasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -102437,7 +101485,7 @@ func newWebAppAuthflowOOBOTPLinkHandler(p *deps.RequestProvider) http.Handler { Redis: handle, AppID: appID, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -102448,7 +101496,7 @@ func newWebAppAuthflowOOBOTPLinkHandler(p *deps.RequestProvider) http.Handler { RedisHandle: handle, Cookies: cookieManager, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -102473,7 +101521,7 @@ func newWebAppAuthflowOOBOTPLinkHandler(p *deps.RequestProvider) http.Handler { UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, + Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -102509,17 +101557,19 @@ func newWebAppAuthflowOOBOTPLinkHandler(p *deps.RequestProvider) http.Handler { responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowOOBOTPLinkHandler := &webapp.AuthflowOOBOTPLinkHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - FlashMessage: flashMessage, - Clock: clockClock, + inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ + AppConfig: appConfig, } - return authflowOOBOTPLinkHandler + authflowV2EnterPasswordHandler := &authflowv2.AuthflowV2EnterPasswordHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, + } + return authflowV2EnterPasswordHandler } -func newWebAppAuthflowV2OOBOTPLinkHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowEnterOOBOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -103475,7 +102525,7 @@ func newWebAppAuthflowV2OOBOTPLinkHandler(p *deps.RequestProvider) http.Handler Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -103486,7 +102536,7 @@ func newWebAppAuthflowV2OOBOTPLinkHandler(p *deps.RequestProvider) http.Handler RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -103511,7 +102561,7 @@ func newWebAppAuthflowV2OOBOTPLinkHandler(p *deps.RequestProvider) http.Handler UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -103544,23 +102594,20 @@ func newWebAppAuthflowV2OOBOTPLinkHandler(p *deps.RequestProvider) http.Handler OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } - inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ - AppConfig: appConfig, - } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2OOBOTPLinkHandler := &authflowv2.AuthflowV2OOBOTPLinkHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, - Renderer: responseRenderer, - Clock: clockClock, + authflowEnterOOBOTPHandler := &webapp.AuthflowEnterOOBOTPHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + FlashMessage: flashMessage, + Clock: clockClock, } - return authflowV2OOBOTPLinkHandler + return authflowEnterOOBOTPHandler } -func newWebAppAuthflowChangePasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2EnterOOBOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -104516,7 +103563,7 @@ func newWebAppAuthflowChangePasswordHandler(p *deps.RequestProvider) http.Handle Redis: handle, AppID: appID, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -104527,7 +103574,7 @@ func newWebAppAuthflowChangePasswordHandler(p *deps.RequestProvider) http.Handle RedisHandle: handle, Cookies: cookieManager, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -104552,7 +103599,7 @@ func newWebAppAuthflowChangePasswordHandler(p *deps.RequestProvider) http.Handle UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, + Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -104585,23 +103632,26 @@ func newWebAppAuthflowChangePasswordHandler(p *deps.RequestProvider) http.Handle OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } - changePasswordViewModeler := &viewmodels.ChangePasswordViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, + inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ + AppConfig: appConfig, } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowChangePasswordHandler := &webapp.AuthflowChangePasswordHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - ChangePasswordViewModel: changePasswordViewModeler, - Renderer: responseRenderer, + authflowV2EnterOOBOTPHandler := &authflowv2.AuthflowV2EnterOOBOTPHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, + Renderer: responseRenderer, + FlashMessage: flashMessage, + Clock: clockClock, + AuthenticatorConfig: authenticatorConfig, + IdentityConfig: identityConfig, } - return authflowChangePasswordHandler + return authflowV2EnterOOBOTPHandler } -func newWebAppAuthflowV2ChangePasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowCreatePasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -105557,7 +104607,7 @@ func newWebAppAuthflowV2ChangePasswordHandler(p *deps.RequestProvider) http.Hand Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -105568,7 +104618,7 @@ func newWebAppAuthflowV2ChangePasswordHandler(p *deps.RequestProvider) http.Hand RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -105593,7 +104643,7 @@ func newWebAppAuthflowV2ChangePasswordHandler(p *deps.RequestProvider) http.Hand UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -105626,24 +104676,18 @@ func newWebAppAuthflowV2ChangePasswordHandler(p *deps.RequestProvider) http.Hand OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } - changePasswordViewModeler := &viewmodels.ChangePasswordViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2ChangePasswordHandler := &authflowv2.AuthflowV2ChangePasswordHandler{ - Controller: authflowController, - Navigator: authflowV2Navigator, - BaseViewModel: baseViewModeler, - ChangePasswordViewModel: changePasswordViewModeler, - Renderer: responseRenderer, + authflowCreatePasswordHandler := &webapp.AuthflowCreatePasswordHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, } - return authflowV2ChangePasswordHandler + return authflowCreatePasswordHandler } -func newWebAppAuthflowV2ChangePasswordSuccessHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2CreatePasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -106668,18 +105712,24 @@ func newWebAppAuthflowV2ChangePasswordSuccessHandler(p *deps.RequestProvider) ht OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ + AppConfig: appConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2ChangePasswordSuccessHandler := &authflowv2.AuthflowV2ChangePasswordSuccessHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + authflowV2CreatePasswordHandler := &authflowv2.AuthflowV2CreatePasswordHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, + Renderer: responseRenderer, + FeatureConfig: featureConfig, + AuthenticatorConfig: authenticatorConfig, } - return authflowV2ChangePasswordSuccessHandler + return authflowV2CreatePasswordHandler } -func newWebAppAuthflowUsePasskeyHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowEnterTOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -107707,15 +106757,15 @@ func newWebAppAuthflowUsePasskeyHandler(p *deps.RequestProvider) http.Handler { responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowUsePasskeyHandler := &webapp.AuthflowUsePasskeyHandler{ + authflowEnterTOTPHandler := &webapp.AuthflowEnterTOTPHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return authflowUsePasskeyHandler + return authflowEnterTOTPHandler } -func newWebAppAuthflowV2UsePasskeyHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2EnterTOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -108746,16 +107796,16 @@ func newWebAppAuthflowV2UsePasskeyHandler(p *deps.RequestProvider) http.Handler responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2UsePasskeyHandler := &authflowv2.AuthflowV2UsePasskeyHandler{ + authflowV2EnterTOTPHandler := &authflowv2.AuthflowV2EnterTOTPHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, Renderer: responseRenderer, } - return authflowV2UsePasskeyHandler + return authflowV2EnterTOTPHandler } -func newWebAppAuthflowPromptCreatePasskeyHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowSetupTOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -109783,15 +108833,15 @@ func newWebAppAuthflowPromptCreatePasskeyHandler(p *deps.RequestProvider) http.H responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowPromptCreatePasskeyHandler := &webapp.AuthflowPromptCreatePasskeyHandler{ + authflowSetupTOTPHandler := &webapp.AuthflowSetupTOTPHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return authflowPromptCreatePasskeyHandler + return authflowSetupTOTPHandler } -func newWebAppAuthflowV2PromptCreatePasskeyHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SetupTOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -110819,15 +109869,15 @@ func newWebAppAuthflowV2PromptCreatePasskeyHandler(p *deps.RequestProvider) http responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2PromptCreatePasskeyHandler := &authflowv2.AuthflowV2PromptCreatePasskeyHandler{ + authflowV2SetupTOTPHandler := &authflowv2.AuthflowV2SetupTOTPHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return authflowV2PromptCreatePasskeyHandler + return authflowV2SetupTOTPHandler } -func newWebAppAuthflowEnterRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowViewRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -111855,15 +110905,15 @@ func newWebAppAuthflowEnterRecoveryCodeHandler(p *deps.RequestProvider) http.Han responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowEnterRecoveryCodeHandler := &webapp.AuthflowEnterRecoveryCodeHandler{ + authflowViewRecoveryCodeHandler := &webapp.AuthflowViewRecoveryCodeHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return authflowEnterRecoveryCodeHandler + return authflowViewRecoveryCodeHandler } -func newWebAppAuthflowV2EnterRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2ViewRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -112891,15 +111941,15 @@ func newWebAppAuthflowV2EnterRecoveryCodeHandler(p *deps.RequestProvider) http.H responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2EnterRecoveryCodeHandler := &authflowv2.AuthflowV2EnterRecoveryCodeHandler{ + authflowV2ViewRecoveryCodeHandler := &authflowv2.AuthflowV2ViewRecoveryCodeHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return authflowV2EnterRecoveryCodeHandler + return authflowV2ViewRecoveryCodeHandler } -func newWebAppAuthflowSetupOOBOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowWhatsappOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -113927,15 +112977,17 @@ func newWebAppAuthflowSetupOOBOTPHandler(p *deps.RequestProvider) http.Handler { responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowSetupOOBOTPHandler := &webapp.AuthflowSetupOOBOTPHandler{ + authflowWhatsappOTPHandler := &webapp.AuthflowWhatsappOTPHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, + FlashMessage: flashMessage, + Clock: clockClock, } - return authflowSetupOOBOTPHandler + return authflowWhatsappOTPHandler } -func newWebAppAuthflowV2SetupOOBOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowOOBOTPLinkHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -114891,7 +113943,7 @@ func newWebAppAuthflowV2SetupOOBOTPHandler(p *deps.RequestProvider) http.Handler Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -114902,7 +113954,7 @@ func newWebAppAuthflowV2SetupOOBOTPHandler(p *deps.RequestProvider) http.Handler RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -114927,7 +113979,7 @@ func newWebAppAuthflowV2SetupOOBOTPHandler(p *deps.RequestProvider) http.Handler UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -114963,15 +114015,17 @@ func newWebAppAuthflowV2SetupOOBOTPHandler(p *deps.RequestProvider) http.Handler responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2SetupOOBOTPHandler := &authflowv2.AuthflowV2SetupOOBOTPHandler{ + authflowOOBOTPLinkHandler := &webapp.AuthflowOOBOTPLinkHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, + FlashMessage: flashMessage, + Clock: clockClock, } - return authflowV2SetupOOBOTPHandler + return authflowOOBOTPLinkHandler } -func newWebAppAuthflowTerminateOtherSessionsHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2OOBOTPLinkHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -115927,7 +114981,7 @@ func newWebAppAuthflowTerminateOtherSessionsHandler(p *deps.RequestProvider) htt Redis: handle, AppID: appID, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -115938,7 +114992,7 @@ func newWebAppAuthflowTerminateOtherSessionsHandler(p *deps.RequestProvider) htt RedisHandle: handle, Cookies: cookieManager, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -115963,7 +115017,7 @@ func newWebAppAuthflowTerminateOtherSessionsHandler(p *deps.RequestProvider) htt UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, + Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -115996,18 +115050,23 @@ func newWebAppAuthflowTerminateOtherSessionsHandler(p *deps.RequestProvider) htt OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ + AppConfig: appConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowTerminateOtherSessionsHandler := &webapp.AuthflowTerminateOtherSessionsHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + authflowV2OOBOTPLinkHandler := &authflowv2.AuthflowV2OOBOTPLinkHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, + Renderer: responseRenderer, + Clock: clockClock, } - return authflowTerminateOtherSessionsHandler + return authflowV2OOBOTPLinkHandler } -func newWebAppAuthflowV2TerminateOtherSessionsHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowChangePasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -116963,7 +116022,7 @@ func newWebAppAuthflowV2TerminateOtherSessionsHandler(p *deps.RequestProvider) h Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -116974,7 +116033,7 @@ func newWebAppAuthflowV2TerminateOtherSessionsHandler(p *deps.RequestProvider) h RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -116999,7 +116058,7 @@ func newWebAppAuthflowV2TerminateOtherSessionsHandler(p *deps.RequestProvider) h UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -117032,18 +116091,23 @@ func newWebAppAuthflowV2TerminateOtherSessionsHandler(p *deps.RequestProvider) h OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + changePasswordViewModeler := &viewmodels.ChangePasswordViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2TerminateOtherSessionsHandler := &authflowv2.AuthflowV2TerminateOtherSessionsHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + authflowChangePasswordHandler := &webapp.AuthflowChangePasswordHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + ChangePasswordViewModel: changePasswordViewModeler, + Renderer: responseRenderer, } - return authflowV2TerminateOtherSessionsHandler + return authflowChangePasswordHandler } -func newWebAppAuthflowWechatHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2ChangePasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -117999,7 +117063,7 @@ func newWebAppAuthflowWechatHandler(p *deps.RequestProvider) http.Handler { Redis: handle, AppID: appID, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -118010,7 +117074,7 @@ func newWebAppAuthflowWechatHandler(p *deps.RequestProvider) http.Handler { RedisHandle: handle, Cookies: cookieManager, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -118035,7 +117099,7 @@ func newWebAppAuthflowWechatHandler(p *deps.RequestProvider) http.Handler { UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, + Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -118068,19 +117132,24 @@ func newWebAppAuthflowWechatHandler(p *deps.RequestProvider) http.Handler { OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + changePasswordViewModeler := &viewmodels.ChangePasswordViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowWechatHandler := &webapp.AuthflowWechatHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - OAuthStateStore: webappoauthStore, + authflowV2ChangePasswordHandler := &authflowv2.AuthflowV2ChangePasswordHandler{ + Controller: authflowController, + Navigator: authflowV2Navigator, + BaseViewModel: baseViewModeler, + ChangePasswordViewModel: changePasswordViewModeler, + Renderer: responseRenderer, } - return authflowWechatHandler + return authflowV2ChangePasswordHandler } -func newWebAppAuthflowForgotPasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2ChangePasswordSuccessHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -119036,7 +118105,7 @@ func newWebAppAuthflowForgotPasswordHandler(p *deps.RequestProvider) http.Handle Redis: handle, AppID: appID, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -119047,7 +118116,7 @@ func newWebAppAuthflowForgotPasswordHandler(p *deps.RequestProvider) http.Handle RedisHandle: handle, Cookies: cookieManager, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -119072,7 +118141,7 @@ func newWebAppAuthflowForgotPasswordHandler(p *deps.RequestProvider) http.Handle UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, + Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -119108,15 +118177,15 @@ func newWebAppAuthflowForgotPasswordHandler(p *deps.RequestProvider) http.Handle responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowForgotPasswordHandler := &webapp.AuthflowForgotPasswordHandler{ + authflowV2ChangePasswordSuccessHandler := &authflowv2.AuthflowV2ChangePasswordSuccessHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return authflowForgotPasswordHandler + return authflowV2ChangePasswordSuccessHandler } -func newWebAppAuthflowV2ForgotPasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowUsePasskeyHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -120072,7 +119141,7 @@ func newWebAppAuthflowV2ForgotPasswordHandler(p *deps.RequestProvider) http.Hand Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -120083,7 +119152,7 @@ func newWebAppAuthflowV2ForgotPasswordHandler(p *deps.RequestProvider) http.Hand RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -120108,7 +119177,7 @@ func newWebAppAuthflowV2ForgotPasswordHandler(p *deps.RequestProvider) http.Hand UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -120141,24 +119210,18 @@ func newWebAppAuthflowV2ForgotPasswordHandler(p *deps.RequestProvider) http.Hand OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } - authflowViewModeler := &viewmodels.AuthflowViewModeler{ - Authentication: authenticationConfig, - LoginID: loginIDConfig, - Identity: identityConfig, - } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2ForgotPasswordHandler := &authflowv2.AuthflowV2ForgotPasswordHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - AuthflowViewModel: authflowViewModeler, - Renderer: responseRenderer, + authflowUsePasskeyHandler := &webapp.AuthflowUsePasskeyHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, } - return authflowV2ForgotPasswordHandler + return authflowUsePasskeyHandler } -func newWebAppAuthflowForgotPasswordOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2UsePasskeyHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -121114,7 +120177,7 @@ func newWebAppAuthflowForgotPasswordOTPHandler(p *deps.RequestProvider) http.Han Redis: handle, AppID: appID, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -121125,7 +120188,7 @@ func newWebAppAuthflowForgotPasswordOTPHandler(p *deps.RequestProvider) http.Han RedisHandle: handle, Cookies: cookieManager, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -121150,7 +120213,7 @@ func newWebAppAuthflowForgotPasswordOTPHandler(p *deps.RequestProvider) http.Han UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, + Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -121183,20 +120246,22 @@ func newWebAppAuthflowForgotPasswordOTPHandler(p *deps.RequestProvider) http.Han OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + inlinePreviewAuthflowBranchViewModeler := &viewmodels.InlinePreviewAuthflowBranchViewModeler{ + AppConfig: appConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowForgotPasswordOTPHandler := &webapp.AuthflowForgotPasswordOTPHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - FlashMessage: flashMessage, - Clock: clockClock, + authflowV2UsePasskeyHandler := &authflowv2.AuthflowV2UsePasskeyHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + InlinePreviewAuthflowBranchViewModeler: inlinePreviewAuthflowBranchViewModeler, + Renderer: responseRenderer, } - return authflowForgotPasswordOTPHandler + return authflowV2UsePasskeyHandler } -func newWebAppAuthflowV2ForgotPasswordOTPHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowPromptCreatePasskeyHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -122152,7 +121217,7 @@ func newWebAppAuthflowV2ForgotPasswordOTPHandler(p *deps.RequestProvider) http.H Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -122163,7 +121228,7 @@ func newWebAppAuthflowV2ForgotPasswordOTPHandler(p *deps.RequestProvider) http.H RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -122188,7 +121253,7 @@ func newWebAppAuthflowV2ForgotPasswordOTPHandler(p *deps.RequestProvider) http.H UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -122224,17 +121289,15 @@ func newWebAppAuthflowV2ForgotPasswordOTPHandler(p *deps.RequestProvider) http.H responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2ForgotPasswordOTPHandler := &authflowv2.AuthflowV2ForgotPasswordOTPHandler{ + authflowPromptCreatePasskeyHandler := &webapp.AuthflowPromptCreatePasskeyHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, - FlashMessage: flashMessage, - Clock: clockClock, } - return authflowV2ForgotPasswordOTPHandler + return authflowPromptCreatePasskeyHandler } -func newWebAppAuthflowForgotPasswordSuccessHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2PromptCreatePasskeyHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -123190,7 +122253,7 @@ func newWebAppAuthflowForgotPasswordSuccessHandler(p *deps.RequestProvider) http Redis: handle, AppID: appID, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -123201,7 +122264,7 @@ func newWebAppAuthflowForgotPasswordSuccessHandler(p *deps.RequestProvider) http RedisHandle: handle, Cookies: cookieManager, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -123226,7 +122289,7 @@ func newWebAppAuthflowForgotPasswordSuccessHandler(p *deps.RequestProvider) http UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, + Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -123262,15 +122325,15 @@ func newWebAppAuthflowForgotPasswordSuccessHandler(p *deps.RequestProvider) http responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowForgotPasswordSuccessHandler := &webapp.AuthflowForgotPasswordSuccessHandler{ + authflowV2PromptCreatePasskeyHandler := &authflowv2.AuthflowV2PromptCreatePasskeyHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return authflowForgotPasswordSuccessHandler + return authflowV2PromptCreatePasskeyHandler } -func newWebAppAuthflowV2ForgotPasswordLinkSentHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowEnterRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -124226,7 +123289,7 @@ func newWebAppAuthflowV2ForgotPasswordLinkSentHandler(p *deps.RequestProvider) h Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -124237,7 +123300,7 @@ func newWebAppAuthflowV2ForgotPasswordLinkSentHandler(p *deps.RequestProvider) h RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -124262,7 +123325,7 @@ func newWebAppAuthflowV2ForgotPasswordLinkSentHandler(p *deps.RequestProvider) h UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -124298,50 +123361,28 @@ func newWebAppAuthflowV2ForgotPasswordLinkSentHandler(p *deps.RequestProvider) h responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2ForgotPasswordLinkSentHandler := &authflowv2.AuthflowV2ForgotPasswordLinkSentHandler{ + authflowEnterRecoveryCodeHandler := &webapp.AuthflowEnterRecoveryCodeHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, - Clock: clockClock, } - return authflowV2ForgotPasswordLinkSentHandler + return authflowEnterRecoveryCodeHandler } -func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2EnterRecoveryCodeHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - handle := appProvider.AppDatabase - appredisHandle := appProvider.Redis - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - appID := appConfig.ID - serviceLogger := webapp2.NewServiceLogger(factory) + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) request := p.Request - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: appredisHandle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - authenticationConfig := appConfig.Authentication - cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: appredisHandle, - Cookies: cookieManager, - } - oAuthConfig := appConfig.OAuth - uiConfig := appConfig.UI httpHost := deps.ProvideHTTPHost(request, trustProxy) httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI globalUIImplementation := environmentConfig.UIImplementation globalUISettingsImplementation := environmentConfig.UISettingsImplementation uiImplementationService := &web.UIImplementationService{ @@ -124354,46 +123395,45 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { HTTPProto: httpProto, UIImplementationService: uiImplementationService, } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, - } - resolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, } - logger := interaction.NewLogger(factory) - remoteIP := deps.ProvideRemoteIP(request, trustProxy) + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() contextContext := deps.ProvideRequestContext(request) - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) - clockClock := _wireSystemClockValue featureConfig := config.FeatureConfig - redisLogger := redis.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - store := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, } userAgentString := deps.ProvideUserAgentString(request) - eventLogger := event.NewLogger(factory) + logger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - userStore := &user.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, - AppID: appID, - } - rawQueries := &user.RawQueries{ - Store: userStore, - } + authenticationConfig := appConfig.Authentication identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -124457,20 +123497,19 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { } store2 := &passkey2.Store{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - templateResolver := &template.Resolver{ + resolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: templateResolver, + Resolver: resolver, } - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -124508,14 +123547,14 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -124630,17 +123669,17 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -124666,7 +123705,7 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -124710,14 +123749,14 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: userStore, + UserStore: store, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: userStore, + UserStore: store, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -124734,7 +123773,7 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: userStore, + Store: store, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -124807,16 +123846,16 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: handle, + Database: appdbHandle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: userStore, + UserStore: store, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -124825,11 +123864,26 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: handle, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -124857,7 +123911,7 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: appredisHandle, + Redis: handle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -124872,21 +123926,21 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + serviceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: whatsappServiceLogger, + Logger: serviceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -124908,27 +123962,12 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { Sender: sender, Translation: translationService, } - rawCommands := &user.RawCommands{ - Store: userStore, - Clock: clockClock, - } - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: userStore, + UserStore: store, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -124937,21 +123976,32 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef2 := session.NewSessionCookieDef(sessionConfig) + cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef2, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, } + oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -124963,7 +124013,7 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: appredisHandle, + Redis: handle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -124971,15 +124021,19 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: resolver, - OfflineGrants: store, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, } sessionManager := &oauth2.SessionManager{ - Store: store, + Store: redisStore, Config: oAuthConfig, Service: offlineGrantService, } @@ -125018,15 +124072,23 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -125034,28 +124096,8 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { Sender: sender, WhatsappService: whatsappService, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: appredisHandle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -125074,140 +124116,227 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { OTPSender: messageSender, PasswordSender: sender2, } - responseWriter := p.ResponseWriter - nonceService := &nonce.Service{ - Cookies: cookieManager, - Request: request, - ResponseWriter: responseWriter, + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, } challengeProvider := &challenge.Provider{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ Context: contextContext, - Redis: appredisHandle, AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } - interactionContext := &interaction.Context{ - Request: request, - RemoteIP: remoteIP, - Database: sqlExecutor, - Clock: clockClock, + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ Config: appConfig, FeatureConfig: featureConfig, - OAuthClientResolver: resolver, - OfflineGrants: store, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, Identities: identityFacade, - Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, - BiometricIdentities: biometricProvider, - OTPCodeService: otpService, - OTPSender: messageSender, - OAuthProviderFactory: oAuthProviderFactory, - OAuthRedirectURIBuilder: endpointsEndpoints, - OAuthStateStore: webappoauthStore, + Authenticators: authenticatorFacade, MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, ForgotPassword: forgotpasswordService, ResetPassword: forgotpasswordService, - Passkey: passkeyService, - Verification: verificationService, - RateLimiter: limiter, - PasswordGenerator: generator, - Nonces: nonceService, + AccountMigrations: accountmigrationService, Challenges: challengeProvider, - Users: userProvider, - StdAttrsService: stdattrsService, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, Events: eventService, - CookieManager: cookieManager, - AuthenticationInfoService: authenticationinfoStoreRedis, - Sessions: idpsessionProvider, - SessionManager: manager2, - SessionCookie: cookieDef2, - OAuthSessions: oauthsessionStoreRedis, - MFADeviceTokenCookie: cookieDef, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, } - interactionStoreRedis := &interaction.StoreRedis{ - Redis: appredisHandle, - AppID: appID, + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, } - interactionService := &interaction.Service{ - Logger: logger, - Context: interactionContext, - Store: interactionStoreRedis, + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, } - webappService2 := &webapp2.Service2{ - Logger: serviceLogger, - Request: request, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - MFADeviceTokenCookie: cookieDef, - ErrorService: errorService, - Cookies: cookieManager, - OAuthConfig: oAuthConfig, - UIConfig: uiConfig, - TrustProxy: trustProxy, - UIInfoResolver: uiService, - OAuthClientResolver: resolver, - Graph: interactionService, + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - botProtectionConfig := appConfig.BotProtection - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: resolver, - Logger: baseLogger, + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, } - publisher := webapp.NewPublisher(appID, appredisHandle) - authflowNavigator := &webapp2.AuthflowNavigator{ + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -125217,30 +124346,66 @@ func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { AuthflowV1Navigator: authflowNavigator, AuthflowV2Navigator: authflowV2Navigator, } - controllerDeps := webapp.ControllerDeps{ - Database: handle, - RedisHandle: appredisHandle, - AppID: appID, - Page: webappService2, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - Publisher: publisher, - Clock: clockClock, + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, TesterEndpointsProvider: endpointsEndpoints, - ErrorRenderer: errorRenderer, TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, } - controllerFactory := webapp.ControllerFactory{ - LoggerFactory: factory, - ControllerDeps: controllerDeps, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - reauthHandler := &webapp.ReauthHandler{ - ControllerFactory: controllerFactory, + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, } - return reauthHandler + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2EnterRecoveryCodeHandler := &authflowv2.AuthflowV2EnterRecoveryCodeHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2EnterRecoveryCodeHandler } -func newWebAppAuthflowReauthHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowSetupOOBOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -126235,14 +125400,48 @@ func newWebAppAuthflowReauthHandler(p *deps.RequestProvider) http.Handler { Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } - authflowReauthHandler := &webapp.AuthflowReauthHandler{ - Controller: authflowController, - AuthflowNavigator: authflowNavigator, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - return authflowReauthHandler + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowSetupOOBOTPHandler := &webapp.AuthflowSetupOOBOTPHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowSetupOOBOTPHandler } -func newWebAppAuthflowV2ReauthHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SetupOOBOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -127237,14 +126436,48 @@ func newWebAppAuthflowV2ReauthHandler(p *deps.RequestProvider) http.Handler { Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } - authflowV2ReauthHandler := &authflowv2.AuthflowV2ReauthHandler{ - Controller: authflowController, - AuthflowNavigator: authflowV2Navigator, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - return authflowV2ReauthHandler + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2SetupOOBOTPHandler := &authflowv2.AuthflowV2SetupOOBOTPHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2SetupOOBOTPHandler } -func newWebAppAuthflowResetPasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowTerminateOtherSessionsHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -128272,49 +127505,28 @@ func newWebAppAuthflowResetPasswordHandler(p *deps.RequestProvider) http.Handler responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowResetPasswordHandler := &webapp.AuthflowResetPasswordHandler{ + authflowTerminateOtherSessionsHandler := &webapp.AuthflowTerminateOtherSessionsHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return authflowResetPasswordHandler + return authflowTerminateOtherSessionsHandler } -func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2TerminateOtherSessionsHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - handle := appProvider.AppDatabase - appredisHandle := appProvider.Redis - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - appID := appConfig.ID - serviceLogger := webapp2.NewServiceLogger(factory) + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) request := p.Request - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: appredisHandle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - authenticationConfig := appConfig.Authentication - cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig trustProxy := environmentConfig.TrustProxy - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: appredisHandle, - Cookies: cookieManager, - } - oAuthConfig := appConfig.OAuth - uiConfig := appConfig.UI httpHost := deps.ProvideHTTPHost(request, trustProxy) httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI globalUIImplementation := environmentConfig.UIImplementation globalUISettingsImplementation := environmentConfig.UISettingsImplementation uiImplementationService := &web.UIImplementationService{ @@ -128327,46 +127539,45 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl HTTPProto: httpProto, UIImplementationService: uiImplementationService, } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, - } - resolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, } - logger := interaction.NewLogger(factory) - remoteIP := deps.ProvideRemoteIP(request, trustProxy) + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() contextContext := deps.ProvideRequestContext(request) - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) - clockClock := _wireSystemClockValue featureConfig := config.FeatureConfig - redisLogger := redis.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - store := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, } userAgentString := deps.ProvideUserAgentString(request) - eventLogger := event.NewLogger(factory) + logger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - userStore := &user.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, - AppID: appID, - } - rawQueries := &user.RawQueries{ - Store: userStore, - } + authenticationConfig := appConfig.Authentication identityConfig := appConfig.Identity identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ @@ -128430,20 +127641,19 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl } store2 := &passkey2.Store{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - templateResolver := &template.Resolver{ + resolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: templateResolver, + Resolver: resolver, } - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -128481,14 +127691,14 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ @@ -128603,17 +127813,17 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -128639,7 +127849,7 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -128683,14 +127893,14 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: userStore, + UserStore: store, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: userStore, + UserStore: store, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -128707,7 +127917,7 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: userStore, + Store: store, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -128780,16 +127990,16 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: handle, + Database: appdbHandle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, Users: userQueries, - UserStore: userStore, + UserStore: store, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -128798,11 +128008,26 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: handle, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -128830,7 +128055,7 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: appredisHandle, + Redis: handle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -128845,21 +128070,21 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + serviceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: whatsappServiceLogger, + Logger: serviceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -128881,27 +128106,12 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl Sender: sender, Translation: translationService, } - rawCommands := &user.RawCommands{ - Store: userStore, - Clock: clockClock, - } - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: userStore, + UserStore: store, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -128910,21 +128120,32 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl } storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef2 := session.NewSessionCookieDef(sessionConfig) + cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef2, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, } + oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, } eventProvider := &access.EventProvider{ @@ -128936,7 +128157,7 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl RemoteIP: remoteIP, UserAgentString: userAgentString, AppID: appID, - Redis: appredisHandle, + Redis: handle, Store: idpsessionStoreRedis, AccessEvents: eventProvider, TrustProxy: trustProxy, @@ -128944,15 +128165,19 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl Clock: clockClock, Random: idpsessionRand, } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: resolver, - OfflineGrants: store, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, } sessionManager := &oauth2.SessionManager{ - Store: store, + Store: redisStore, Config: oAuthConfig, Service: offlineGrantService, } @@ -128991,15 +128216,23 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl identityFacade := facade.IdentityFacade{ Coordinator: coordinator, } - authenticatorFacade := facade.AuthenticatorFacade{ - Coordinator: coordinator, - } anonymousStoreRedis := &anonymous.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -129007,28 +128240,8 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl Sender: sender, WhatsappService: whatsappService, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ - Context: contextContext, - AppID: appID, - Redis: appredisHandle, - } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, - } - webappoauthStore := &webappoauth.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - } - mfaFacade := &facade.MFAFacade{ - Coordinator: coordinator, + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, } forgotpasswordLogger := forgotpassword.NewLogger(factory) sender2 := forgotpassword.Sender{ @@ -129047,175 +128260,6 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl OTPSender: messageSender, PasswordSender: sender2, } - responseWriter := p.ResponseWriter - nonceService := &nonce.Service{ - Cookies: cookieManager, - Request: request, - ResponseWriter: responseWriter, - } - challengeProvider := &challenge.Provider{ - Redis: appredisHandle, - AppID: appID, - Clock: clockClock, - } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, - } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - } - manager2 := &session.Manager{ - IDPSessions: idpsessionManager, - AccessTokenSessions: sessionManager, - Events: eventService, - } - oauthsessionStoreRedis := &oauthsession.StoreRedis{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - } - interactionContext := &interaction.Context{ - Request: request, - RemoteIP: remoteIP, - Database: sqlExecutor, - Clock: clockClock, - Config: appConfig, - FeatureConfig: featureConfig, - OAuthClientResolver: resolver, - OfflineGrants: store, - Identities: identityFacade, - Authenticators: authenticatorFacade, - AnonymousIdentities: anonymousProvider, - AnonymousUserPromotionCodeStore: anonymousStoreRedis, - BiometricIdentities: biometricProvider, - OTPCodeService: otpService, - OTPSender: messageSender, - OAuthProviderFactory: oAuthProviderFactory, - OAuthRedirectURIBuilder: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - MFA: mfaFacade, - ForgotPassword: forgotpasswordService, - ResetPassword: forgotpasswordService, - Passkey: passkeyService, - Verification: verificationService, - RateLimiter: limiter, - PasswordGenerator: generator, - Nonces: nonceService, - Challenges: challengeProvider, - Users: userProvider, - StdAttrsService: stdattrsService, - Events: eventService, - CookieManager: cookieManager, - AuthenticationInfoService: authenticationinfoStoreRedis, - Sessions: idpsessionProvider, - SessionManager: manager2, - SessionCookie: cookieDef2, - OAuthSessions: oauthsessionStoreRedis, - MFADeviceTokenCookie: cookieDef, - } - interactionStoreRedis := &interaction.StoreRedis{ - Redis: appredisHandle, - AppID: appID, - } - interactionService := &interaction.Service{ - Logger: logger, - Context: interactionContext, - Store: interactionStoreRedis, - } - webappService2 := &webapp2.Service2{ - Logger: serviceLogger, - Request: request, - Sessions: sessionStoreRedis, - SessionCookie: sessionCookieDef, - SignedUpCookie: signedUpCookieDef, - MFADeviceTokenCookie: cookieDef, - ErrorService: errorService, - Cookies: cookieManager, - OAuthConfig: oAuthConfig, - UIConfig: uiConfig, - TrustProxy: trustProxy, - UIInfoResolver: uiService, - OAuthClientResolver: resolver, - Graph: interactionService, - } - uiFeatureConfig := featureConfig.UI - forgotPasswordConfig := appConfig.ForgotPassword - googleTagManagerConfig := appConfig.GoogleTagManager - botProtectionConfig := appConfig.BotProtection - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: resolver, - Logger: baseLogger, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - publisher := webapp.NewPublisher(appID, appredisHandle) - authflowNavigator := &webapp2.AuthflowNavigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ - Endpoints: endpointsEndpoints, - OAuthStateStore: webappoauthStore, - } - errorRenderer := &webapp.ErrorRenderer{ - ErrorService: errorService, - UIImplementationService: uiImplementationService, - AuthflowV1Navigator: authflowNavigator, - AuthflowV2Navigator: authflowV2Navigator, - } - controllerDeps := webapp.ControllerDeps{ - Database: handle, - RedisHandle: appredisHandle, - AppID: appID, - Page: webappService2, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - Publisher: publisher, - Clock: clockClock, - TesterEndpointsProvider: endpointsEndpoints, - ErrorRenderer: errorRenderer, - TrustProxy: trustProxy, - } - controllerFactory := webapp.ControllerFactory{ - LoggerFactory: factory, - ControllerDeps: controllerDeps, - } - authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) - customattrsService := &customattrs.Service{ - Config: userProfileConfig, - ServiceNoEvent: customattrsServiceNoEvent, - Events: eventService, - } - workflowVerificationFacade := facade.WorkflowVerificationFacade{ - Verification: verificationService, - } accountMigrationConfig := appConfig.AccountMigration accountMigrationHookConfig := accountMigrationConfig.Hook hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) @@ -129241,6 +128285,11 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl DenoHook: accountMigrationDenoHook, WebHook: accountMigrationWebHook, } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } captchaConfig := appConfig.Captcha providerLogger := captcha.NewProviderLogger(factory) deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) @@ -129251,6 +128300,7 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl Logger: providerLogger, CloudflareClient: cloudflareClient, } + botProtectionConfig := appConfig.BotProtection botprotectionProviderLogger := botprotection.NewProviderLogger(factory) botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) @@ -129263,6 +128313,21 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl RecaptchaV2Client: recaptchaV2Client, Events: eventService, } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } requestOptionsService := &passkey2.RequestOptionsService{ ConfigService: configService, IdentityService: serviceService, @@ -129280,6 +128345,17 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl Config: ldapConfig, SecretConfig: ldapServerUserCredentials, } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) userFacade := &facade.UserFacade{ UserProvider: userProvider, Coordinator: coordinator, @@ -129326,34 +128402,42 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl IDPSessions: idpsessionProvider, Sessions: manager2, AuthenticationInfos: authenticationinfoStoreRedis, - SessionCookie: cookieDef2, - MFADeviceTokenCookie: cookieDef, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, UserFacade: userFacade, Cookies: cookieManager, Events: eventService, RateLimiter: limiter, - OfflineGrants: store, + OfflineGrants: redisStore, IDTokens: idTokenIssuer, } authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) authenticationflowStoreImpl := &authenticationflow.StoreImpl{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Context: contextContext, } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } authenticationflowService := &authenticationflow.Service{ ContextDoNotUseDirectly: contextContext, Deps: dependencies, Logger: authenticationflowServiceLogger, Store: authenticationflowStoreImpl, - Database: handle, + Database: appdbHandle, UIConfig: uiConfig, UIInfoResolver: uiService, - OAuthClientResolver: resolver, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, } samlsessionStoreRedis := &samlsession.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } promptResolver := &oauth2.PromptResolver{ @@ -129363,8 +128447,8 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: resolver, - OfflineGrants: store, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, } idTokenHintResolver := &oidc.IDTokenHintResolver{ Issuer: idTokenIssuer, @@ -129378,7 +128462,33 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl IDTokenHintResolver: idTokenHintResolver, Clock: clockClock, Cookies: cookieManager, - ClientResolver: resolver, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, } authflowController := &webapp.AuthflowController{ Logger: authflowControllerLogger, @@ -129394,23 +128504,52 @@ func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handl SAMLSessions: samlsessionStoreRedis, UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, - OAuthClientResolver: resolver, + OAuthClientResolver: oauthclientResolver, Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } - authflowV2ResetPasswordHandler := &authflowv2.AuthflowV2ResetPasswordHandler{ - NonAuthflowControllerFactory: controllerFactory, - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - AdminAPIResetPasswordPolicy: passwordChecker, - ResetPassword: forgotpasswordService, - Database: handle, + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, } - return authflowV2ResetPasswordHandler + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2TerminateOtherSessionsHandler := &authflowv2.AuthflowV2TerminateOtherSessionsHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2TerminateOtherSessionsHandler } -func newWebAppAuthflowResetPasswordSuccessHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowWechatHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -130438,15 +129577,16 @@ func newWebAppAuthflowResetPasswordSuccessHandler(p *deps.RequestProvider) http. responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowResetPasswordSuccessHandler := &webapp.AuthflowResetPasswordSuccessHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + authflowWechatHandler := &webapp.AuthflowWechatHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + OAuthStateStore: webappoauthStore, } - return authflowResetPasswordSuccessHandler + return authflowWechatHandler } -func newWebAppAuthflowV2ResetPasswordSuccessHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowForgotPasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -131402,7 +130542,7 @@ func newWebAppAuthflowV2ResetPasswordSuccessHandler(p *deps.RequestProvider) htt Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -131413,7 +130553,7 @@ func newWebAppAuthflowV2ResetPasswordSuccessHandler(p *deps.RequestProvider) htt RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -131438,7 +130578,7 @@ func newWebAppAuthflowV2ResetPasswordSuccessHandler(p *deps.RequestProvider) htt UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -131474,360 +130614,15 @@ func newWebAppAuthflowV2ResetPasswordSuccessHandler(p *deps.RequestProvider) htt responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2ResetPasswordSuccessHandler := &authflowv2.AuthflowV2ResetPasswordSuccessHandler{ + authflowForgotPasswordHandler := &webapp.AuthflowForgotPasswordHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, } - return authflowV2ResetPasswordSuccessHandler -} - -func newWebAppAuthflowAccountStatusHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - oAuthConfig := appConfig.OAuth - uiConfig := appConfig.UI - featureConfig := config.FeatureConfig - uiFeatureConfig := featureConfig.UI - request := p.Request - contextContext := deps.ProvideRequestContext(request) - localizationConfig := appConfig.Localization - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) - webAppCDNHost := environmentConfig.WebAppCDNHost - manager := appContext.Resources - globalEmbeddedResourceManager := rootProvider.EmbeddedResources - staticAssetResolver := &web.StaticAssetResolver{ - Context: contextContext, - Localization: localizationConfig, - HTTPOrigin: httpOrigin, - HTTPProto: httpProto, - WebAppCDNHost: webAppCDNHost, - Resources: manager, - EmbeddedResources: globalEmbeddedResourceManager, - } - forgotPasswordConfig := appConfig.ForgotPassword - authenticationConfig := appConfig.Authentication - googleTagManagerConfig := appConfig.GoogleTagManager - botProtectionConfig := appConfig.BotProtection - appID := appConfig.ID - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - handle := appProvider.Redis - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) - supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ - Resources: manager, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - } - engine := &template.Engine{ - Resolver: resolver, - } - translationService := &translation.Service{ - Context: contextContext, - TemplateEngine: engine, - StaticAssets: staticAssetResolver, - } - clockClock := _wireSystemClockValue - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } - factory := appProvider.LoggerFactory - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - authflowAccountStatusHandler := &webapp.AuthflowAccountStatusHandler{ - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - } - return authflowAccountStatusHandler -} - -func newWebAppAuthflowV2AccountStatusHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - oAuthConfig := appConfig.OAuth - uiConfig := appConfig.UI - featureConfig := config.FeatureConfig - uiFeatureConfig := featureConfig.UI - request := p.Request - contextContext := deps.ProvideRequestContext(request) - localizationConfig := appConfig.Localization - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) - webAppCDNHost := environmentConfig.WebAppCDNHost - manager := appContext.Resources - globalEmbeddedResourceManager := rootProvider.EmbeddedResources - staticAssetResolver := &web.StaticAssetResolver{ - Context: contextContext, - Localization: localizationConfig, - HTTPOrigin: httpOrigin, - HTTPProto: httpProto, - WebAppCDNHost: webAppCDNHost, - Resources: manager, - EmbeddedResources: globalEmbeddedResourceManager, - } - forgotPasswordConfig := appConfig.ForgotPassword - authenticationConfig := appConfig.Authentication - googleTagManagerConfig := appConfig.GoogleTagManager - botProtectionConfig := appConfig.BotProtection - appID := appConfig.ID - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - handle := appProvider.Redis - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) - supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ - Resources: manager, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - } - engine := &template.Engine{ - Resolver: resolver, - } - translationService := &translation.Service{ - Context: contextContext, - TemplateEngine: engine, - StaticAssets: staticAssetResolver, - } - clockClock := _wireSystemClockValue - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } - factory := appProvider.LoggerFactory - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - authflowV2AccountStatusHandler := &authflowv2.AuthflowV2AccountStatusHandler{ - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - } - return authflowV2AccountStatusHandler -} - -func newWebAppAuthflowNoAuthenticatorHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - oAuthConfig := appConfig.OAuth - uiConfig := appConfig.UI - featureConfig := config.FeatureConfig - uiFeatureConfig := featureConfig.UI - request := p.Request - contextContext := deps.ProvideRequestContext(request) - localizationConfig := appConfig.Localization - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) - webAppCDNHost := environmentConfig.WebAppCDNHost - manager := appContext.Resources - globalEmbeddedResourceManager := rootProvider.EmbeddedResources - staticAssetResolver := &web.StaticAssetResolver{ - Context: contextContext, - Localization: localizationConfig, - HTTPOrigin: httpOrigin, - HTTPProto: httpProto, - WebAppCDNHost: webAppCDNHost, - Resources: manager, - EmbeddedResources: globalEmbeddedResourceManager, - } - forgotPasswordConfig := appConfig.ForgotPassword - authenticationConfig := appConfig.Authentication - googleTagManagerConfig := appConfig.GoogleTagManager - botProtectionConfig := appConfig.BotProtection - appID := appConfig.ID - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - handle := appProvider.Redis - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) - supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ - Resources: manager, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - } - engine := &template.Engine{ - Resolver: resolver, - } - translationService := &translation.Service{ - Context: contextContext, - TemplateEngine: engine, - StaticAssets: staticAssetResolver, - } - clockClock := _wireSystemClockValue - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } - factory := appProvider.LoggerFactory - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - authflowNoAuthenticatorHandler := &webapp.AuthflowNoAuthenticatorHandler{ - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - } - return authflowNoAuthenticatorHandler + return authflowForgotPasswordHandler } -func newWebAppAuthflowFinishFlowHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2ForgotPasswordHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -132783,7 +131578,7 @@ func newWebAppAuthflowFinishFlowHandler(p *deps.RequestProvider) http.Handler { Redis: handle, AppID: appID, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -132794,7 +131589,7 @@ func newWebAppAuthflowFinishFlowHandler(p *deps.RequestProvider) http.Handler { RedisHandle: handle, Cookies: cookieManager, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -132819,7 +131614,7 @@ func newWebAppAuthflowFinishFlowHandler(p *deps.RequestProvider) http.Handler { UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowNavigator, + Navigator: authflowV2Navigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -132852,18 +131647,24 @@ func newWebAppAuthflowFinishFlowHandler(p *deps.RequestProvider) http.Handler { OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } + authflowViewModeler := &viewmodels.AuthflowViewModeler{ + Authentication: authenticationConfig, + LoginID: loginIDConfig, + Identity: identityConfig, + } responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowFinishFlowHandler := &webapp.AuthflowFinishFlowHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + authflowV2ForgotPasswordHandler := &authflowv2.AuthflowV2ForgotPasswordHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + AuthflowViewModel: authflowViewModeler, + Renderer: responseRenderer, } - return authflowFinishFlowHandler + return authflowV2ForgotPasswordHandler } -func newWebAppAuthflowV2FinishFlowHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowForgotPasswordOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -133819,7 +132620,7 @@ func newWebAppAuthflowV2FinishFlowHandler(p *deps.RequestProvider) http.Handler Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -133830,7 +132631,7 @@ func newWebAppAuthflowV2FinishFlowHandler(p *deps.RequestProvider) http.Handler RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -133855,7 +132656,7 @@ func newWebAppAuthflowV2FinishFlowHandler(p *deps.RequestProvider) http.Handler UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -133891,15 +132692,17 @@ func newWebAppAuthflowV2FinishFlowHandler(p *deps.RequestProvider) http.Handler responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2FinishFlowHandler := &authflowv2.AuthflowV2FinishFlowHandler{ + authflowForgotPasswordOTPHandler := &webapp.AuthflowForgotPasswordOTPHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, + FlashMessage: flashMessage, + Clock: clockClock, } - return authflowV2FinishFlowHandler + return authflowForgotPasswordOTPHandler } -func newWebAppAuthflowV2AccountLinkingHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2ForgotPasswordOTPHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -134927,131 +133730,17 @@ func newWebAppAuthflowV2AccountLinkingHandler(p *deps.RequestProvider) http.Hand responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2AccountLinkingHandler := &authflowv2.AuthflowV2AccountLinkingHandler{ + authflowV2ForgotPasswordOTPHandler := &authflowv2.AuthflowV2ForgotPasswordOTPHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, - Endpoints: endpointsEndpoints, - } - return authflowV2AccountLinkingHandler -} - -func newWebAppAuthflowV2NoAuthenticatorHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - oAuthConfig := appConfig.OAuth - uiConfig := appConfig.UI - featureConfig := config.FeatureConfig - uiFeatureConfig := featureConfig.UI - request := p.Request - contextContext := deps.ProvideRequestContext(request) - localizationConfig := appConfig.Localization - httpProto := deps.ProvideHTTPProto(request, trustProxy) - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) - webAppCDNHost := environmentConfig.WebAppCDNHost - manager := appContext.Resources - globalEmbeddedResourceManager := rootProvider.EmbeddedResources - staticAssetResolver := &web.StaticAssetResolver{ - Context: contextContext, - Localization: localizationConfig, - HTTPOrigin: httpOrigin, - HTTPProto: httpProto, - WebAppCDNHost: webAppCDNHost, - Resources: manager, - EmbeddedResources: globalEmbeddedResourceManager, - } - forgotPasswordConfig := appConfig.ForgotPassword - authenticationConfig := appConfig.Authentication - googleTagManagerConfig := appConfig.GoogleTagManager - botProtectionConfig := appConfig.BotProtection - appID := appConfig.ID - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - handle := appProvider.Redis - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: handle, - Cookies: cookieManager, - } - defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) - supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ - Resources: manager, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - } - engine := &template.Engine{ - Resolver: resolver, - } - translationService := &translation.Service{ - Context: contextContext, - TemplateEngine: engine, - StaticAssets: staticAssetResolver, - } - clockClock := _wireSystemClockValue - flashMessage := &httputil.FlashMessage{ - Cookies: cookieManager, - } - authUISentryDSN := environmentConfig.AuthUISentryDSN - authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } - factory := appProvider.LoggerFactory - baseLogger := viewmodels.NewBaseLogger(factory) - baseViewModeler := &viewmodels.BaseViewModeler{ - TrustProxy: trustProxy, - OAuth: oAuthConfig, - AuthUI: uiConfig, - AuthUIFeatureConfig: uiFeatureConfig, - StaticAssets: staticAssetResolver, - ForgotPassword: forgotPasswordConfig, - Authentication: authenticationConfig, - GoogleTagManager: googleTagManagerConfig, - BotProtection: botProtectionConfig, - ErrorService: errorService, - Translations: translationService, - Clock: clockClock, - FlashMessage: flashMessage, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - AuthUISentryDSN: authUISentryDSN, - AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: oauthclientResolver, - Logger: baseLogger, - } - responseRenderer := &webapp.ResponseRenderer{ - TemplateEngine: engine, - } - authflowV2NoAuthenticatorHandler := &authflowv2.AuthflowV2NoAuthenticatorHandler{ - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, + FlashMessage: flashMessage, + Clock: clockClock, } - return authflowV2NoAuthenticatorHandler + return authflowV2ForgotPasswordOTPHandler } -func newWebAppAuthflowV2WechatHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowForgotPasswordSuccessHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -136007,7 +134696,7 @@ func newWebAppAuthflowV2WechatHandler(p *deps.RequestProvider) http.Handler { Redis: handle, AppID: appID, } - authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + authflowNavigator := &webapp2.AuthflowNavigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -136018,7 +134707,7 @@ func newWebAppAuthflowV2WechatHandler(p *deps.RequestProvider) http.Handler { RedisHandle: handle, Cookies: cookieManager, } - authflowNavigator := &webapp2.AuthflowNavigator{ + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ Endpoints: endpointsEndpoints, OAuthStateStore: webappoauthStore, } @@ -136043,7 +134732,7 @@ func newWebAppAuthflowV2WechatHandler(p *deps.RequestProvider) http.Handler { UIInfoResolver: uiInfoResolver, UIConfig: uiConfig, OAuthClientResolver: oauthclientResolver, - Navigator: authflowV2Navigator, + Navigator: authflowNavigator, ErrorRenderer: errorRenderer, } uiFeatureConfig := featureConfig.UI @@ -136079,16 +134768,15 @@ func newWebAppAuthflowV2WechatHandler(p *deps.RequestProvider) http.Handler { responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2WechatHandler := &authflowv2.AuthflowV2WechatHandler{ - Controller: authflowController, - BaseViewModel: baseViewModeler, - Renderer: responseRenderer, - OAuthStateStore: webappoauthStore, + authflowForgotPasswordSuccessHandler := &webapp.AuthflowForgotPasswordSuccessHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, } - return authflowV2WechatHandler + return authflowForgotPasswordSuccessHandler } -func newWebAppAuthflowV2LDAPLoginHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2ForgotPasswordLinkSentHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) @@ -137116,33 +135804,50 @@ func newWebAppAuthflowV2LDAPLoginHandler(p *deps.RequestProvider) http.Handler { responseRenderer := &webapp.ResponseRenderer{ TemplateEngine: engine, } - authflowV2LDAPLoginHandler := &authflowv2.AuthflowV2LDAPLoginHandler{ + authflowV2ForgotPasswordLinkSentHandler := &authflowv2.AuthflowV2ForgotPasswordLinkSentHandler{ Controller: authflowController, BaseViewModel: baseViewModeler, Renderer: responseRenderer, + Clock: clockClock, } - return authflowV2LDAPLoginHandler + return authflowV2ForgotPasswordLinkSentHandler } -func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { - clockClock := _wireSystemClockValue +func newWebAppReauthHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider + factory := appProvider.LoggerFactory + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig - samlEnvironmentConfig := environmentConfig.SAML - samlConfig := appConfig.SAML - secretConfig := config.SecretConfig - samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) - samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) - request := p.Request trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI httpHost := deps.ProvideHTTPHost(request, trustProxy) httpProto := deps.ProvideHTTPProto(request, trustProxy) - uiConfig := appConfig.UI globalUIImplementation := environmentConfig.UIImplementation globalUISettingsImplementation := environmentConfig.UISettingsImplementation uiImplementationService := &web.UIImplementationService{ @@ -137155,24 +135860,47 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { HTTPProto: httpProto, UIImplementationService: uiImplementationService, } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) - handle := appProvider.AppDatabase sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) - store := &user.Store{ + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, AppID: appID, } rawQueries := &user.RawQueries{ - Store: store, + Store: userStore, } - authenticationConfig := appConfig.Authentication identityConfig := appConfig.Identity - featureConfig := config.FeatureConfig identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ SQLBuilder: sqlBuilderApp, @@ -137233,7 +135961,6 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, Redis: appredisHandle, @@ -137241,15 +135968,14 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ + templateResolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: resolver, + Resolver: templateResolver, } - localizationConfig := appConfig.Localization httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources @@ -137285,7 +136011,6 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - remoteIP := deps.ProvideRemoteIP(request, trustProxy) web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, @@ -137293,15 +136018,14 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { AppID: appID, Clock: clockClock, } - factory := appProvider.LoggerFactory - logger := ratelimit.NewLogger(factory) + ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ - Logger: logger, + Logger: ratelimitLogger, Storage: storageRedis, Config: rateLimitsFeatureConfig, } @@ -137492,14 +136216,14 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: store, + UserStore: userStore, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -137516,7 +136240,7 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: store, + Store: userStore, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -137525,14 +136249,198 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { Web3: web3Service, RolesAndGroups: queries, } - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, } - userAgentString := deps.ProvideUserAgentString(request) storeRedisLogger := idpsession.NewStoreRedisLogger(factory) idpsessionStoreRedis := &idpsession.StoreRedis{ Redis: appredisHandle, @@ -137540,6 +136448,14 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Logger: storeRedisLogger, } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } eventStoreRedis := &access.EventStoreRedis{ Redis: appredisHandle, AppID: appID, @@ -137547,7 +136463,6 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { eventProvider := &access.EventProvider{ Store: eventStoreRedis, } - sessionConfig := appConfig.Session idpsessionRand := _wireRandValue idpsessionProvider := &idpsession.Provider{ Context: contextContext, @@ -137562,225 +136477,465 @@ func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } - oAuthConfig := appConfig.OAuth - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, - } - offlineGrantService := &oauth2.OfflineGrantService{ + offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - samlService := &saml.Service{ - Clock: clockClock, - AppID: appID, - SAMLEnvironmentConfig: samlEnvironmentConfig, - SAMLConfig: samlConfig, - SAMLIdpSigningMaterials: samlIdpSigningMaterials, - SAMLSpSigningMaterials: samlSpSigningMaterials, - Endpoints: endpointsEndpoints, - UserInfoProvider: idTokenIssuer, - IDPSessionProvider: idpsessionProvider, - OfflineGrantSessionProvider: offlineGrantService, - } - metadataHandler := &saml2.MetadataHandler{ - SAMLService: samlService, - } - return metadataHandler -} - -func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { - appProvider := p.AppProvider - factory := appProvider.LoggerFactory - loginHandlerLogger := saml2.NewLoginHandlerLogger(factory) - clockClock := _wireSystemClockValue - handle := appProvider.AppDatabase - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - samlConfig := appConfig.SAML - appID := appConfig.ID - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - samlEnvironmentConfig := environmentConfig.SAML - secretConfig := config.SecretConfig - samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) - samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) - request := p.Request - trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, + ClientResolver: resolver, + OfflineGrants: store, } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) - databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - contextContext := deps.ProvideRequestContext(request) - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) - store := &user.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, - AppID: appID, + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, } - rawQueries := &user.RawQueries{ - Store: store, + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, } - authenticationConfig := appConfig.Authentication - identityConfig := appConfig.Identity - featureConfig := config.FeatureConfig - identityFeatureConfig := featureConfig.Identity - serviceStore := &service.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, } - loginidStore := &loginid.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, } - loginIDConfig := identityConfig.LoginID - manager := appContext.Resources - typeCheckerFactory := &loginid.TypeCheckerFactory{ - UIConfig: uiConfig, - LoginIDConfig: loginIDConfig, - Resources: manager, + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, } - checker := &loginid.Checker{ - Config: loginIDConfig, - TypeCheckerFactory: typeCheckerFactory, + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, } - normalizerFactory := &loginid.NormalizerFactory{ - Config: loginIDConfig, + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, } - provider := &loginid.Provider{ - Store: loginidStore, - Config: loginIDConfig, - Checker: checker, - NormalizerFactory: normalizerFactory, - Clock: clockClock, + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, } - oauthStore := &oauth3.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - IdentityConfig: identityConfig, + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, } - oauthProvider := &oauth3.Provider{ - Store: oauthStore, - Clock: clockClock, - IdentityConfig: identityConfig, + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, } - anonymousStore := &anonymous.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, } - anonymousProvider := &anonymous.Provider{ - Store: anonymousStore, - Clock: clockClock, + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, } - biometricStore := &biometric.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, } - biometricProvider := &biometric.Provider{ - Store: biometricStore, + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, Clock: clockClock, } - passkeyStore := &passkey.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, } - appredisHandle := appProvider.Redis - store2 := &passkey2.Store{ + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, Redis: appredisHandle, AppID: appID, } - defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) - supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - resolver := &template.Resolver{ - Resources: manager, - DefaultLanguageTag: defaultLanguageTag, - SupportedLanguageTags: supportedLanguageTags, - } - engine := &template.Engine{ - Resolver: resolver, - } - localizationConfig := appConfig.Localization - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) - webAppCDNHost := environmentConfig.WebAppCDNHost - globalEmbeddedResourceManager := rootProvider.EmbeddedResources - staticAssetResolver := &web.StaticAssetResolver{ - Context: contextContext, - Localization: localizationConfig, - HTTPOrigin: httpOrigin, - HTTPProto: httpProto, - WebAppCDNHost: webAppCDNHost, - Resources: manager, - EmbeddedResources: globalEmbeddedResourceManager, - } - translationService := &translation.Service{ - Context: contextContext, - TemplateEngine: engine, - StaticAssets: staticAssetResolver, - } - configService := &passkey2.ConfigService{ - Request: request, - TrustProxy: trustProxy, - TranslationService: translationService, - } - passkeyService := &passkey2.Service{ - Store: store2, - ConfigService: configService, - } - passkeyProvider := &passkey.Provider{ - Store: passkeyStore, - Clock: clockClock, - Passkey: passkeyService, - } - siweStore := &siwe.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, } - remoteIP := deps.ProvideRemoteIP(request, trustProxy) - web3Config := appConfig.Web3 - storeRedis := &siwe2.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, Redis: appredisHandle, AppID: appID, - Clock: clockClock, } - logger := ratelimit.NewLogger(factory) - storageRedis := &ratelimit.StorageRedis{ - AppID: appID, + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + reauthHandler := &webapp.ReauthHandler{ + ControllerFactory: controllerFactory, + } + return reauthHandler +} + +func newWebAppAuthflowReauthHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: handle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ - Logger: logger, + Logger: ratelimitLogger, Storage: storageRedis, Config: rateLimitsFeatureConfig, } @@ -137891,17 +137046,17 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -137927,7 +137082,7 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -138004,92 +137159,6 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { Web3: web3Service, RolesAndGroups: queries, } - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - userAgentString := deps.ProvideUserAgentString(request) - storeRedisLogger := idpsession.NewStoreRedisLogger(factory) - idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: appredisHandle, - AppID: appID, - Clock: clockClock, - Logger: storeRedisLogger, - } - eventStoreRedis := &access.EventStoreRedis{ - Redis: appredisHandle, - AppID: appID, - } - eventProvider := &access.EventProvider{ - Store: eventStoreRedis, - } - sessionConfig := appConfig.Session - idpsessionRand := _wireRandValue - idpsessionProvider := &idpsession.Provider{ - Context: contextContext, - RemoteIP: remoteIP, - UserAgentString: userAgentString, - AppID: appID, - Redis: appredisHandle, - Store: idpsessionStoreRedis, - AccessEvents: eventProvider, - TrustProxy: trustProxy, - Config: sessionConfig, - Clock: clockClock, - Random: idpsessionRand, - } - oAuthConfig := appConfig.OAuth - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, - } - offlineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - samlService := &saml.Service{ - Clock: clockClock, - AppID: appID, - SAMLEnvironmentConfig: samlEnvironmentConfig, - SAMLConfig: samlConfig, - SAMLIdpSigningMaterials: samlIdpSigningMaterials, - SAMLSpSigningMaterials: samlSpSigningMaterials, - Endpoints: endpointsEndpoints, - UserInfoProvider: idTokenIssuer, - IDPSessionProvider: idpsessionProvider, - OfflineGrantSessionProvider: offlineGrantService, - } - samlsessionStoreRedis := &samlsession.StoreRedis{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - } - uiService := &samlsession.UIService{ - Endpoints: endpointsEndpoints, - } - rawCommands := &user.RawCommands{ - Store: store, - Clock: clockClock, - } - eventLogger := event.NewLogger(factory) - sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) - storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) resolverImpl := &event.ResolverImpl{ Users: userQueries, } @@ -138154,11 +137223,11 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) client := elasticsearch.NewClient(elasticsearchCredentials) queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) elasticsearchService := elasticsearch.Service{ Clock: clockClock, Context: contextContext, - Database: handle, + Database: appdbHandle, Logger: elasticsearchServiceLogger, AppID: appID, Client: client, @@ -138172,9 +137241,9 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { elasticsearchSink := &elasticsearch.Sink{ Logger: elasticsearchLogger, Service: elasticsearchService, - Database: handle, + Database: appdbHandle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) userCommands := &user.Commands{ RawCommands: rawCommands, RawQueries: rawQueries, @@ -138191,7 +137260,7 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { Queries: userQueries, } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -138219,7 +137288,7 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { Logger: usageLogger, Clock: clockClock, AppID: appID, - Redis: appredisHandle, + Redis: handle, } messagingConfig := appConfig.Messaging messagingRateLimitsConfig := messagingConfig.RateLimits @@ -138241,7 +137310,7 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { whatsappConfig := messagingConfig.Whatsapp whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) tokenStore := &whatsapp.TokenStore{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -138282,8 +137351,14 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, @@ -138291,7 +137366,43 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { Cookies: cookieManager, CookieDef: cookieDef, } - oauthOfflineGrantService := oauth2.OfflineGrantService{ + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, @@ -138301,7 +137412,7 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { sessionManager := &oauth2.SessionManager{ Store: redisStore, Config: oAuthConfig, - Service: oauthOfflineGrantService, + Service: offlineGrantService, } accountDeletionConfig := appConfig.AccountDeletion accountAnonymizationConfig := appConfig.AccountAnonymization @@ -138335,51 +137446,321 @@ func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { Clock: clockClock, PasswordGenerator: generator, } - userFacade := &facade.UserFacade{ - UserProvider: userProvider, - Coordinator: coordinator, + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, } - loginResultHandler := saml2.LoginResultHandler{ - Clock: clockClock, - Database: handle, - SAMLService: samlService, + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, } - samlBindingHTTPPostWriter := &samlbinding.SAMLBindingHTTPPostWriter{} - loginHandler := &saml2.LoginHandler{ - Logger: loginHandlerLogger, - Clock: clockClock, - Database: handle, - SAMLConfig: samlConfig, - SAMLService: samlService, - SAMLSessionService: samlsessionStoreRedis, - SAMLUIService: uiService, - UserFacade: userFacade, - LoginResultHandler: loginResultHandler, - BindingHTTPPostWriter: samlBindingHTTPPostWriter, + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, } - return loginHandler -} - -func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowNavigator, + ErrorRenderer: errorRenderer, + } + authflowReauthHandler := &webapp.AuthflowReauthHandler{ + Controller: authflowController, + AuthflowNavigator: authflowNavigator, + } + return authflowReauthHandler +} + +func newWebAppAuthflowV2ReauthHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider factory := appProvider.LoggerFactory - loginFinishHandlerLogger := saml2.NewLoginFinishHandlerLogger(factory) - clockClock := _wireSystemClockValue - appContext := appProvider.AppContext - config := appContext.Config - appConfig := config.AppConfig - appID := appConfig.ID + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request rootProvider := appProvider.RootProvider environmentConfig := rootProvider.EnvironmentConfig - samlEnvironmentConfig := environmentConfig.SAML - samlConfig := appConfig.SAML - secretConfig := config.SecretConfig - samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) - samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) - request := p.Request trustProxy := environmentConfig.TrustProxy httpHost := deps.ProvideHTTPHost(request, trustProxy) httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig uiConfig := appConfig.UI globalUIImplementation := environmentConfig.UIImplementation globalUISettingsImplementation := environmentConfig.UISettingsImplementation @@ -138393,24 +137774,46 @@ func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { HTTPProto: httpProto, UIImplementationService: uiImplementationService, } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - contextContext := deps.ProvideRequestContext(request) - handle := appProvider.AppDatabase - sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, AppID: appID, } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } rawQueries := &user.RawQueries{ Store: store, } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) authenticationConfig := appConfig.Authentication identityConfig := appConfig.Identity - featureConfig := config.FeatureConfig identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ SQLBuilder: sqlBuilderApp, @@ -138471,10 +137874,9 @@ func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) @@ -138487,8 +137889,6 @@ func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { engine := &template.Engine{ Resolver: resolver, } - localizationConfig := appConfig.Localization - httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources staticAssetResolver := &web.StaticAssetResolver{ @@ -138523,22 +137923,21 @@ func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - remoteIP := deps.ProvideRemoteIP(request, trustProxy) web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } - logger := ratelimit.NewLogger(factory) + ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ - Logger: logger, + Logger: ratelimitLogger, Storage: storageRedis, Config: rateLimitsFeatureConfig, } @@ -138649,17 +138048,17 @@ func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { testModeConfig := appConfig.TestMode testModeFeatureConfig := featureConfig.TestMode codeStoreRedis := &otp.CodeStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } lookupStoreRedis := &otp.LookupStoreRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } attemptTrackerRedis := &otp.AttemptTrackerRedis{ - Redis: appredisHandle, + Redis: handle, AppID: appID, Clock: clockClock, } @@ -138685,7 +138084,7 @@ func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { lockoutLogger := lockout.NewLogger(factory) lockoutStorageRedis := &lockout.StorageRedis{ AppID: appID, - Redis: appredisHandle, + Redis: handle, } lockoutService := &lockout.Service{ Logger: lockoutLogger, @@ -138762,64 +138161,12676 @@ func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { Web3: web3Service, RolesAndGroups: queries, } - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, + resolverImpl := &event.ResolverImpl{ + Users: userQueries, } - userAgentString := deps.ProvideUserAgentString(request) - storeRedisLogger := idpsession.NewStoreRedisLogger(factory) - idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: appredisHandle, - AppID: appID, - Clock: clockClock, - Logger: storeRedisLogger, + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, } - eventStoreRedis := &access.EventStoreRedis{ - Redis: appredisHandle, - AppID: appID, + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, } - eventProvider := &access.EventProvider{ - Store: eventStoreRedis, + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, } - sessionConfig := appConfig.Session - idpsessionRand := _wireRandValue - idpsessionProvider := &idpsession.Provider{ + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, Context: contextContext, - RemoteIP: remoteIP, - UserAgentString: userAgentString, + Database: appdbHandle, + Logger: elasticsearchServiceLogger, AppID: appID, - Redis: appredisHandle, - Store: idpsessionStoreRedis, - AccessEvents: eventProvider, - TrustProxy: trustProxy, - Config: sessionConfig, - Clock: clockClock, - Random: idpsessionRand, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, } - oAuthConfig := appConfig.OAuth - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: appdbHandle, } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, - Clock: clockClock, } - offlineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: handle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, + } + authflowV2ReauthHandler := &authflowv2.AuthflowV2ReauthHandler{ + Controller: authflowController, + AuthflowNavigator: authflowV2Navigator, + } + return authflowV2ReauthHandler +} + +func newWebAppAuthflowResetPasswordHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: handle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: handle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: appdbHandle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: handle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowNavigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowResetPasswordHandler := &webapp.AuthflowResetPasswordHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowResetPasswordHandler +} + +func newWebAppAuthflowV2ResetPasswordHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef2, + MFADeviceTokenCookie: cookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: store, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: appredisHandle, + AppID: appID, + Context: contextContext, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: handle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: resolver, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: resolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, + } + authflowV2ResetPasswordHandler := &authflowv2.AuthflowV2ResetPasswordHandler{ + NonAuthflowControllerFactory: controllerFactory, + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + AdminAPIResetPasswordPolicy: passwordChecker, + ResetPassword: forgotpasswordService, + Database: handle, + } + return authflowV2ResetPasswordHandler +} + +func newWebAppAuthflowResetPasswordSuccessHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: handle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: handle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: appdbHandle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: handle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowNavigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowResetPasswordSuccessHandler := &webapp.AuthflowResetPasswordSuccessHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowResetPasswordSuccessHandler +} + +func newWebAppAuthflowV2ResetPasswordSuccessHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: handle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: handle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: appdbHandle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: handle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2ResetPasswordSuccessHandler := &authflowv2.AuthflowV2ResetPasswordSuccessHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2ResetPasswordSuccessHandler +} + +func newWebAppAuthflowAccountStatusHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + featureConfig := config.FeatureConfig + uiFeatureConfig := featureConfig.UI + request := p.Request + contextContext := deps.ProvideRequestContext(request) + localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + manager := appContext.Resources + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + forgotPasswordConfig := appConfig.ForgotPassword + authenticationConfig := appConfig.Authentication + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + appID := appConfig.ID + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + handle := appProvider.Redis + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + clockClock := _wireSystemClockValue + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + factory := appProvider.LoggerFactory + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowAccountStatusHandler := &webapp.AuthflowAccountStatusHandler{ + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowAccountStatusHandler +} + +func newWebAppAuthflowV2AccountStatusHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + featureConfig := config.FeatureConfig + uiFeatureConfig := featureConfig.UI + request := p.Request + contextContext := deps.ProvideRequestContext(request) + localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + manager := appContext.Resources + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + forgotPasswordConfig := appConfig.ForgotPassword + authenticationConfig := appConfig.Authentication + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + appID := appConfig.ID + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + handle := appProvider.Redis + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + clockClock := _wireSystemClockValue + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + factory := appProvider.LoggerFactory + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2AccountStatusHandler := &authflowv2.AuthflowV2AccountStatusHandler{ + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2AccountStatusHandler +} + +func newWebAppAuthflowNoAuthenticatorHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + featureConfig := config.FeatureConfig + uiFeatureConfig := featureConfig.UI + request := p.Request + contextContext := deps.ProvideRequestContext(request) + localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + manager := appContext.Resources + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + forgotPasswordConfig := appConfig.ForgotPassword + authenticationConfig := appConfig.Authentication + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + appID := appConfig.ID + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + handle := appProvider.Redis + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + clockClock := _wireSystemClockValue + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + factory := appProvider.LoggerFactory + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowNoAuthenticatorHandler := &webapp.AuthflowNoAuthenticatorHandler{ + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowNoAuthenticatorHandler +} + +func newWebAppAuthflowFinishFlowHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: handle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: handle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: appdbHandle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: handle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowNavigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowFinishFlowHandler := &webapp.AuthflowFinishFlowHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowFinishFlowHandler +} + +func newWebAppAuthflowV2FinishFlowHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: handle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: handle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: appdbHandle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: handle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2FinishFlowHandler := &authflowv2.AuthflowV2FinishFlowHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2FinishFlowHandler +} + +func newWebAppAuthflowV2AccountLinkingHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: handle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: handle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: appdbHandle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: handle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2AccountLinkingHandler := &authflowv2.AuthflowV2AccountLinkingHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Endpoints: endpointsEndpoints, + } + return authflowV2AccountLinkingHandler +} + +func newWebAppAuthflowV2NoAuthenticatorHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + featureConfig := config.FeatureConfig + uiFeatureConfig := featureConfig.UI + request := p.Request + contextContext := deps.ProvideRequestContext(request) + localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + manager := appContext.Resources + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + forgotPasswordConfig := appConfig.ForgotPassword + authenticationConfig := appConfig.Authentication + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + appID := appConfig.ID + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + handle := appProvider.Redis + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + clockClock := _wireSystemClockValue + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + factory := appProvider.LoggerFactory + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2NoAuthenticatorHandler := &authflowv2.AuthflowV2NoAuthenticatorHandler{ + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2NoAuthenticatorHandler +} + +func newWebAppAuthflowV2WechatHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: handle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: handle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: appdbHandle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: handle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2WechatHandler := &authflowv2.AuthflowV2WechatHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + OAuthStateStore: webappoauthStore, + } + return authflowV2WechatHandler +} + +func newWebAppAuthflowV2LDAPLoginHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + authflowControllerLogger := webapp.NewAuthflowControllerLogger(factory) + request := p.Request + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + clockClock := _wireSystemClockValue + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + appID := appConfig.ID + handle := appProvider.Redis + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: handle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + contextContext := deps.ProvideRequestContext(request) + featureConfig := config.FeatureConfig + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + appdbHandle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, appdbHandle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + userAgentString := deps.ProvideUserAgentString(request) + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: handle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: handle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(handle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: appdbHandle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: appdbHandle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, appdbHandle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: handle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: handle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: handle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: handle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + Clock: clockClock, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + customattrsService := &customattrs.Service{ + Config: userProfileConfig, + ServiceNoEvent: customattrsServiceNoEvent, + Events: eventService, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + workflowVerificationFacade := facade.WorkflowVerificationFacade{ + Verification: verificationService, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + accountMigrationConfig := appConfig.AccountMigration + accountMigrationHookConfig := accountMigrationConfig.Hook + hookDenoClient := accountmigration.NewHookDenoClient(denoEndpoint, hookLogger, accountMigrationHookConfig) + denoMiddlewareLogger := accountmigration.NewDenoMiddlewareLogger(factory) + accountMigrationDenoHook := &accountmigration.AccountMigrationDenoHook{ + DenoHook: denoHook, + Client: hookDenoClient, + Logger: denoMiddlewareLogger, + } + hookWebHookImpl := &hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + hookHTTPClient := accountmigration.NewHookHTTPClient(accountMigrationHookConfig) + webhookMiddlewareLogger := accountmigration.NewWebhookMiddlewareLogger(factory) + accountMigrationWebHook := &accountmigration.AccountMigrationWebHook{ + WebHook: hookWebHookImpl, + Client: hookHTTPClient, + Logger: webhookMiddlewareLogger, + } + accountmigrationService := &accountmigration.Service{ + Config: accountMigrationHookConfig, + DenoHook: accountMigrationDenoHook, + WebHook: accountMigrationWebHook, + } + challengeProvider := &challenge.Provider{ + Redis: handle, + AppID: appID, + Clock: clockClock, + } + captchaConfig := appConfig.Captcha + providerLogger := captcha.NewProviderLogger(factory) + deprecated_CaptchaCloudflareCredentials := deps.ProvideCaptchaCloudflareCredentials(secretConfig) + cloudflareClient := captcha2.NewCloudflareClient(deprecated_CaptchaCloudflareCredentials) + captchaProvider := &captcha.Provider{ + RemoteIP: remoteIP, + Config: captchaConfig, + Logger: providerLogger, + CloudflareClient: cloudflareClient, + } + botProtectionConfig := appConfig.BotProtection + botprotectionProviderLogger := botprotection.NewProviderLogger(factory) + botProtectionProviderCredentials := deps.ProvideBotProtectionProvidersCredentials(secretConfig) + botprotectionCloudflareClient := botprotection.NewCloudflareClient(botProtectionProviderCredentials, environmentConfig) + recaptchaV2Client := botprotection.NewRecaptchaV2Client(botProtectionProviderCredentials, environmentConfig) + botprotectionProvider := &botprotection.Provider{ + RemoteIP: remoteIP, + Config: botProtectionConfig, + Logger: botprotectionProviderLogger, + CloudflareClient: botprotectionCloudflareClient, + RecaptchaV2Client: recaptchaV2Client, + Events: eventService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: handle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + requestOptionsService := &passkey2.RequestOptionsService{ + ConfigService: configService, + IdentityService: serviceService, + Store: store2, + } + creationOptionsService := &passkey2.CreationOptionsService{ + ConfigService: configService, + UserService: userQueries, + IdentityService: serviceService, + Store: store2, + } + ldapConfig := identityConfig.LDAP + ldapServerUserCredentials := deps.ProvideLDAPServerUserCredentials(secretConfig) + clientFactory := &ldap2.ClientFactory{ + Config: ldapConfig, + SecretConfig: ldapServerUserCredentials, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + dependencies := &authenticationflow.Dependencies{ + Config: appConfig, + FeatureConfig: featureConfig, + Clock: clockClock, + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + HTTPRequest: request, + Users: userProvider, + Identities: identityFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + Authenticators: authenticatorFacade, + MFA: mfaFacade, + StdAttrsService: stdattrsService, + CustomAttrsService: customattrsService, + OTPCodes: otpService, + OTPSender: messageSender, + Verification: workflowVerificationFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + AccountMigrations: accountmigrationService, + Challenges: challengeProvider, + Captcha: captchaProvider, + BotProtection: botprotectionProvider, + OAuthProviderFactory: oAuthProviderFactory, + PasskeyRequestOptionsService: requestOptionsService, + PasskeyCreationOptionsService: creationOptionsService, + PasskeyService: passkeyService, + LoginIDs: provider, + LDAP: ldapProvider, + LDAPClientFactory: clientFactory, + IDPSessions: idpsessionProvider, + Sessions: manager2, + AuthenticationInfos: authenticationinfoStoreRedis, + SessionCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, + UserFacade: userFacade, + Cookies: cookieManager, + Events: eventService, + RateLimiter: limiter, + OfflineGrants: redisStore, + IDTokens: idTokenIssuer, + } + authenticationflowServiceLogger := authenticationflow.NewServiceLogger(factory) + authenticationflowStoreImpl := &authenticationflow.StoreImpl{ + Redis: handle, + AppID: appID, + Context: contextContext, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationflowService := &authenticationflow.Service{ + ContextDoNotUseDirectly: contextContext, + Deps: dependencies, + Logger: authenticationflowServiceLogger, + Store: authenticationflowStoreImpl, + Database: appdbHandle, + UIConfig: uiConfig, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + promptResolver := &oauth2.PromptResolver{ + Clock: clockClock, + } + oauthOfflineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + idTokenHintResolver := &oidc.IDTokenHintResolver{ + Issuer: idTokenIssuer, + Sessions: idpsessionProvider, + OfflineGrantService: oauthOfflineGrantService, + } + uiInfoResolver := &oidc.UIInfoResolver{ + Config: oAuthConfig, + EndpointsProvider: endpointsEndpoints, + PromptResolver: promptResolver, + IDTokenHintResolver: idTokenHintResolver, + Clock: clockClock, + Cookies: cookieManager, + ClientResolver: oauthclientResolver, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: handle, + AppID: appID, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: handle, + Cookies: cookieManager, + } + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + authflowController := &webapp.AuthflowController{ + Logger: authflowControllerLogger, + TesterEndpointsProvider: endpointsEndpoints, + TrustProxy: trustProxy, + Clock: clockClock, + Cookies: cookieManager, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + Authflows: authenticationflowService, + OAuthSessions: oauthsessionStoreRedis, + SAMLSessions: samlsessionStoreRedis, + UIInfoResolver: uiInfoResolver, + UIConfig: uiConfig, + OAuthClientResolver: oauthclientResolver, + Navigator: authflowV2Navigator, + ErrorRenderer: errorRenderer, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + authflowV2LDAPLoginHandler := &authflowv2.AuthflowV2LDAPLoginHandler{ + Controller: authflowController, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2LDAPLoginHandler +} + +func newSAMLMetadataHandler(p *deps.RequestProvider) http.Handler { + clockClock := _wireSystemClockValue + appProvider := p.AppProvider + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + samlEnvironmentConfig := environmentConfig.SAML + samlConfig := appConfig.SAML + secretConfig := config.SecretConfig + samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) + samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) + request := p.Request + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + contextContext := deps.ProvideRequestContext(request) + handle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: store, + } + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + localizationConfig := appConfig.Localization + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + factory := appProvider.LoggerFactory + logger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: logger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + sessionConfig := appConfig.Session + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oAuthConfig := appConfig.OAuth + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + offlineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + samlService := &saml.Service{ + Clock: clockClock, + AppID: appID, + SAMLEnvironmentConfig: samlEnvironmentConfig, + SAMLConfig: samlConfig, + SAMLIdpSigningMaterials: samlIdpSigningMaterials, + SAMLSpSigningMaterials: samlSpSigningMaterials, + Endpoints: endpointsEndpoints, + UserInfoProvider: idTokenIssuer, + IDPSessionProvider: idpsessionProvider, + OfflineGrantSessionProvider: offlineGrantService, + } + metadataHandler := &saml2.MetadataHandler{ + SAMLService: samlService, + } + return metadataHandler +} + +func newSAMLLoginHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + loginHandlerLogger := saml2.NewLoginHandlerLogger(factory) + clockClock := _wireSystemClockValue + handle := appProvider.AppDatabase + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + samlConfig := appConfig.SAML + appID := appConfig.ID + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + samlEnvironmentConfig := environmentConfig.SAML + secretConfig := config.SecretConfig + samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) + samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) + request := p.Request + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: store, + } + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + localizationConfig := appConfig.Localization + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + logger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: logger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + sessionConfig := appConfig.Session + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oAuthConfig := appConfig.OAuth + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + offlineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + samlService := &saml.Service{ + Clock: clockClock, + AppID: appID, + SAMLEnvironmentConfig: samlEnvironmentConfig, + SAMLConfig: samlConfig, + SAMLIdpSigningMaterials: samlIdpSigningMaterials, + SAMLSpSigningMaterials: samlSpSigningMaterials, + Endpoints: endpointsEndpoints, + UserInfoProvider: idTokenIssuer, + IDPSessionProvider: idpsessionProvider, + OfflineGrantSessionProvider: offlineGrantService, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + uiService := &samlsession.UIService{ + Endpoints: endpointsEndpoints, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + eventLogger := event.NewLogger(factory) + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + oauthOfflineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: oauthOfflineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + loginResultHandler := saml2.LoginResultHandler{ + Clock: clockClock, + Database: handle, + SAMLService: samlService, + } + samlBindingHTTPPostWriter := &samlbinding.SAMLBindingHTTPPostWriter{} + loginHandler := &saml2.LoginHandler{ + Logger: loginHandlerLogger, + Clock: clockClock, + Database: handle, + SAMLConfig: samlConfig, + SAMLService: samlService, + SAMLSessionService: samlsessionStoreRedis, + SAMLUIService: uiService, + UserFacade: userFacade, + LoginResultHandler: loginResultHandler, + BindingHTTPPostWriter: samlBindingHTTPPostWriter, + } + return loginHandler +} + +func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + loginFinishHandlerLogger := saml2.NewLoginFinishHandlerLogger(factory) + clockClock := _wireSystemClockValue + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + samlEnvironmentConfig := environmentConfig.SAML + samlConfig := appConfig.SAML + secretConfig := config.SecretConfig + samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) + samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) + request := p.Request + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + contextContext := deps.ProvideRequestContext(request) + handle := appProvider.AppDatabase + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: store, + } + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + localizationConfig := appConfig.Localization + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + logger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: logger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + sessionConfig := appConfig.Session + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oAuthConfig := appConfig.OAuth + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + offlineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + samlService := &saml.Service{ + Clock: clockClock, + AppID: appID, + SAMLEnvironmentConfig: samlEnvironmentConfig, + SAMLConfig: samlConfig, + SAMLIdpSigningMaterials: samlIdpSigningMaterials, + SAMLSpSigningMaterials: samlSpSigningMaterials, + Endpoints: endpointsEndpoints, + UserInfoProvider: idTokenIssuer, + IDPSessionProvider: idpsessionProvider, + OfflineGrantSessionProvider: offlineGrantService, + } + samlsessionStoreRedis := &samlsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + loginResultHandler := saml2.LoginResultHandler{ + Clock: clockClock, + Database: handle, + SAMLService: samlService, + } + samlBindingHTTPPostWriter := &samlbinding.SAMLBindingHTTPPostWriter{} + loginFinishHandler := &saml2.LoginFinishHandler{ + Logger: loginFinishHandlerLogger, + Clock: clockClock, + SAMLService: samlService, + SAMLSessionService: samlsessionStoreRedis, + AuthenticationInfoResolver: uiService, + AuthenticationInfoService: authenticationinfoStoreRedis, + LoginResultHandler: loginResultHandler, + BindingHTTPPostWriter: samlBindingHTTPPostWriter, + } + return loginFinishHandler +} + +func newSAMLLogoutHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + logoutHandlerLogger := saml2.NewLogoutHandlerLogger(factory) + clockClock := _wireSystemClockValue + handle := appProvider.AppDatabase + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + samlConfig := appConfig.SAML + appID := appConfig.ID + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + samlEnvironmentConfig := environmentConfig.SAML + secretConfig := config.SecretConfig + samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) + samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) + request := p.Request + trustProxy := environmentConfig.TrustProxy + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + uiConfig := appConfig.UI + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: store, + } + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + localizationConfig := appConfig.Localization + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + logger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: logger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + idTokenIssuer := &oidc.IDTokenIssuer{ + Secrets: oAuthKeyMaterials, + BaseURL: endpointsEndpoints, + Users: userQueries, + RolesAndGroups: queries, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + sessionConfig := appConfig.Session + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + oAuthConfig := appConfig.OAuth + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + offlineGrantService := &oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, } samlService := &saml.Service{ Clock: clockClock, @@ -138833,7 +150844,14289 @@ func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { IDPSessionProvider: idpsessionProvider, OfflineGrantSessionProvider: offlineGrantService, } - samlsessionStoreRedis := &samlsession.StoreRedis{ + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + oauthOfflineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: oauthOfflineGrantService, + } + eventLogger := event.NewLogger(factory) + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + samlslosessionStoreRedis := &samlslosession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + samlBindingHTTPPostWriter := &samlbinding.SAMLBindingHTTPPostWriter{} + samlBindingHTTPRedirectWriter := &samlbinding.SAMLBindingHTTPRedirectWriter{ + Signer: samlService, + } + sloService := &saml.SLOService{ + SAMLService: samlService, + BindingHTTPPostWriter: samlBindingHTTPPostWriter, + BindingHTTPRedirectWriter: samlBindingHTTPRedirectWriter, + } + logoutHandler := &saml2.LogoutHandler{ + Logger: logoutHandlerLogger, + Clock: clockClock, + Database: handle, + SAMLConfig: samlConfig, + SAMLService: samlService, + SessionManager: manager2, + SAMLSLOSessionService: samlslosessionStoreRedis, + SAMLSLOService: sloService, + Endpoints: endpointsEndpoints, + BindingHTTPPostWriter: samlBindingHTTPPostWriter, + BindingHTTPRedirectWriter: samlBindingHTTPRedirectWriter, + } + return logoutHandler +} + +func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + settingsProfileViewModeler := &viewmodels.SettingsProfileViewModeler{ + Localization: localizationConfig, + UserProfileConfig: userProfileConfig, + Users: userQueries, + Identities: facadeIdentityFacade, + Clock: clockClock, + } + authflowV2SettingsProfileHandler := &authflowv2.AuthflowV2SettingsProfileHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + SettingsProfileViewModel: settingsProfileViewModeler, + Renderer: responseRenderer, + } + return authflowV2SettingsProfileHandler +} + +func newWebAppAuthflowV2SettingsIdentityAddEmailHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsIdentityAddEmailHandler := &authflowv2.AuthflowV2SettingsIdentityAddEmailHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + AccountManagement: accountmanagementService, + } + return authflowV2SettingsIdentityAddEmailHandler +} + +func newWebAppAuthflowV2SettingsIdentityEditEmailHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsIdentityEditEmailHandler := &authflowv2.AuthflowV2SettingsIdentityEditEmailHandler{ + Database: handle, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + AccountManagement: accountmanagementService, + Identities: serviceService, + } + return authflowV2SettingsIdentityEditEmailHandler +} + +func newWebAppAuthflowV2SettingsIdentityListEmailHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + identityConfig := appConfig.Identity + loginIDConfig := identityConfig.LoginID + authenticationConfig := appConfig.Authentication + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + request := p.Request + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + store := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + uiConfig := appConfig.UI + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + clockClock := _wireSystemClockValue + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + factory := appProvider.LoggerFactory + logger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: logger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: store, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + serviceLogger := webapp2.NewServiceLogger(factory) + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + interactionLogger := interaction.NewLogger(factory) + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + serviceStore := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store3 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store3, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: serviceStore, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: interactionLogger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + settingsProfileViewModeler := &viewmodels.SettingsProfileViewModeler{ + Localization: localizationConfig, + UserProfileConfig: userProfileConfig, + Users: userQueries, + Identities: facadeIdentityFacade, + Clock: clockClock, + } + authflowV2SettingsIdentityListEmailHandler := &authflowv2.AuthflowV2SettingsIdentityListEmailHandler{ + Database: handle, + LoginIDConfig: loginIDConfig, + Identities: serviceService, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Verification: verificationService, + SettingsProfileViewModel: settingsProfileViewModeler, + Renderer: responseRenderer, + } + return authflowV2SettingsIdentityListEmailHandler +} + +func newWebAppAuthflowV2SettingsIdentityVerifyEmailHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsIdentityVerifyEmailHandler := &authflowv2.AuthflowV2SettingsIdentityVerifyEmailHandler{ + Database: handle, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + OTPCodeService: otpService, + Renderer: responseRenderer, + AccountManagement: accountmanagementService, + Clock: clockClock, + Config: appConfig, + AuthenticatorConfig: authenticatorConfig, + } + return authflowV2SettingsIdentityVerifyEmailHandler +} + +func newWebAppAuthflowV2SettingsIdentityViewEmailHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + identityConfig := appConfig.Identity + loginIDConfig := identityConfig.LoginID + authenticationConfig := appConfig.Authentication + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + request := p.Request + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + store := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + uiConfig := appConfig.UI + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + clockClock := _wireSystemClockValue + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + factory := appProvider.LoggerFactory + logger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: logger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: store, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + serviceLogger := webapp2.NewServiceLogger(factory) + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + interactionLogger := interaction.NewLogger(factory) + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + serviceStore := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store3 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store3, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: serviceStore, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: interactionLogger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + service4 := verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + accountmanagementRedisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: accountmanagementRedisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsIdentityViewEmailHandler := &authflowv2.AuthflowV2SettingsIdentityViewEmailHandler{ + Database: handle, + LoginIDConfig: loginIDConfig, + Identities: serviceService, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Verification: service4, + Renderer: responseRenderer, + AccountManagement: accountmanagementService, + } + return authflowV2SettingsIdentityViewEmailHandler +} + +func newWebAppAuthflowV2SettingsIdentityChangePrimaryEmailHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + settingsProfileViewModeler := &viewmodels.SettingsProfileViewModeler{ + Localization: localizationConfig, + UserProfileConfig: userProfileConfig, + Users: userQueries, + Identities: facadeIdentityFacade, + Clock: clockClock, + } + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + authflowV2SettingsIdentityChangePrimaryEmailHandler := &authflowv2.AuthflowV2SettingsIdentityChangePrimaryEmailHandler{ + Database: handle, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + SettingsProfileViewModel: settingsProfileViewModeler, + Renderer: responseRenderer, + Users: userFacade, + StdAttrs: stdattrsService, + Identities: serviceService, + } + return authflowV2SettingsIdentityChangePrimaryEmailHandler +} + +func newWebAppAuthflowV2SettingsIdentityAddPhoneHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + factory := appProvider.LoggerFactory + handle := appProvider.AppDatabase + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsIdentityAddPhoneHandler := &authflowv2.AuthflowV2SettingsIdentityAddPhoneHandler{ + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + AuthenticatorConfig: authenticatorConfig, + AccountManagement: accountmanagementService, + } + return authflowV2SettingsIdentityAddPhoneHandler +} + +func newWebAppAuthflowV2SettingsIdentityEditPhoneHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsIdentityEditPhoneHandler := &authflowv2.AuthflowV2SettingsIdentityEditPhoneHandler{ + Database: handle, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + AuthenticatorConfig: authenticatorConfig, + AccountManagement: accountmanagementService, + Identities: serviceService, + } + return authflowV2SettingsIdentityEditPhoneHandler +} + +func newWebAppAuthflowV2SettingsIdentityListPhoneHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + identityConfig := appConfig.Identity + loginIDConfig := identityConfig.LoginID + authenticationConfig := appConfig.Authentication + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + request := p.Request + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + store := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + uiConfig := appConfig.UI + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + clockClock := _wireSystemClockValue + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + factory := appProvider.LoggerFactory + logger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: logger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: store, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + serviceLogger := webapp2.NewServiceLogger(factory) + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + interactionLogger := interaction.NewLogger(factory) + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + serviceStore := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store3 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store3, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: serviceStore, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: interactionLogger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + settingsProfileViewModeler := &viewmodels.SettingsProfileViewModeler{ + Localization: localizationConfig, + UserProfileConfig: userProfileConfig, + Users: userQueries, + Identities: facadeIdentityFacade, + Clock: clockClock, + } + authflowV2SettingsIdentityListPhoneHandler := &authflowv2.AuthflowV2SettingsIdentityListPhoneHandler{ + Database: handle, + LoginIDConfig: loginIDConfig, + Identities: serviceService, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Verification: verificationService, + SettingsProfileViewModel: settingsProfileViewModeler, + Renderer: responseRenderer, + } + return authflowV2SettingsIdentityListPhoneHandler +} + +func newWebAppAuthflowV2SettingsIdentityViewPhoneHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + identityConfig := appConfig.Identity + loginIDConfig := identityConfig.LoginID + authenticationConfig := appConfig.Authentication + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + request := p.Request + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + store := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + uiConfig := appConfig.UI + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + clockClock := _wireSystemClockValue + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + factory := appProvider.LoggerFactory + logger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: logger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: store, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + serviceLogger := webapp2.NewServiceLogger(factory) + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + interactionLogger := interaction.NewLogger(factory) + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + serviceStore := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store3 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store3, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: serviceStore, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: interactionLogger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + accountmanagementRedisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: accountmanagementRedisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsIdentityViewPhoneHandler := &authflowv2.AuthflowV2SettingsIdentityViewPhoneHandler{ + Database: handle, + LoginIDConfig: loginIDConfig, + Identities: serviceService, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Verification: verificationService, + Renderer: responseRenderer, + AuthenticatorConfig: authenticatorConfig, + AccountManagement: accountmanagementService, + } + return authflowV2SettingsIdentityViewPhoneHandler +} + +func newWebAppAuthflowV2SettingsIdentityChangePrimaryPhoneHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + settingsProfileViewModeler := &viewmodels.SettingsProfileViewModeler{ + Localization: localizationConfig, + UserProfileConfig: userProfileConfig, + Users: userQueries, + Identities: facadeIdentityFacade, + Clock: clockClock, + } + userFacade := &facade.UserFacade{ + UserProvider: userProvider, + Coordinator: coordinator, + } + authflowV2SettingsIdentityChangePrimaryPhoneHandler := &authflowv2.AuthflowV2SettingsIdentityChangePrimaryPhoneHandler{ + Database: handle, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + SettingsProfileViewModel: settingsProfileViewModeler, + Renderer: responseRenderer, + Users: userFacade, + StdAttrs: stdattrsService, + Identities: serviceService, + } + return authflowV2SettingsIdentityChangePrimaryPhoneHandler +} + +func newWebAppAuthflowV2SettingsIdentityVerifyPhoneHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + factory := appProvider.LoggerFactory + appredisHandle := appProvider.Redis + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + appID := appConfig.ID + serviceLogger := webapp2.NewServiceLogger(factory) + request := p.Request + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + authenticationConfig := appConfig.Authentication + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + uiConfig := appConfig.UI + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpProto := deps.ProvideHTTPProto(request, trustProxy) + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + resolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + logger := interaction.NewLogger(factory) + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + featureConfig := config.FeatureConfig + redisLogger := redis.NewLogger(factory) + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + store := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + identityConfig := appConfig.Identity + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + templateResolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: templateResolver, + } + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: resolver, + OfflineGrants: store, + } + sessionManager := &oauth2.SessionManager{ + Store: store, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: resolver, + OfflineGrants: store, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: logger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: resolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: resolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + facadeIdentityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + accountmanagementService := accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: facadeIdentityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + authflowV2SettingsIdentityVerifyPhoneHandler := &authflowv2.AuthflowV2SettingsIdentityVerifyPhoneHandler{ + Database: handle, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + OTPCodeService: otpService, + Renderer: responseRenderer, + AccountManagement: accountmanagementService, + Clock: clockClock, + Config: appConfig, + AuthenticatorConfig: authenticatorConfig, + } + return authflowV2SettingsIdentityVerifyPhoneHandler +} + +func newWebAppAuthflowV2SettingsIdentityListUsernameHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + identityConfig := appConfig.Identity + loginIDConfig := identityConfig.LoginID + authenticationConfig := appConfig.Authentication + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + request := p.Request + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + store := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + uiConfig := appConfig.UI + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + clockClock := _wireSystemClockValue + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + factory := appProvider.LoggerFactory + logger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: logger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: store, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + serviceLogger := webapp2.NewServiceLogger(factory) + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + oAuthConfig := appConfig.OAuth + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + interactionLogger := interaction.NewLogger(factory) + redisLogger := redis.NewLogger(factory) + redisStore := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + userAgentString := deps.ProvideUserAgentString(request) + eventLogger := event.NewLogger(factory) + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + userStore := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawQueries := &user.RawQueries{ + Store: userStore, + } + serviceStore := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store3 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store3, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: serviceStore, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: userStore, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: userStore, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: userStore, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: whatsappServiceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + rawCommands := &user.RawCommands{ + Store: userStore, + Clock: clockClock, + } + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: userStore, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + cookieDef2 := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef2, + } + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + } + sessionManager := &oauth2.SessionManager{ + Store: redisStore, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: oauthclientResolver, + OfflineGrants: redisStore, + Identities: identityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef2, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: cookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: interactionLogger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: serviceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: cookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + authflowV2SettingsIdentityListUsernameHandler := &authflowv2.AuthflowV2SettingsIdentityListUsernameHandler{ + Database: handle, + LoginIDConfig: loginIDConfig, + Identities: serviceService, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2SettingsIdentityListUsernameHandler +} + +func newWebAppAuthflowV2SettingsIdentityNewUsernameHandler(p *deps.RequestProvider) http.Handler { + appProvider := p.AppProvider + handle := appProvider.AppDatabase + appContext := appProvider.AppContext + config := appContext.Config + appConfig := config.AppConfig + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + request := p.Request + contextContext := deps.ProvideRequestContext(request) + sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue + store := &user.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, + } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + userAgentString := deps.ProvideUserAgentString(request) + factory := appProvider.LoggerFactory + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) + authenticationConfig := appConfig.Authentication + identityConfig := appConfig.Identity + featureConfig := config.FeatureConfig + identityFeatureConfig := featureConfig.Identity + serviceStore := &service.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginidStore := &loginid.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI + manager := appContext.Resources + typeCheckerFactory := &loginid.TypeCheckerFactory{ + UIConfig: uiConfig, + LoginIDConfig: loginIDConfig, + Resources: manager, + } + checker := &loginid.Checker{ + Config: loginIDConfig, + TypeCheckerFactory: typeCheckerFactory, + } + normalizerFactory := &loginid.NormalizerFactory{ + Config: loginIDConfig, + } + provider := &loginid.Provider{ + Store: loginidStore, + Config: loginIDConfig, + Checker: checker, + NormalizerFactory: normalizerFactory, + Clock: clockClock, + } + oauthStore := &oauth3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + IdentityConfig: identityConfig, + } + oauthProvider := &oauth3.Provider{ + Store: oauthStore, + Clock: clockClock, + IdentityConfig: identityConfig, + } + anonymousStore := &anonymous.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + anonymousProvider := &anonymous.Provider{ + Store: anonymousStore, + Clock: clockClock, + } + biometricStore := &biometric.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + biometricProvider := &biometric.Provider{ + Store: biometricStore, + Clock: clockClock, + } + passkeyStore := &passkey.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + appredisHandle := appProvider.Redis + store2 := &passkey2.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) + supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) + resolver := &template.Resolver{ + Resources: manager, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + } + engine := &template.Engine{ + Resolver: resolver, + } + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) + httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) + webAppCDNHost := environmentConfig.WebAppCDNHost + globalEmbeddedResourceManager := rootProvider.EmbeddedResources + staticAssetResolver := &web.StaticAssetResolver{ + Context: contextContext, + Localization: localizationConfig, + HTTPOrigin: httpOrigin, + HTTPProto: httpProto, + WebAppCDNHost: webAppCDNHost, + Resources: manager, + EmbeddedResources: globalEmbeddedResourceManager, + } + translationService := &translation.Service{ + Context: contextContext, + TemplateEngine: engine, + StaticAssets: staticAssetResolver, + } + configService := &passkey2.ConfigService{ + Request: request, + TrustProxy: trustProxy, + TranslationService: translationService, + } + passkeyService := &passkey2.Service{ + Store: store2, + ConfigService: configService, + } + passkeyProvider := &passkey.Provider{ + Store: passkeyStore, + Clock: clockClock, + Passkey: passkeyService, + } + siweStore := &siwe.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + web3Config := appConfig.Web3 + storeRedis := &siwe2.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + ratelimitLogger := ratelimit.NewLogger(factory) + storageRedis := &ratelimit.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + rateLimitsFeatureConfig := featureConfig.RateLimits + limiter := &ratelimit.Limiter{ + Logger: ratelimitLogger, + Storage: storageRedis, + Config: rateLimitsFeatureConfig, + } + siweLogger := siwe2.NewLogger(factory) + siweService := &siwe2.Service{ + RemoteIP: remoteIP, + HTTPOrigin: httpOrigin, + Web3Config: web3Config, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + NonceStore: storeRedis, + RateLimiter: limiter, + Logger: siweLogger, + } + siweProvider := &siwe.Provider{ + Store: siweStore, + Clock: clockClock, + SIWE: siweService, + } + ldapStore := &ldap.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + normalizer := &stdattrs.Normalizer{ + LoginIDNormalizerFactory: normalizerFactory, + } + ldapProvider := &ldap.Provider{ + Store: ldapStore, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + } + serviceService := &service.Service{ + Authentication: authenticationConfig, + Identity: identityConfig, + IdentityFeatureConfig: identityFeatureConfig, + Store: serviceStore, + LoginID: provider, + OAuth: oauthProvider, + Anonymous: anonymousProvider, + Biometric: biometricProvider, + Passkey: passkeyProvider, + SIWE: siweProvider, + LDAP: ldapProvider, + } + store3 := &service2.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + passwordStore := &password.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorConfig := appConfig.Authenticator + authenticatorPasswordConfig := authenticatorConfig.Password + passwordLogger := password.NewLogger(factory) + historyStore := &password.HistoryStore{ + Clock: clockClock, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorFeatureConfig := featureConfig.Authenticator + passwordChecker := password.ProvideChecker(authenticatorPasswordConfig, authenticatorFeatureConfig, historyStore) + expiry := password.ProvideExpiry(authenticatorPasswordConfig, clockClock) + housekeeperLogger := password.NewHousekeeperLogger(factory) + housekeeper := &password.Housekeeper{ + Store: historyStore, + Logger: housekeeperLogger, + Config: authenticatorPasswordConfig, + } + passwordProvider := &password.Provider{ + Store: passwordStore, + Config: authenticatorPasswordConfig, + Clock: clockClock, + Logger: passwordLogger, + PasswordHistory: historyStore, + PasswordChecker: passwordChecker, + Expiry: expiry, + Housekeeper: housekeeper, + } + store4 := &passkey3.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + provider2 := &passkey3.Provider{ + Store: store4, + Clock: clockClock, + Passkey: passkeyService, + } + totpStore := &totp.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + authenticatorTOTPConfig := authenticatorConfig.TOTP + totpProvider := &totp.Provider{ + Store: totpStore, + Config: authenticatorTOTPConfig, + Clock: clockClock, + } + oobStore := &oob.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + oobProvider := &oob.Provider{ + Store: oobStore, + LoginIDNormalizerFactory: normalizerFactory, + Clock: clockClock, + } + testModeConfig := appConfig.TestMode + testModeFeatureConfig := featureConfig.TestMode + codeStoreRedis := &otp.CodeStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + lookupStoreRedis := &otp.LookupStoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + attemptTrackerRedis := &otp.AttemptTrackerRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + otpLogger := otp.NewLogger(factory) + otpService := &otp.Service{ + Clock: clockClock, + AppID: appID, + TestModeConfig: testModeConfig, + TestModeFeatureConfig: testModeFeatureConfig, + RemoteIP: remoteIP, + CodeStore: codeStoreRedis, + LookupStore: lookupStoreRedis, + AttemptTracker: attemptTrackerRedis, + Logger: otpLogger, + RateLimiter: limiter, + } + rateLimits := service2.RateLimits{ + IP: remoteIP, + Config: authenticationConfig, + RateLimiter: limiter, + } + authenticationLockoutConfig := authenticationConfig.Lockout + lockoutLogger := lockout.NewLogger(factory) + lockoutStorageRedis := &lockout.StorageRedis{ + AppID: appID, + Redis: appredisHandle, + } + lockoutService := &lockout.Service{ + Logger: lockoutLogger, + Storage: lockoutStorageRedis, + } + serviceLockout := service2.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + service3 := &service2.Service{ + Store: store3, + Config: appConfig, + Password: passwordProvider, + Passkey: provider2, + TOTP: totpProvider, + OOBOTP: oobProvider, + OTPCodeService: otpService, + RateLimits: rateLimits, + Lockout: serviceLockout, + } + verificationConfig := appConfig.Verification + userProfileConfig := appConfig.UserProfile + storePQ := &verification.StorePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + verificationService := &verification.Service{ + Config: verificationConfig, + UserProfileConfig: userProfileConfig, + Clock: clockClock, + ClaimStore: storePQ, + } + imagesCDNHost := environmentConfig.ImagesCDNHost + pictureTransformer := &stdattrs2.PictureTransformer{ + HTTPProto: httpProto, + HTTPHost: httpHost, + ImagesCDNHost: imagesCDNHost, + } + serviceNoEvent := &stdattrs2.ServiceNoEvent{ + UserProfileConfig: userProfileConfig, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + ClaimStore: storePQ, + Transformer: pictureTransformer, + } + customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ + Config: userProfileConfig, + UserQueries: rawQueries, + UserStore: store, + } + nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint + web3Service := &web3.Service{ + APIEndpoint: nftIndexerAPIEndpoint, + Web3Config: web3Config, + } + rolesgroupsStore := &rolesgroups.Store{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + queries := &rolesgroups.Queries{ + Store: rolesgroupsStore, + } + userQueries := &user.Queries{ + RawQueries: rawQueries, + Store: store, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + resolverImpl := &event.ResolverImpl{ + Users: userQueries, + } + hookLogger := hook.NewLogger(factory) + hookConfig := appConfig.Hook + webHookLogger := hook.NewWebHookLogger(factory) + webhookKeyMaterials := deps.ProvideWebhookKeyMaterials(secretConfig) + webHookImpl := hook.WebHookImpl{ + Logger: webHookLogger, + Secret: webhookKeyMaterials, + } + syncHTTPClient := hook.NewSyncHTTPClient(hookConfig) + asyncHTTPClient := hook.NewAsyncHTTPClient() + eventWebHookImpl := &hook.EventWebHookImpl{ + WebHookImpl: webHookImpl, + SyncHTTP: syncHTTPClient, + AsyncHTTP: asyncHTTPClient, + } + denoHookLogger := hook.NewDenoHookLogger(factory) + denoHook := hook.DenoHook{ + Context: contextContext, + ResourceManager: manager, + Logger: denoHookLogger, + } + denoEndpoint := environmentConfig.DenoEndpoint + syncDenoClient := hook.NewSyncDenoClient(denoEndpoint, hookConfig, hookLogger) + asyncDenoClient := hook.NewAsyncDenoClient(denoEndpoint, hookLogger) + eventDenoHookImpl := &hook.EventDenoHookImpl{ + DenoHook: denoHook, + SyncDenoClient: syncDenoClient, + AsyncDenoClient: asyncDenoClient, + } + commands := &rolesgroups.Commands{ + Store: rolesgroupsStore, + } + sink := &hook.Sink{ + Logger: hookLogger, + Config: hookConfig, + Clock: clockClock, + EventWebHook: eventWebHookImpl, + EventDenoHook: eventDenoHookImpl, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + RolesAndGroups: commands, + } + auditLogger := audit.NewLogger(factory) + writeHandle := appProvider.AuditWriteDatabase + auditDatabaseCredentials := deps.ProvideAuditDatabaseCredentials(secretConfig) + auditdbSQLBuilderApp := auditdb.NewSQLBuilderApp(auditDatabaseCredentials, appID) + writeSQLExecutor := auditdb.NewWriteSQLExecutor(contextContext, writeHandle) + writeStore := &audit.WriteStore{ + SQLBuilder: auditdbSQLBuilderApp, + SQLExecutor: writeSQLExecutor, + } + auditSink := &audit.Sink{ + Logger: auditLogger, + Database: writeHandle, + Store: writeStore, + } + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + store5 := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: store5, + } + sessionManager := &oauth2.SessionManager{ + Store: store5, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, Redis: appredisHandle, AppID: appID, @@ -138841,78 +165134,270 @@ func newSAMLLoginFinishHandler(p *deps.RequestProvider) http.Handler { uiService := &authenticationinfo.UIService{ EndpointsProvider: endpointsEndpoints, } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + accountmanagementService := &accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: identityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + webappServiceLogger := webapp2.NewServiceLogger(factory) + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + interactionLogger := interaction.NewLogger(factory) + facadeIdentityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, + } + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + manager2 := &session.Manager{ + IDPSessions: idpsessionManager, + AccessTokenSessions: sessionManager, + Events: eventService, + } + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, Redis: appredisHandle, AppID: appID, } - loginResultHandler := saml2.LoginResultHandler{ - Clock: clockClock, - Database: handle, - SAMLService: samlService, + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: oauthclientResolver, + OfflineGrants: store5, + Identities: facadeIdentityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: mfaCookieDef, + } + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + interactionService := &interaction.Service{ + Logger: interactionLogger, + Context: interactionContext, + Store: interactionStoreRedis, + } + webappService2 := &webapp2.Service2{ + Logger: webappServiceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: mfaCookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, } - samlBindingHTTPPostWriter := &samlbinding.SAMLBindingHTTPPostWriter{} - loginFinishHandler := &saml2.LoginFinishHandler{ - Logger: loginFinishHandlerLogger, - Clock: clockClock, - SAMLService: samlService, - SAMLSessionService: samlsessionStoreRedis, - AuthenticationInfoResolver: uiService, - AuthenticationInfoService: authenticationinfoStoreRedis, - LoginResultHandler: loginResultHandler, - BindingHTTPPostWriter: samlBindingHTTPPostWriter, + authflowV2SettingsIdentityNewUsernameHandler := &authflowv2.AuthflowV2SettingsIdentityNewUsernameHandler{ + Database: handle, + AccountManagement: accountmanagementService, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, } - return loginFinishHandler + return authflowV2SettingsIdentityNewUsernameHandler } -func newSAMLLogoutHandler(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsIdentityViewUsernameHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider - factory := appProvider.LoggerFactory - logoutHandlerLogger := saml2.NewLogoutHandlerLogger(factory) - clockClock := _wireSystemClockValue handle := appProvider.AppDatabase appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig - samlConfig := appConfig.SAML - appID := appConfig.ID - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - samlEnvironmentConfig := environmentConfig.SAML secretConfig := config.SecretConfig - samlIdpSigningMaterials := deps.ProvideSAMLIdpSigningMaterials(secretConfig) - samlSpSigningMaterials := deps.ProvideSAMLSpSigningMaterials(secretConfig) - request := p.Request - trustProxy := environmentConfig.TrustProxy - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) - uiConfig := appConfig.UI - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - oAuthKeyMaterials := deps.ProvideOAuthKeyMaterials(secretConfig) databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) + appID := appConfig.ID sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) + request := p.Request contextContext := deps.ProvideRequestContext(request) sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) + clockClock := _wireSystemClockValue store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, AppID: appID, } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } rawQueries := &user.RawQueries{ Store: store, } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + remoteIP := deps.ProvideRemoteIP(request, trustProxy) + userAgentString := deps.ProvideUserAgentString(request) + factory := appProvider.LoggerFactory + logger := event.NewLogger(factory) + localizationConfig := appConfig.Localization + sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) + storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) authenticationConfig := appConfig.Authentication identityConfig := appConfig.Identity featureConfig := config.FeatureConfig @@ -138926,6 +165411,7 @@ func newSAMLLogoutHandler(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -138992,7 +165478,8 @@ func newSAMLLogoutHandler(p *deps.RequestProvider) http.Handler { engine := &template.Engine{ Resolver: resolver, } - localizationConfig := appConfig.Localization + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources @@ -139028,7 +165515,6 @@ func newSAMLLogoutHandler(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } - remoteIP := deps.ProvideRemoteIP(request, trustProxy) web3Config := appConfig.Web3 storeRedis := &siwe2.StoreRedis{ Context: contextContext, @@ -139036,14 +165522,14 @@ func newSAMLLogoutHandler(p *deps.RequestProvider) http.Handler { AppID: appID, Clock: clockClock, } - logger := ratelimit.NewLogger(factory) + ratelimitLogger := ratelimit.NewLogger(factory) storageRedis := &ratelimit.StorageRedis{ AppID: appID, Redis: appredisHandle, } rateLimitsFeatureConfig := featureConfig.RateLimits limiter := &ratelimit.Limiter{ - Logger: logger, + Logger: ratelimitLogger, Storage: storageRedis, Config: rateLimitsFeatureConfig, } @@ -139267,101 +165753,6 @@ func newSAMLLogoutHandler(p *deps.RequestProvider) http.Handler { Web3: web3Service, RolesAndGroups: queries, } - idTokenIssuer := &oidc.IDTokenIssuer{ - Secrets: oAuthKeyMaterials, - BaseURL: endpointsEndpoints, - Users: userQueries, - RolesAndGroups: queries, - Clock: clockClock, - } - userAgentString := deps.ProvideUserAgentString(request) - storeRedisLogger := idpsession.NewStoreRedisLogger(factory) - idpsessionStoreRedis := &idpsession.StoreRedis{ - Redis: appredisHandle, - AppID: appID, - Clock: clockClock, - Logger: storeRedisLogger, - } - eventStoreRedis := &access.EventStoreRedis{ - Redis: appredisHandle, - AppID: appID, - } - eventProvider := &access.EventProvider{ - Store: eventStoreRedis, - } - sessionConfig := appConfig.Session - idpsessionRand := _wireRandValue - idpsessionProvider := &idpsession.Provider{ - Context: contextContext, - RemoteIP: remoteIP, - UserAgentString: userAgentString, - AppID: appID, - Redis: appredisHandle, - Store: idpsessionStoreRedis, - AccessEvents: eventProvider, - TrustProxy: trustProxy, - Config: sessionConfig, - Clock: clockClock, - Random: idpsessionRand, - } - oAuthConfig := appConfig.OAuth - oauthclientResolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } - redisLogger := redis.NewLogger(factory) - redisStore := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, - } - offlineGrantService := &oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - samlService := &saml.Service{ - Clock: clockClock, - AppID: appID, - SAMLEnvironmentConfig: samlEnvironmentConfig, - SAMLConfig: samlConfig, - SAMLIdpSigningMaterials: samlIdpSigningMaterials, - SAMLSpSigningMaterials: samlSpSigningMaterials, - Endpoints: endpointsEndpoints, - UserInfoProvider: idTokenIssuer, - IDPSessionProvider: idpsessionProvider, - OfflineGrantSessionProvider: offlineGrantService, - } - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - cookieDef := session.NewSessionCookieDef(sessionConfig) - idpsessionManager := &idpsession.Manager{ - Store: idpsessionStoreRedis, - Config: sessionConfig, - Cookies: cookieManager, - CookieDef: cookieDef, - } - oauthOfflineGrantService := oauth2.OfflineGrantService{ - OAuthConfig: oAuthConfig, - Clock: clockClock, - IDPSessions: idpsessionProvider, - ClientResolver: oauthclientResolver, - OfflineGrants: redisStore, - } - sessionManager := &oauth2.SessionManager{ - Store: redisStore, - Config: oAuthConfig, - Service: oauthOfflineGrantService, - } - eventLogger := event.NewLogger(factory) - sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) - storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) resolverImpl := &event.ResolverImpl{ Users: userQueries, } @@ -139421,155 +165812,559 @@ func newSAMLLogoutHandler(p *deps.RequestProvider) http.Handler { Database: writeHandle, Store: writeStore, } - elasticsearchLogger := elasticsearch.NewLogger(factory) - elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) - elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) - client := elasticsearch.NewClient(elasticsearchCredentials) - queue := appProvider.TaskQueue - userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) - elasticsearchService := elasticsearch.Service{ - Clock: clockClock, - Context: contextContext, - Database: handle, - Logger: elasticsearchServiceLogger, - AppID: appID, - Client: client, - Users: userQueries, - UserStore: store, - IdentityService: serviceService, - RolesGroups: rolesgroupsStore, - TaskQueue: queue, - Producer: userReindexProducer, + elasticsearchLogger := elasticsearch.NewLogger(factory) + elasticsearchServiceLogger := elasticsearch.NewElasticsearchServiceLogger(factory) + elasticsearchCredentials := deps.ProvideElasticsearchCredentials(secretConfig) + client := elasticsearch.NewClient(elasticsearchCredentials) + queue := appProvider.TaskQueue + userReindexProducer := redisqueue.NewUserReindexProducer(appredisHandle, clockClock) + elasticsearchService := elasticsearch.Service{ + Clock: clockClock, + Context: contextContext, + Database: handle, + Logger: elasticsearchServiceLogger, + AppID: appID, + Client: client, + Users: userQueries, + UserStore: store, + IdentityService: serviceService, + RolesGroups: rolesgroupsStore, + TaskQueue: queue, + Producer: userReindexProducer, + } + elasticsearchSink := &elasticsearch.Sink{ + Logger: elasticsearchLogger, + Service: elasticsearchService, + Database: handle, + } + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } + storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + storeRecoveryCodePQ := &mfa.StoreRecoveryCodePQ{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + mfaLockout := mfa.Lockout{ + Config: authenticationLockoutConfig, + RemoteIP: remoteIP, + Provider: lockoutService, + } + mfaService := &mfa.Service{ + IP: remoteIP, + DeviceTokens: storeDeviceTokenRedis, + RecoveryCodes: storeRecoveryCodePQ, + Clock: clockClock, + Config: authenticationConfig, + RateLimiter: limiter, + Lockout: mfaLockout, + } + messagingLogger := messaging.NewLogger(factory) + usageLogger := usage.NewLogger(factory) + usageLimiter := &usage.Limiter{ + Logger: usageLogger, + Clock: clockClock, + AppID: appID, + Redis: appredisHandle, + } + messagingConfig := appConfig.Messaging + messagingRateLimitsConfig := messagingConfig.RateLimits + messagingFeatureConfig := featureConfig.Messaging + rateLimitsEnvironmentConfig := &environmentConfig.RateLimits + limits := messaging.Limits{ + Logger: messagingLogger, + RateLimiter: limiter, + UsageLimiter: usageLimiter, + RemoteIP: remoteIP, + Config: messagingRateLimitsConfig, + FeatureConfig: messagingFeatureConfig, + EnvConfig: rateLimitsEnvironmentConfig, + } + serviceLogger := whatsapp.NewServiceLogger(factory) + devMode := environmentConfig.DevMode + featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) + testModeWhatsappConfig := testModeConfig.Whatsapp + whatsappConfig := messagingConfig.Whatsapp + whatsappOnPremisesCredentials := deps.ProvideWhatsappOnPremisesCredentials(secretConfig) + tokenStore := &whatsapp.TokenStore{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) + whatsappService := &whatsapp.Service{ + Context: contextContext, + Logger: serviceLogger, + DevMode: devMode, + FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, + TestModeWhatsappConfig: testModeWhatsappConfig, + WhatsappConfig: whatsappConfig, + LocalizationConfig: localizationConfig, + OnPremisesClient: onPremisesClient, + TokenStore: tokenStore, + } + sender := &messaging.Sender{ + Limits: limits, + TaskQueue: queue, + Events: eventService, + Whatsapp: whatsappService, + MessagingFeatureConfig: messagingFeatureConfig, + } + forgotpasswordSender := &forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + stdattrsService := &stdattrs2.Service{ + UserProfileConfig: userProfileConfig, + ServiceNoEvent: serviceNoEvent, + Identities: serviceService, + UserQueries: rawQueries, + UserStore: store, + Events: eventService, + } + authorizationStore := &pq.AuthorizationStore{ + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + } + storeRedisLogger := idpsession.NewStoreRedisLogger(factory) + idpsessionStoreRedis := &idpsession.StoreRedis{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + Logger: storeRedisLogger, + } + sessionConfig := appConfig.Session + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + cookieDef := session.NewSessionCookieDef(sessionConfig) + idpsessionManager := &idpsession.Manager{ + Store: idpsessionStoreRedis, + Config: sessionConfig, + Cookies: cookieManager, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + store5 := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, + } + oAuthConfig := appConfig.OAuth + eventStoreRedis := &access.EventStoreRedis{ + Redis: appredisHandle, + AppID: appID, + } + eventProvider := &access.EventProvider{ + Store: eventStoreRedis, + } + idpsessionRand := _wireRandValue + idpsessionProvider := &idpsession.Provider{ + Context: contextContext, + RemoteIP: remoteIP, + UserAgentString: userAgentString, + AppID: appID, + Redis: appredisHandle, + Store: idpsessionStoreRedis, + AccessEvents: eventProvider, + TrustProxy: trustProxy, + Config: sessionConfig, + Clock: clockClock, + Random: idpsessionRand, + } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } + offlineGrantService := oauth2.OfflineGrantService{ + OAuthConfig: oAuthConfig, + Clock: clockClock, + IDPSessions: idpsessionProvider, + ClientResolver: oauthclientResolver, + OfflineGrants: store5, + } + sessionManager := &oauth2.SessionManager{ + Store: store5, + Config: oAuthConfig, + Service: offlineGrantService, + } + accountDeletionConfig := appConfig.AccountDeletion + accountAnonymizationConfig := appConfig.AccountAnonymization + maxTrials := _wireMaxTrialsValue + passwordRand := password.NewRandSource() + generator := &password.Generator{ + MaxTrials: maxTrials, + Checker: passwordChecker, + Rand: passwordRand, + PasswordConfig: authenticatorPasswordConfig, + } + coordinator := &facade.Coordinator{ + Events: eventService, + Identities: serviceService, + Authenticators: service3, + Verification: verificationService, + MFA: mfaService, + SendPassword: forgotpasswordSender, + UserCommands: userCommands, + UserQueries: userQueries, + RolesGroupsCommands: commands, + StdAttrsService: stdattrsService, + PasswordHistory: historyStore, + OAuth: authorizationStore, + IDPSessions: idpsessionManager, + OAuthSessions: sessionManager, + IdentityConfig: identityConfig, + AccountDeletionConfig: accountDeletionConfig, + AccountAnonymizationConfig: accountAnonymizationConfig, + AuthenticationConfig: authenticationConfig, + Clock: clockClock, + PasswordGenerator: generator, + } + identityFacade := &facade.IdentityFacade{ + Coordinator: coordinator, + } + messageSender := &otp.MessageSender{ + AppID: appID, + Translation: translationService, + Endpoints: endpointsEndpoints, + Sender: sender, + WhatsappService: whatsappService, + } + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + accountmanagementService := &accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: identityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + webappServiceLogger := webapp2.NewServiceLogger(factory) + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + interactionLogger := interaction.NewLogger(factory) + facadeIdentityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, + } + webappoauthStore := &webappoauth.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + } + mfaFacade := &facade.MFAFacade{ + Coordinator: coordinator, + } + forgotpasswordLogger := forgotpassword.NewLogger(factory) + sender2 := forgotpassword.Sender{ + AppConfg: appConfig, + Identities: serviceService, + Sender: sender, + Translation: translationService, + } + forgotpasswordService := &forgotpassword.Service{ + Logger: forgotpasswordLogger, + Config: appConfig, + FeatureConfig: featureConfig, + Identities: serviceService, + Authenticators: authenticatorFacade, + OTPCodes: otpService, + OTPSender: messageSender, + PasswordSender: sender2, } - elasticsearchSink := &elasticsearch.Sink{ - Logger: elasticsearchLogger, - Service: elasticsearchService, - Database: handle, + responseWriter := p.ResponseWriter + nonceService := &nonce.Service{ + Cookies: cookieManager, + Request: request, + ResponseWriter: responseWriter, + } + challengeProvider := &challenge.Provider{ + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, Events: eventService, } - samlslosessionStoreRedis := &samlslosession.StoreRedis{ + oauthsessionStoreRedis := &oauthsession.StoreRedis{ Context: contextContext, Redis: appredisHandle, AppID: appID, } - samlBindingHTTPPostWriter := &samlbinding.SAMLBindingHTTPPostWriter{} - samlBindingHTTPRedirectWriter := &samlbinding.SAMLBindingHTTPRedirectWriter{ - Signer: samlService, + interactionContext := &interaction.Context{ + Request: request, + RemoteIP: remoteIP, + Database: sqlExecutor, + Clock: clockClock, + Config: appConfig, + FeatureConfig: featureConfig, + OAuthClientResolver: oauthclientResolver, + OfflineGrants: store5, + Identities: facadeIdentityFacade, + Authenticators: authenticatorFacade, + AnonymousIdentities: anonymousProvider, + AnonymousUserPromotionCodeStore: anonymousStoreRedis, + BiometricIdentities: biometricProvider, + OTPCodeService: otpService, + OTPSender: messageSender, + OAuthProviderFactory: oAuthProviderFactory, + OAuthRedirectURIBuilder: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + MFA: mfaFacade, + ForgotPassword: forgotpasswordService, + ResetPassword: forgotpasswordService, + Passkey: passkeyService, + Verification: verificationService, + RateLimiter: limiter, + PasswordGenerator: generator, + Nonces: nonceService, + Challenges: challengeProvider, + Users: userProvider, + StdAttrsService: stdattrsService, + Events: eventService, + CookieManager: cookieManager, + AuthenticationInfoService: authenticationinfoStoreRedis, + Sessions: idpsessionProvider, + SessionManager: manager2, + SessionCookie: cookieDef, + OAuthSessions: oauthsessionStoreRedis, + MFADeviceTokenCookie: mfaCookieDef, } - sloService := &saml.SLOService{ - SAMLService: samlService, - BindingHTTPPostWriter: samlBindingHTTPPostWriter, - BindingHTTPRedirectWriter: samlBindingHTTPRedirectWriter, + interactionStoreRedis := &interaction.StoreRedis{ + Redis: appredisHandle, + AppID: appID, } - logoutHandler := &saml2.LogoutHandler{ - Logger: logoutHandlerLogger, - Clock: clockClock, - Database: handle, - SAMLConfig: samlConfig, - SAMLService: samlService, - SessionManager: manager2, - SAMLSLOSessionService: samlslosessionStoreRedis, - SAMLSLOService: sloService, - Endpoints: endpointsEndpoints, - BindingHTTPPostWriter: samlBindingHTTPPostWriter, - BindingHTTPRedirectWriter: samlBindingHTTPRedirectWriter, + interactionService := &interaction.Service{ + Logger: interactionLogger, + Context: interactionContext, + Store: interactionStoreRedis, } - return logoutHandler + webappService2 := &webapp2.Service2{ + Logger: webappServiceLogger, + Request: request, + Sessions: sessionStoreRedis, + SessionCookie: sessionCookieDef, + SignedUpCookie: signedUpCookieDef, + MFADeviceTokenCookie: mfaCookieDef, + ErrorService: errorService, + Cookies: cookieManager, + OAuthConfig: oAuthConfig, + UIConfig: uiConfig, + TrustProxy: trustProxy, + UIInfoResolver: uiService, + OAuthClientResolver: oauthclientResolver, + Graph: interactionService, + } + uiFeatureConfig := featureConfig.UI + forgotPasswordConfig := appConfig.ForgotPassword + googleTagManagerConfig := appConfig.GoogleTagManager + botProtectionConfig := appConfig.BotProtection + flashMessage := &httputil.FlashMessage{ + Cookies: cookieManager, + } + authUISentryDSN := environmentConfig.AuthUISentryDSN + authUIWindowMessageAllowedOrigins := environmentConfig.AuthUIWindowMessageAllowedOrigins + baseLogger := viewmodels.NewBaseLogger(factory) + baseViewModeler := &viewmodels.BaseViewModeler{ + TrustProxy: trustProxy, + OAuth: oAuthConfig, + AuthUI: uiConfig, + AuthUIFeatureConfig: uiFeatureConfig, + StaticAssets: staticAssetResolver, + ForgotPassword: forgotPasswordConfig, + Authentication: authenticationConfig, + GoogleTagManager: googleTagManagerConfig, + BotProtection: botProtectionConfig, + ErrorService: errorService, + Translations: translationService, + Clock: clockClock, + FlashMessage: flashMessage, + DefaultLanguageTag: defaultLanguageTag, + SupportedLanguageTags: supportedLanguageTags, + AuthUISentryDSN: authUISentryDSN, + AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, + OAuthClientResolver: oauthclientResolver, + Logger: baseLogger, + } + responseRenderer := &webapp.ResponseRenderer{ + TemplateEngine: engine, + } + publisher := webapp.NewPublisher(appID, appredisHandle) + authflowNavigator := &webapp2.AuthflowNavigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + authflowV2Navigator := &authflowv2.AuthflowV2Navigator{ + Endpoints: endpointsEndpoints, + OAuthStateStore: webappoauthStore, + } + errorRenderer := &webapp.ErrorRenderer{ + ErrorService: errorService, + UIImplementationService: uiImplementationService, + AuthflowV1Navigator: authflowNavigator, + AuthflowV2Navigator: authflowV2Navigator, + } + controllerDeps := webapp.ControllerDeps{ + Database: handle, + RedisHandle: appredisHandle, + AppID: appID, + Page: webappService2, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + Publisher: publisher, + Clock: clockClock, + TesterEndpointsProvider: endpointsEndpoints, + ErrorRenderer: errorRenderer, + TrustProxy: trustProxy, + } + controllerFactory := webapp.ControllerFactory{ + LoggerFactory: factory, + ControllerDeps: controllerDeps, + } + authflowV2SettingsIdentityViewUsernameHandler := &authflowv2.AuthflowV2SettingsIdentityViewUsernameHandler{ + Database: handle, + AccountManagement: accountmanagementService, + LoginIDConfig: loginIDConfig, + Identities: serviceService, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, + } + return authflowV2SettingsIdentityViewUsernameHandler } -func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { +func newWebAppAuthflowV2SettingsIdentityEditUsernameHandler(p *deps.RequestProvider) http.Handler { appProvider := p.AppProvider - factory := appProvider.LoggerFactory handle := appProvider.AppDatabase - appredisHandle := appProvider.Redis appContext := appProvider.AppContext config := appContext.Config appConfig := config.AppConfig + secretConfig := config.SecretConfig + databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) appID := appConfig.ID - serviceLogger := webapp2.NewServiceLogger(factory) + sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) request := p.Request - sessionStoreRedis := &webapp2.SessionStoreRedis{ - AppID: appID, - Redis: appredisHandle, - } - sessionCookieDef := webapp2.NewSessionCookieDef() - signedUpCookieDef := webapp2.NewSignedUpCookieDef() - authenticationConfig := appConfig.Authentication - cookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) - errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() - rootProvider := appProvider.RootProvider - environmentConfig := rootProvider.EnvironmentConfig - trustProxy := environmentConfig.TrustProxy - httpConfig := appConfig.HTTP - cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) - errorService := &webapp2.ErrorService{ - AppID: appID, - Cookie: errorTokenCookieDef, - RedisHandle: appredisHandle, - Cookies: cookieManager, - } - oAuthConfig := appConfig.OAuth - uiConfig := appConfig.UI - httpHost := deps.ProvideHTTPHost(request, trustProxy) - httpProto := deps.ProvideHTTPProto(request, trustProxy) - globalUIImplementation := environmentConfig.UIImplementation - globalUISettingsImplementation := environmentConfig.UISettingsImplementation - uiImplementationService := &web.UIImplementationService{ - UIConfig: uiConfig, - GlobalUIImplementation: globalUIImplementation, - GlobalUISettingsImplementation: globalUISettingsImplementation, - } - endpointsEndpoints := &endpoints.Endpoints{ - HTTPHost: httpHost, - HTTPProto: httpProto, - UIImplementationService: uiImplementationService, - } - uiService := &authenticationinfo.UIService{ - EndpointsProvider: endpointsEndpoints, - } - resolver := &oauthclient.Resolver{ - OAuthConfig: oAuthConfig, - TesterEndpoints: endpointsEndpoints, - } - logger := interaction.NewLogger(factory) - remoteIP := deps.ProvideRemoteIP(request, trustProxy) contextContext := deps.ProvideRequestContext(request) sqlExecutor := appdb.NewSQLExecutor(contextContext, handle) clockClock := _wireSystemClockValue - featureConfig := config.FeatureConfig - redisLogger := redis.NewLogger(factory) - secretConfig := config.SecretConfig - databaseCredentials := deps.ProvideDatabaseCredentials(secretConfig) - sqlBuilderApp := appdb.NewSQLBuilderApp(databaseCredentials, appID) - store := &redis.Store{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Logger: redisLogger, + store := &user.Store{ SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, Clock: clockClock, + AppID: appID, + } + rawCommands := &user.RawCommands{ + Store: store, + Clock: clockClock, + } + rawQueries := &user.RawQueries{ + Store: store, } + rootProvider := appProvider.RootProvider + environmentConfig := rootProvider.EnvironmentConfig + trustProxy := environmentConfig.TrustProxy + remoteIP := deps.ProvideRemoteIP(request, trustProxy) userAgentString := deps.ProvideUserAgentString(request) - eventLogger := event.NewLogger(factory) + factory := appProvider.LoggerFactory + logger := event.NewLogger(factory) localizationConfig := appConfig.Localization sqlBuilder := appdb.NewSQLBuilder(databaseCredentials) storeImpl := event.NewStoreImpl(sqlBuilder, sqlExecutor) - userStore := &user.Store{ - SQLBuilder: sqlBuilderApp, - SQLExecutor: sqlExecutor, - Clock: clockClock, - AppID: appID, - } - rawQueries := &user.RawQueries{ - Store: userStore, - } + authenticationConfig := appConfig.Authentication identityConfig := appConfig.Identity + featureConfig := config.FeatureConfig identityFeatureConfig := featureConfig.Identity serviceStore := &service.Store{ SQLBuilder: sqlBuilderApp, @@ -139580,6 +166375,7 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { SQLExecutor: sqlExecutor, } loginIDConfig := identityConfig.LoginID + uiConfig := appConfig.UI manager := appContext.Resources typeCheckerFactory := &loginid.TypeCheckerFactory{ UIConfig: uiConfig, @@ -139630,6 +166426,7 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { SQLBuilder: sqlBuilderApp, SQLExecutor: sqlExecutor, } + appredisHandle := appProvider.Redis store2 := &passkey2.Store{ Context: contextContext, Redis: appredisHandle, @@ -139637,14 +166434,16 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { } defaultLanguageTag := deps.ProvideDefaultLanguageTag(config) supportedLanguageTags := deps.ProvideSupportedLanguageTags(config) - templateResolver := &template.Resolver{ + resolver := &template.Resolver{ Resources: manager, DefaultLanguageTag: defaultLanguageTag, SupportedLanguageTags: supportedLanguageTags, } engine := &template.Engine{ - Resolver: templateResolver, + Resolver: resolver, } + httpProto := deps.ProvideHTTPProto(request, trustProxy) + httpHost := deps.ProvideHTTPHost(request, trustProxy) httpOrigin := httputil.MakeHTTPOrigin(httpProto, httpHost) webAppCDNHost := environmentConfig.WebAppCDNHost globalEmbeddedResourceManager := rootProvider.EmbeddedResources @@ -139885,14 +166684,14 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { UserProfileConfig: userProfileConfig, Identities: serviceService, UserQueries: rawQueries, - UserStore: userStore, + UserStore: store, ClaimStore: storePQ, Transformer: pictureTransformer, } customattrsServiceNoEvent := &customattrs.ServiceNoEvent{ Config: userProfileConfig, UserQueries: rawQueries, - UserStore: userStore, + UserStore: store, } nftIndexerAPIEndpoint := environmentConfig.NFTIndexerAPIEndpoint web3Service := &web3.Service{ @@ -139909,7 +166708,7 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { } userQueries := &user.Queries{ RawQueries: rawQueries, - Store: userStore, + Store: store, Identities: serviceService, Authenticators: service3, Verification: verificationService, @@ -139991,7 +166790,7 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { AppID: appID, Client: client, Users: userQueries, - UserStore: userStore, + UserStore: store, IdentityService: serviceService, RolesGroups: rolesgroupsStore, TaskQueue: queue, @@ -140002,7 +166801,43 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { Service: elasticsearchService, Database: handle, } - eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, eventLogger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + eventService := event.NewService(contextContext, appID, remoteIP, userAgentString, logger, handle, clockClock, localizationConfig, storeImpl, resolverImpl, sink, auditSink, elasticsearchSink) + userCommands := &user.Commands{ + RawCommands: rawCommands, + RawQueries: rawQueries, + Events: eventService, + Verification: verificationService, + UserProfileConfig: userProfileConfig, + StandardAttributes: serviceNoEvent, + CustomAttributes: customattrsServiceNoEvent, + Web3: web3Service, + RolesAndGroups: queries, + } + userProvider := &user.Provider{ + Commands: userCommands, + Queries: userQueries, + } + redisStore := &accountmanagement.RedisStore{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + Clock: clockClock, + } + oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) + oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) + simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + Context: contextContext, + AppID: appID, + Redis: appredisHandle, + } + oAuthProviderFactory := &sso.OAuthProviderFactory{ + IdentityConfig: identityConfig, + Credentials: oAuthSSOProviderCredentials, + Clock: clockClock, + StandardAttributesNormalizer: normalizer, + HTTPClient: oAuthHTTPClient, + SimpleStoreRedisFactory: simpleStoreRedisFactory, + } storeDeviceTokenRedis := &mfa.StoreDeviceTokenRedis{ Redis: appredisHandle, AppID: appID, @@ -140047,7 +166882,7 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { FeatureConfig: messagingFeatureConfig, EnvConfig: rateLimitsEnvironmentConfig, } - whatsappServiceLogger := whatsapp.NewServiceLogger(factory) + serviceLogger := whatsapp.NewServiceLogger(factory) devMode := environmentConfig.DevMode featureTestModeWhatsappSuppressed := deps.ProvideTestModeWhatsappSuppressed(testModeFeatureConfig) testModeWhatsappConfig := testModeConfig.Whatsapp @@ -140061,7 +166896,7 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { onPremisesClient := whatsapp.NewWhatsappOnPremisesClient(whatsappConfig, whatsappOnPremisesCredentials, tokenStore) whatsappService := &whatsapp.Service{ Context: contextContext, - Logger: whatsappServiceLogger, + Logger: serviceLogger, DevMode: devMode, FeatureTestModeWhatsappSuppressed: featureTestModeWhatsappSuppressed, TestModeWhatsappConfig: testModeWhatsappConfig, @@ -140083,27 +166918,12 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { Sender: sender, Translation: translationService, } - rawCommands := &user.RawCommands{ - Store: userStore, - Clock: clockClock, - } - userCommands := &user.Commands{ - RawCommands: rawCommands, - RawQueries: rawQueries, - Events: eventService, - Verification: verificationService, - UserProfileConfig: userProfileConfig, - StandardAttributes: serviceNoEvent, - CustomAttributes: customattrsServiceNoEvent, - Web3: web3Service, - RolesAndGroups: queries, - } stdattrsService := &stdattrs2.Service{ UserProfileConfig: userProfileConfig, ServiceNoEvent: serviceNoEvent, Identities: serviceService, UserQueries: rawQueries, - UserStore: userStore, + UserStore: store, Events: eventService, } authorizationStore := &pq.AuthorizationStore{ @@ -140118,13 +166938,26 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { Logger: storeRedisLogger, } sessionConfig := appConfig.Session - cookieDef2 := session.NewSessionCookieDef(sessionConfig) + httpConfig := appConfig.HTTP + cookieManager := deps.NewCookieManager(request, trustProxy, httpConfig) + cookieDef := session.NewSessionCookieDef(sessionConfig) idpsessionManager := &idpsession.Manager{ Store: idpsessionStoreRedis, Config: sessionConfig, Cookies: cookieManager, - CookieDef: cookieDef2, + CookieDef: cookieDef, + } + redisLogger := redis.NewLogger(factory) + store5 := &redis.Store{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Logger: redisLogger, + SQLBuilder: sqlBuilderApp, + SQLExecutor: sqlExecutor, + Clock: clockClock, } + oAuthConfig := appConfig.OAuth eventStoreRedis := &access.EventStoreRedis{ Redis: appredisHandle, AppID: appID, @@ -140146,15 +166979,31 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { Clock: clockClock, Random: idpsessionRand, } + globalUIImplementation := environmentConfig.UIImplementation + globalUISettingsImplementation := environmentConfig.UISettingsImplementation + uiImplementationService := &web.UIImplementationService{ + UIConfig: uiConfig, + GlobalUIImplementation: globalUIImplementation, + GlobalUISettingsImplementation: globalUISettingsImplementation, + } + endpointsEndpoints := &endpoints.Endpoints{ + HTTPHost: httpHost, + HTTPProto: httpProto, + UIImplementationService: uiImplementationService, + } + oauthclientResolver := &oauthclient.Resolver{ + OAuthConfig: oAuthConfig, + TesterEndpoints: endpointsEndpoints, + } offlineGrantService := oauth2.OfflineGrantService{ OAuthConfig: oAuthConfig, Clock: clockClock, IDPSessions: idpsessionProvider, - ClientResolver: resolver, - OfflineGrants: store, + ClientResolver: oauthclientResolver, + OfflineGrants: store5, } sessionManager := &oauth2.SessionManager{ - Store: store, + Store: store5, Config: oAuthConfig, Service: offlineGrantService, } @@ -140190,18 +167039,9 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { Clock: clockClock, PasswordGenerator: generator, } - identityFacade := facade.IdentityFacade{ - Coordinator: coordinator, - } - authenticatorFacade := facade.AuthenticatorFacade{ + identityFacade := &facade.IdentityFacade{ Coordinator: coordinator, } - anonymousStoreRedis := &anonymous.StoreRedis{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - Clock: clockClock, - } messageSender := &otp.MessageSender{ AppID: appID, Translation: translationService, @@ -140209,20 +167049,57 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { Sender: sender, WhatsappService: whatsappService, } - oAuthSSOProviderCredentials := deps.ProvideOAuthSSOProviderCredentials(secretConfig) - oAuthHTTPClient := sso.ProvideOAuthHTTPClient(environmentConfig) - simpleStoreRedisFactory := &sso.SimpleStoreRedisFactory{ + authenticatorFacade := facade.AuthenticatorFacade{ + Coordinator: coordinator, + } + authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ Context: contextContext, - AppID: appID, Redis: appredisHandle, + AppID: appID, } - oAuthProviderFactory := &sso.OAuthProviderFactory{ - IdentityConfig: identityConfig, - Credentials: oAuthSSOProviderCredentials, - Clock: clockClock, - StandardAttributesNormalizer: normalizer, - HTTPClient: oAuthHTTPClient, - SimpleStoreRedisFactory: simpleStoreRedisFactory, + uiService := &authenticationinfo.UIService{ + EndpointsProvider: endpointsEndpoints, + } + accountmanagementService := &accountmanagement.Service{ + Database: handle, + Config: appConfig, + Users: userProvider, + Store: redisStore, + OAuthProvider: oAuthProviderFactory, + Identities: identityFacade, + Events: eventService, + OTPSender: messageSender, + OTPCodeService: otpService, + Authenticators: authenticatorFacade, + AuthenticationInfoService: authenticationinfoStoreRedis, + PasskeyService: passkeyService, + Verification: verificationService, + UIInfoResolver: uiService, + } + webappServiceLogger := webapp2.NewServiceLogger(factory) + sessionStoreRedis := &webapp2.SessionStoreRedis{ + AppID: appID, + Redis: appredisHandle, + } + sessionCookieDef := webapp2.NewSessionCookieDef() + signedUpCookieDef := webapp2.NewSignedUpCookieDef() + mfaCookieDef := mfa.NewDeviceTokenCookieDef(authenticationConfig) + errorTokenCookieDef := webapp2.NewErrorTokenCookieDef() + errorService := &webapp2.ErrorService{ + AppID: appID, + Cookie: errorTokenCookieDef, + RedisHandle: appredisHandle, + Cookies: cookieManager, + } + interactionLogger := interaction.NewLogger(factory) + facadeIdentityFacade := facade.IdentityFacade{ + Coordinator: coordinator, + } + anonymousStoreRedis := &anonymous.StoreRedis{ + Context: contextContext, + Redis: appredisHandle, + AppID: appID, + Clock: clockClock, } webappoauthStore := &webappoauth.Store{ Context: contextContext, @@ -140260,15 +167137,6 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { AppID: appID, Clock: clockClock, } - userProvider := &user.Provider{ - Commands: userCommands, - Queries: userQueries, - } - authenticationinfoStoreRedis := &authenticationinfo.StoreRedis{ - Context: contextContext, - Redis: appredisHandle, - AppID: appID, - } manager2 := &session.Manager{ IDPSessions: idpsessionManager, AccessTokenSessions: sessionManager, @@ -140286,9 +167154,9 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { Clock: clockClock, Config: appConfig, FeatureConfig: featureConfig, - OAuthClientResolver: resolver, - OfflineGrants: store, - Identities: identityFacade, + OAuthClientResolver: oauthclientResolver, + OfflineGrants: store5, + Identities: facadeIdentityFacade, Authenticators: authenticatorFacade, AnonymousIdentities: anonymousProvider, AnonymousUserPromotionCodeStore: anonymousStoreRedis, @@ -140314,33 +167182,33 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { AuthenticationInfoService: authenticationinfoStoreRedis, Sessions: idpsessionProvider, SessionManager: manager2, - SessionCookie: cookieDef2, + SessionCookie: cookieDef, OAuthSessions: oauthsessionStoreRedis, - MFADeviceTokenCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, } interactionStoreRedis := &interaction.StoreRedis{ Redis: appredisHandle, AppID: appID, } interactionService := &interaction.Service{ - Logger: logger, + Logger: interactionLogger, Context: interactionContext, Store: interactionStoreRedis, } webappService2 := &webapp2.Service2{ - Logger: serviceLogger, + Logger: webappServiceLogger, Request: request, Sessions: sessionStoreRedis, SessionCookie: sessionCookieDef, SignedUpCookie: signedUpCookieDef, - MFADeviceTokenCookie: cookieDef, + MFADeviceTokenCookie: mfaCookieDef, ErrorService: errorService, Cookies: cookieManager, OAuthConfig: oAuthConfig, UIConfig: uiConfig, TrustProxy: trustProxy, UIInfoResolver: uiService, - OAuthClientResolver: resolver, + OAuthClientResolver: oauthclientResolver, Graph: interactionService, } uiFeatureConfig := featureConfig.UI @@ -140371,7 +167239,7 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { SupportedLanguageTags: supportedLanguageTags, AuthUISentryDSN: authUISentryDSN, AuthUIWindowMessageAllowedOrigins: authUIWindowMessageAllowedOrigins, - OAuthClientResolver: resolver, + OAuthClientResolver: oauthclientResolver, Logger: baseLogger, } responseRenderer := &webapp.ResponseRenderer{ @@ -140409,23 +167277,15 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { LoggerFactory: factory, ControllerDeps: controllerDeps, } - facadeIdentityFacade := &facade.IdentityFacade{ - Coordinator: coordinator, - } - settingsProfileViewModeler := &viewmodels.SettingsProfileViewModeler{ - Localization: localizationConfig, - UserProfileConfig: userProfileConfig, - Users: userQueries, - Identities: facadeIdentityFacade, - Clock: clockClock, - } - authflowV2SettingsProfileHandler := &authflowv2.AuthflowV2SettingsProfileHandler{ - ControllerFactory: controllerFactory, - BaseViewModel: baseViewModeler, - SettingsProfileViewModel: settingsProfileViewModeler, - Renderer: responseRenderer, + authflowV2SettingsIdentityEditUsernameHandler := &authflowv2.AuthflowV2SettingsIdentityEditUsernameHandler{ + Database: handle, + AccountManagement: accountmanagementService, + Identities: serviceService, + ControllerFactory: controllerFactory, + BaseViewModel: baseViewModeler, + Renderer: responseRenderer, } - return authflowV2SettingsProfileHandler + return authflowV2SettingsIdentityEditUsernameHandler } // Injectors from wire_middleware.go: diff --git a/pkg/auth/wire_handler.go b/pkg/auth/wire_handler.go index 82c2585012..833c8aa454 100644 --- a/pkg/auth/wire_handler.go +++ b/pkg/auth/wire_handler.go @@ -457,6 +457,13 @@ func newWebAppSettingsBiometricHandler(p *deps.RequestProvider) http.Handler { )) } +func newWebAppAuthflowV2SettingsBiometricHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsBiometricHandler)), + )) +} + func newWebAppSettingsMFAHandler(p *deps.RequestProvider) http.Handler { panic(wire.Build( DependencySet, @@ -464,6 +471,27 @@ func newWebAppSettingsMFAHandler(p *deps.RequestProvider) http.Handler { )) } +func newWebAppAuthflowV2SettingsMFAHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsMFAHandler)), + )) +} + +func newWebAppAuthflowV2SettingsMFACreatePasswordHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsMFACreatePasswordHandler)), + )) +} + +func newWebAppAuthflowV2SettingsMFAPasswordHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsMFAPasswordHandler)), + )) +} + func newWebAppSettingsTOTPHandler(p *deps.RequestProvider) http.Handler { panic(wire.Build( DependencySet, @@ -471,6 +499,20 @@ func newWebAppSettingsTOTPHandler(p *deps.RequestProvider) http.Handler { )) } +func newWebAppAuthflowV2SettingsTOTPHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsTOTPHandler)), + )) +} + +func newWebAppAuthflowV2SettingsOOBOTPHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsOOBOTPHandler)), + )) +} + func newWebAppSettingsPasskeyHandler(p *deps.RequestProvider) http.Handler { panic(wire.Build( DependencySet, @@ -478,6 +520,13 @@ func newWebAppSettingsPasskeyHandler(p *deps.RequestProvider) http.Handler { )) } +func newWebAppAuthflowV2SettingsChangePasskeyHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsChangePasskeyHandler)), + )) +} + func newWebAppSettingsOOBOTPHandler(p *deps.RequestProvider) http.Handler { panic(wire.Build( DependencySet, @@ -499,6 +548,13 @@ func newWebAppSettingsSessionsHandler(p *deps.RequestProvider) http.Handler { )) } +func newWebAppAuthflowV2SettingsSessionsHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsSessionsHandler)), + )) +} + func newWebAppForceChangePasswordHandler(p *deps.RequestProvider) http.Handler { panic(wire.Build( DependencySet, @@ -513,6 +569,13 @@ func newWebAppSettingsChangePasswordHandler(p *deps.RequestProvider) http.Handle )) } +func newWebAppAuthflowV2SettingsChangePasswordHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsChangePasswordHandler)), + )) +} + func newWebAppForceChangeSecondaryPasswordHandler(p *deps.RequestProvider) http.Handler { panic(wire.Build( DependencySet, @@ -534,6 +597,13 @@ func newWebAppSettingsDeleteAccountHandler(p *deps.RequestProvider) http.Handler )) } +func newWebAppAuthflowV2SettingsDeleteAccountHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsDeleteAccountHandler)), + )) +} + func newWebAppSettingsDeleteAccountSuccessHandler(p *deps.RequestProvider) http.Handler { panic(wire.Build( DependencySet, @@ -541,6 +611,20 @@ func newWebAppSettingsDeleteAccountSuccessHandler(p *deps.RequestProvider) http. )) } +func newWebAppAuthflowV2SettingsDeleteAccountSuccessHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsDeleteAccountSuccessHandler)), + )) +} + +func newWebAppAuthflowV2SettingsAdvancedSettingsHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsAdvancedSettingsHandler)), + )) +} + func newWebAppAccountStatusHandler(p *deps.RequestProvider) http.Handler { panic(wire.Build( DependencySet, @@ -1163,3 +1247,115 @@ func newWebAppAuthflowV2SettingsProfile(p *deps.RequestProvider) http.Handler { wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsProfileHandler)), )) } + +func newWebAppAuthflowV2SettingsIdentityAddEmailHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityAddEmailHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityEditEmailHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityEditEmailHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityListEmailHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityListEmailHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityVerifyEmailHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityVerifyEmailHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityViewEmailHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityViewEmailHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityChangePrimaryEmailHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityChangePrimaryEmailHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityAddPhoneHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityAddPhoneHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityEditPhoneHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityEditPhoneHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityListPhoneHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityListPhoneHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityViewPhoneHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityViewPhoneHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityChangePrimaryPhoneHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityChangePrimaryPhoneHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityVerifyPhoneHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityVerifyPhoneHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityListUsernameHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityListUsernameHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityNewUsernameHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityNewUsernameHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityViewUsernameHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityViewUsernameHandler)), + )) +} + +func newWebAppAuthflowV2SettingsIdentityEditUsernameHandler(p *deps.RequestProvider) http.Handler { + panic(wire.Build( + DependencySet, + wire.Bind(new(http.Handler), new(*handlerwebappauthflowv2.AuthflowV2SettingsIdentityEditUsernameHandler)), + )) +} diff --git a/pkg/lib/web/html.go b/pkg/lib/web/html.go index 7dea2a72d4..3b58870480 100644 --- a/pkg/lib/web/html.go +++ b/pkg/lib/web/html.go @@ -72,7 +72,9 @@ var TemplateWebAuthflowV2TermsOfServiceAndPrivacyPolicyFooterHTML = template.Reg var TemplateWebAuthflowV2WatermarkHTML = template.RegisterHTML("web/authflowv2/__watermark.html") var TemplateWebAuthflowV2CSRFErrorPageLayoutHTML = template.RegisterHTML("web/authflowv2/__csrf_error_page_layout.html") var TemplateWebAuthflowV2SettingsItemHTML = template.RegisterHTML("web/authflowv2/__settings_item.html") +var TemplateWebAuthflowV2SettingsActionItemHTML = template.RegisterHTML("web/authflowv2/__settings_action_item.html") var TemplateWebAuthflowV2SettingsRadioHTML = template.RegisterHTML("web/authflowv2/__settings_radio.html") +var TemplateWebAuthflowV2SettingsDialog = template.RegisterHTML("web/authflowv2/__settings_dialog.html") var TemplateWebSettingsV2PageFrameHTML = template.RegisterHTML("web/authflowv2/__settings_page_frame.html") var TemplateWebAuthflowV2NavBar = template.RegisterHTML("web/authflowv2/__navbar.html") @@ -143,11 +145,13 @@ var BaseComponentsHTML = []*template.HTML{ TemplateWebAuthflowV2CSRFErrorPageLayoutHTML, TemplateWebAuthflowV2BrandLogoHTML, TemplateWebAuthflowV2SettingsItemHTML, + TemplateWebAuthflowV2SettingsActionItemHTML, TemplateWebAuthflowV2NavBar, TemplateWebAuthflowV2DateInputHTML, TemplateWebAuthflowV2UserProfilePic, TemplateWebAuthflowV2SettingsRadioHTML, TemplateWebAuthflowV2SettingsTextInput, + TemplateWebAuthflowV2SettingsDialog, TemplateWebAuthflowV2LocaleInputHTML, TemplateWebAuthflowV2TimezoneInput, TemplateWebAuthflowV2CountryInput, diff --git a/resources/authgear/templates/en/translation.json b/resources/authgear/templates/en/translation.json index 01b7d4463f..4e3e6e71f2 100644 --- a/resources/authgear/templates/en/translation.json +++ b/resources/authgear/templates/en/translation.json @@ -879,13 +879,17 @@ "v2.component.bot-protection-widget.default.noscript": "JavaScript is required for captcha verification. Please enable JavaScript in your browser to proceed.", "v2.component.button.default.copy": "Copy", "v2.component.button.default.download": "Download", + "v2.component.button.default.label-cancel": "Cancel", "v2.component.button.default.label-continue": "Continue", "v2.component.button.default.label-continue-with-passkey": "Continue with Passkey", "v2.component.button.default.label-continue-with-phone": "Continue with Phone Number", "v2.component.button.default.label-continue-with-text-login-id": "Continue with {variant, select, email {Email} username {Username} other {Email / Username}}", + "v2.component.button.default.label-edit": "Edit", "v2.component.button.default.label-login": "Login", + "v2.component.button.default.label-remove": "Remove", "v2.component.button.default.label-save": "Save", "v2.component.button.default.label-send": "Send", + "v2.component.button.default.label-terminate": "Terminate", "v2.component.device-token-checkbox.default.label": "Remember this device, and don’t ask again", "v2.component.divider.default.or-label": "or", "v2.component.input.default.placeholder-email": "Email address", @@ -923,6 +927,7 @@ "v2.component.oob-otp-resend-button.default.countdown-unit": "Resend code in %s", "v2.component.oob-otp-resend-button.default.label": "Resend code", "v2.component.password-input.default.hide-password": "Hide password", + "v2.component.password-input.default.placeholder-confirm-new-password": "Re-enter new password", "v2.component.password-input.default.placeholder-confirm-password": "Re-enter Password", "v2.component.password-input.default.placeholder-new-password": "New Password", "v2.component.password-input.default.placeholder-password": "Current Password", @@ -932,7 +937,6 @@ "v2.component.select-input.default.no-results-found": "No results found", "v2.component.select-input.default.not-provided-label": "Not provided", "v2.component.select-input.default.search-label": "Search", - "v2.component.select-input.default.unset-label": "Unset", "v2.component.toc-pp-footer.default.label": "By registering, you agree to the {variant, select, both{Terms of Service and Privacy Policy} termsOnly{Terms of Service} privacyOnly{Privacy Policy} other{}}", "v2.component.verify-bot-protection.default.description": "You will be redirected shortly after you completed the challenge", "v2.component.verify-bot-protection.default.title": "Checking your system...", @@ -1115,26 +1119,117 @@ "v2.page.select-account.default.description": "You have logged in with {email_is_present,select,true{{email}} other{{phone_number_is_present,select,true{{phone_number}} other{{preferred_username}}}}}. Proceed to continue.", "v2.page.select-account.default.title": "Log in to {AppOrClientName}", "v2.page.select-account.default.use-another-account": "Use another account", + "v2.page.settings-advanced-settings.default.title": "Advanced Settings", + "v2.page.settings-biometric.default.dialog-description": "Are you sure you want to disconnect biometric login for this device?", + "v2.page.settings-biometric.default.dialog-title": "Disconnect Biometric Login", + "v2.page.settings-biometric.default.disconnect-button-label": "Disconnect", + "v2.page.settings-biometric.default.item-description": "Created at {time, datetime, short} UTC", + "v2.page.settings-biometric.default.title": "Biometric Login", + "v2.page.settings-biometric.default.no-biometric-description": "You do not have any devices with biometrics enabled.", + "v2.page.settings-biometric.default.unknown-name-item-label": "Unknown Device", + "v2.page.settings-change-password.default.title": "Change Password", + "v2.page.settings-delete-account-success.default.button-label": "Done", + "v2.page.settings-delete-account-success.default.description": "Your account has been deactivated and the data will be deleted on {date, date, long}", + "v2.page.settings-delete-account-success.default.title": "Account deletion scheduled", + "v2.page.settings-delete-account.default.button-label": "Delete Account", + "v2.page.settings-delete-account.default.description": "By deleting the account, add data will be permanently deleted and we will not be able to retrieve it. If you continue, your account will be deleted on {date, date, long}", + "v2.page.settings-delete-account.default.input-placeholder": "Type {input} to confirm", + "v2.page.settings-delete-account.default.title": "Delete Account", + "v2.page.settings-edit-custom-attribute.default.custom-attribute-numeric-hint-maximum": "Please enter a number less than or equal to {maximum}", + "v2.page.settings-edit-custom-attribute.default.custom-attribute-numeric-hint-minimum": "Please enter a number greater than or equal to {minimum}", + "v2.page.settings-edit-custom-attribute.default.custom-attribute-numeric-hint-minimum-maximum": "Please enter a number between {minimum} and {maximum}", + "v2.page.settings-identity-add-email.default.email-input-placeholder": "New Email Address", + "v2.page.settings-identity-add-email.default.title": "Add New Email", + "v2.page.settings-identity-add-phone.default.title": "Add New Phone", + "v2.page.settings-identity-add-phone.default.phone-input-placeholder": "Phone Number", + "v2.page.settings-identity-change-primary-email.default.title": "Primary Email", + "v2.page.settings-identity-change-primary-phone.default.title": "Primary Phone", + "v2.page.settings-identity-edit-email.default.description": "Your current email is {target}", + "v2.page.settings-identity-edit-email.default.email-input-placeholder": "New Email Address", + "v2.page.settings-identity-edit-email.default.title": "Edit Email", + "v2.page.settings-identity-edit-phone.default.description": "Your current phone number is {target}", + "v2.page.settings-identity-edit-phone.default.title": "Edit Phone", + "v2.page.settings-identity-edit-phone.default.phone-input-placeholder": "Phone Number", + "v2.page.settings-identity-edit-username.default.title": "Change Username", + "v2.page.settings-identity-email.default.title": "Email", + "v2.page.settings-identity-list-email.default.button-add-email-label": "+ Add new email", + "v2.page.settings-identity-list-email.default.button-change-primary-email-label": "Change", + "v2.page.settings-identity-list-email.default.primary-email-label": "Primary email", + "v2.page.settings-identity-list-phone.default.button-add-phone-label": "+ Add new phone number", + "v2.page.settings-identity-list-phone.default.button-change-primary-phone-label": "Change", + "v2.page.settings-identity-list-phone.default.primary-phone-label": "Primary phone", + "v2.page.settings-identity-list-username.default.button-add-username-label": "+ Add username", + "v2.page.settings-identity-list-username.default.title": "Username", + "v2.page.settings-identity-new-username.default.title": "Add Username", + "v2.page.settings-identity-phone.default.title": "Phone", + "v2.page.settings-identity-verify-email.default.title": "Verification", + "v2.page.settings-identity-verify-phone.default.title": "Verification", + "v2.page.settings-identity-view-email.default.button-edit-email-label": "Edit", + "v2.page.settings-identity-view-email.default.button-remove-email-label": "Remove this email", + "v2.page.settings-identity-view-email.default.button-verify-email-label": "Verify", + "v2.page.settings-identity-view-email.default.remove-identity-dialog-description": "Are you sure you want to remove the email address {target} from your account?", + "v2.page.settings-identity-view-email.default.remove-identity-dialog-title": "Remove Email Address", + "v2.page.settings-identity-view-phone.default.button-edit-phone-label": "Edit", + "v2.page.settings-identity-view-phone.default.button-remove-phone-label": "Remove this phone", + "v2.page.settings-identity-view-phone.default.button-verify-phone-label": "Verify", + "v2.page.settings-identity-view-phone.default.remove-identity-dialog-description": "Are you sure you want to remove the phone number {target} from your account?", + "v2.page.settings-identity-view-phone.default.remove-identity-dialog-title": "Remove Phone Number", + "v2.page.settings-identity-view-username.default.button-remove-label": "Remove username", + "v2.page.settings-identity-view-username.default.dialog-delete-username-description": "Are you sure you want to remove username {Username} from your account?", + "v2.page.settings-identity-view-username.default.dialog-delete-username-title": "Remove Username", + "v2.page.settings-identity-view-username.default.title": "Username", + "v2.page.settings-identity.default.verification-status-unverified-label": "Not Verified", + "v2.page.settings-identity.default.verification-status-verified-label": "Verified", + "v2.page.settings-mfa-create-password.default.title": "Additional password", + "v2.page.settings-mfa-password.default.additional-password-added-at": "Added at {time, datetime, short} UTC", + "v2.page.settings-mfa-password.default.additional-password-label": "Additional password", + "v2.page.settings-mfa-password.default.additional-password-updated-at": "Updated at {time, datetime, short} UTC", + "v2.page.settings-mfa-password.default.dialog-delete-description": "Are you sure you want to remove additional password?", + "v2.page.settings-mfa-password.default.dialog-delete-title": "Remove additional password", + "v2.page.settings-mfa-password.default.title": "Additional password", + "v2.page.settings-mfa-password.default.remove-button-label": "Remove additional password", + "v2.page.settings-mfa.default.activated-label": "Activated", + "v2.page.settings-mfa.default.additional-password-label": "Additional password", + "v2.page.settings-mfa.default.dialog-revoke-device-description": "You have {NumberOfDeviceTokens, plural, one{# trusted device} other{# trusted devices}} trusted devices associated with your account. Do you want to remove all trusted devices?", + "v2.page.settings-mfa.default.dialog-revoke-device-title": "Remove trusted devices", + "v2.page.settings-mfa.default.inactive-label": "Inactive", + "v2.page.settings-mfa.default.title": "2-Factor Authentication", + "v2.page.settings-mfa.default.secondary-oob-otp-email-label": "Email", + "v2.page.settings-mfa.default.secondary-oob-otp-sms-label": "WhatsApp/SMS message", + "v2.page.settings-mfa.default.secondary-totp-label": "Authenticator app/device", + "v2.page.settings-mfa.default.trusted-devices-has-device-tokens-message": "You have {NumberOfDeviceTokens, plural, one{# trusted device} other{# trusted devices}}", + "v2.page.settings-mfa.default.trusted-devices-label": "Trusted devices", + "v2.page.settings-mfa.default.trusted-devices-no-device-tokens-message": "You do not have any trusted devices that can skip 2-step verification.", + "v2.page.settings-oob-otp-email.default.title": "Email", + "v2.page.settings-oob-otp-sms.default.title": "WhatsApp/SMS message", + "v2.page.settings-oob-otp.default.added-at-label": "Added at {time, datetime, short} UTC", + "v2.page.settings-oob-otp.default.button-oob-otp-email-label": "+ Add email", + "v2.page.settings-oob-otp.default.button-oob-otp-sms-label": "+ Add WhatsApp/SMS phone number", + "v2.page.settings-passkey.default.add-passkey-button-label": "+ Add passkey", + "v2.page.settings-passkey.default.dialog-description": "Are you sure you want to remove this passkey?", + "v2.page.settings-passkey.default.dialog-title": "Remove Passkey", + "v2.page.settings-passkey.default.item-description": "Added at {time, datetime, short} UTC", + "v2.page.settings-passkey.default.title": "Passkey", "v2.page.settings-profile-edit-address.default.country-label": "Country", "v2.page.settings-profile-edit-address.default.locality-label": "City", - "v2.page.settings-profile-edit-address.default.navbar-title": "Address", + "v2.page.settings-profile-edit-address.default.title": "Address", "v2.page.settings-profile-edit-address.default.postal-code-label": "Postal code", "v2.page.settings-profile-edit-address.default.region-label": "Region", "v2.page.settings-profile-edit-address.default.street-label": "Street address", - "v2.page.settings-profile-edit-birthdate.default.navbar-title": "Birthdate", + "v2.page.settings-profile-edit-birthdate.default.title": "Birthdate", "v2.page.settings-profile-edit-gender.default.gender-label-custom": "Custom", "v2.page.settings-profile-edit-gender.default.gender-label-female": "Female", "v2.page.settings-profile-edit-gender.default.gender-label-male": "Male", "v2.page.settings-profile-edit-gender.default.gender-label-unspecified": "Not provided", "v2.page.settings-profile-edit-gender.default.title": "Gender", - "v2.page.settings-profile-edit-locale.default.navbar-title": "Language", + "v2.page.settings-profile-edit-locale.default.title": "Language", "v2.page.settings-profile-edit-name.default.family-name-input-label": "Last name", "v2.page.settings-profile-edit-name.default.fullname-input-label": "Full name", "v2.page.settings-profile-edit-name.default.given-name-input-label": "First name", "v2.page.settings-profile-edit-name.default.middle-name-input-label": "Middle name", - "v2.page.settings-profile-edit-name.default.navbar-title": "Name", + "v2.page.settings-profile-edit-name.default.title": "Name", "v2.page.settings-profile-edit-name.default.nickname-input-label": "Nick name", - "v2.page.settings-profile-edit-zoneinfo.default.navbar-title": "Timezone", + "v2.page.settings-profile-edit-zoneinfo.default.title": "Timezone", "v2.page.settings-profile-no-permission.default.content": "Not authorized", "v2.page.settings-profile-no-permission.default.title": "Unexpected Issues", "v2.page.settings-profile.default.address-title": "Address", @@ -1146,9 +1241,21 @@ "v2.page.settings-profile.default.gender-title": "Gender", "v2.page.settings-profile.default.language-title": "Language", "v2.page.settings-profile.default.name-title": "Name", - "v2.page.settings-profile.default.navbar-title": "Profile", + "v2.page.settings-profile.default.title": "Profile", "v2.page.settings-profile.default.profile-picture-title": "Profile Picture", "v2.page.settings-profile.default.zoneinfo-title": "Timezone", + "v2.page.settings-sessions.default.all-sessions-dialog-description": "This will remove access to your account from all other devices", + "v2.page.settings-sessions.default.all-sessions-dialog-title": "Terminate all other sessions", + "v2.page.settings-sessions.default.country-ip-item-description": "{countryName} ({countryCode}) - {ip}", + "v2.page.settings-sessions.default.device-item-description": "{isCurrent, select, true {{desc} · Active Now} other {{desc} · {time, datetime, short} UTC}}", + "v2.page.settings-sessions.default.title": "Signed in Devices", + "v2.page.settings-sessions.default.revoke-all-label": "Terminate all other sessions", + "v2.page.settings-sessions.default.session-dialog-description": "This will remove access to your account on this device", + "v2.page.settings-sessions.default.session-dialog-title": "Terminate session", + "v2.page.settings-totp.default.added-at-label": "Added at {time, datetime, short} UTC", + "v2.page.settings-totp.default.button-add-authenticator-label": "+ Add authenticator app/device", + "v2.page.settings-totp.default.title": "Authenticator app/device", + "v2.page.settings.default.button-label-account-deletion": "Delete Account", "v2.page.settings.default.button-label-advanced-settings": "Advanced Settings", "v2.page.settings.default.button-label-and-more": "{item} and more", "v2.page.settings.default.button-label-back-to-app": "Back to my app", diff --git a/resources/authgear/templates/en/web/authflowv2/__error.html b/resources/authgear/templates/en/web/authflowv2/__error.html index d985bca8a4..34fe804136 100644 --- a/resources/authgear/templates/en/web/authflowv2/__error.html +++ b/resources/authgear/templates/en/web/authflowv2/__error.html @@ -1,4 +1,5 @@ {{- define "authflowv2/__error.html" -}} +{{ $dict := (dict "IdentityTypeIncoming" "other") }} {{ $display_error := false }} {{ if .Error }} {{ $display_error = true }} @@ -154,6 +155,9 @@ {{ else }} {{ include "v2.error.developer-email-required" nil }} {{ end }} + {{ else if eq .Error.reason "AccountManagementDuplicatedIdentity" }} + {{ $dict := (dict "IdentityTypeIncoming" "other") }} + {{ include "v2.error.account-conflict" $dict }} {{ else if eq .Error.reason "InvariantViolated" }} {{ $cause := .Error.info.cause }} {{ if (eq $cause.kind "RemoveLastIdentity") }} @@ -207,12 +211,12 @@ {{ if $error_reason.title }} {{ $error_reason.title }} {{ else }} - {{ if eq .Error.info.event_type "pre_signup" }} - {{ include "v2.error.webhook-pre-signup-disallowed" nil }} + {{ if eq .Error.info.event_type "pre_signup" }} + {{ include "v2.error.webhook-pre-signup-disallowed" nil }} {{ else }} {{ include "v2.error.webhook-disallowed" nil }} - {{ end }} - {{ end }} + {{ end }} + {{ end }} {{ if $error_reason.reason }}
{{ $error_reason.reason }} {{ end }} diff --git a/resources/authgear/templates/en/web/authflowv2/__new_password_field.html b/resources/authgear/templates/en/web/authflowv2/__new_password_field.html index 44b4c81f7f..1737d2ae46 100644 --- a/resources/authgear/templates/en/web/authflowv2/__new_password_field.html +++ b/resources/authgear/templates/en/web/authflowv2/__new_password_field.html @@ -40,6 +40,7 @@ "Type" "new-password" "AutoFocus" $.AutoFocus "PasswordRules" $.PasswordRules + "Placeholder" $.NewPasswordInputPlaceholder "InputAttrs" ` data-text-field-target="input" data-password-policy-target="input" @@ -66,6 +67,7 @@ "Classname" $confirm_pw_input_classname "Name" $.ConfirmPasswordInputName "Type" "confirm-password" + "Placeholder" $.ConfirmPasswordInputPlaceholder "InputAttrs" ` data-text-field-target="input" data-new-password-field-target="confirmPasswordInput" diff --git a/resources/authgear/templates/en/web/authflowv2/__otp_input.html b/resources/authgear/templates/en/web/authflowv2/__otp_input.html index 0fe2a25fbd..87346bf0b1 100644 --- a/resources/authgear/templates/en/web/authflowv2/__otp_input.html +++ b/resources/authgear/templates/en/web/authflowv2/__otp_input.html @@ -69,6 +69,7 @@ data-action="submit->turbo-form#submitForm" > {{ $.CSRFField }} + {{ $.ResendFormContent }} + {{ template "authflowv2/__settings_dialog.html" (dict + "Ctx" . + "DialogID" "remove-male-dialog" + "Title" "Dialog Title" + "Description" "Dialog description" + "FormContent" (include "inputs" (dict "value" "male")) + "Buttons" (list + (dict + "Type" "Destructive" + "Label" (include "v2.component.button.default.label-remove" nil) + "Value" "remove" + "Event" "authgear.button.sign_in" + ) + (dict + "Type" "Cancel" + "Label" (include "v2.component.button.default.label-cancel" nil) + ) + ) + )}} +*/}} + +{{ define "authflowv2/__settings_dialog.html" }} +{{ template "authflowv2/__dialog.html" + (dict + "Ctx" $.Ctx + "DialogID" $.DialogID + "ClassName" "settings-dialog" + "DialogContent" (include "authflowv2/__settings_dialog_content.html" + (dict + "Ctx" $.Ctx + "Title" $.Title + "Description" $.Description + "FormContent" $.FormContent + "Buttons" $.Buttons + ) + ) + ) +}} +{{ end }} + +{{ define "authflowv2/__settings_dialog_content.html" }} +
+
+
+

+ {{ $.Title }} +

+

+ {{ $.Description }} +

+
+
+ {{ $.FormContent }} + {{ range $.Buttons }} + + {{ end }} +
+
+
+{{ end }} diff --git a/resources/authgear/templates/en/web/authflowv2/__settings_item.html b/resources/authgear/templates/en/web/authflowv2/__settings_item.html index 4fd98b395f..367118db4d 100644 --- a/resources/authgear/templates/en/web/authflowv2/__settings_item.html +++ b/resources/authgear/templates/en/web/authflowv2/__settings_item.html @@ -4,6 +4,7 @@ "Label" (include "some-key" nil) "Href" "url" "MaterialIconName" `email` + "SupplementaryNote" "some content" "Children" $.Emails ) }} @@ -19,6 +20,9 @@ {{ else }} without-content {{ end }} + {{ if $.SupplementaryNote }} + with-note + {{end }} " {{ if $.Href }} href="{{ $.Href }}" @@ -35,10 +39,16 @@ {{ $.Label }}

+ {{ if $.SupplementaryNote }} +
+ {{ $.SupplementaryNote }} +
+ {{ end }} + {{/* If there is content */}} {{ if $.Children }} {{ $length := len $.Children }} -

+

{{ $item := index $.Children 0}} {{ if gt $length 1 }} {{ include "v2.page.settings.default.button-label-and-more" (dict "item" $item ) }} @@ -46,7 +56,7 @@ {{ $item }} {{ end }}

-