package runtime import ( "context" "git.sendico.io/tech/sxchnge/product/app/api" "git.sendico.io/tech/sxchnge/product/auth/config" "git.sendico.io/tech/sxchnge/product/auth/flow" "git.sendico.io/tech/sxchnge/product/auth/storage" "git.sendico.io/tech/sxchnge/product/customers" "git.sendico.io/tech/sxchnge/product/identity" "git.sendico.io/tech/sxchnge/product/notifications" "git.sendico.io/tech/sxchnge/product/providers/sendico" "git.sendico.io/tech/sxchnge/product/twofactor" "git.sendico.io/tech/sxchnge/product/twofactor/delivery" factorstore "git.sendico.io/tech/sxchnge/product/twofactor/store" "git.sendico.io/tech/sxchnge/shared/database" merrors "git.sendico.io/tech/sxchnge/shared/errors" "git.sendico.io/tech/sxchnge/shared/logging" "go.uber.org/zap" ) func OpenDependencies(_ context.Context, logger mlogger.Logger, config *api.Config, db db.Factory) (_ *api.Dependencies, _ func(context.Context) error, result error) { limits, err := config.Mw.ResolveLoginRateLimits() if err != nil { return nil, nil, err } stores, err := storage.OpenStores(logger, db, config.AuthStorage) if err != nil { return nil, nil, err } customers, err := accountservice.FromStores(logger, &config.Mw.Password, stores, db.TransactionFactory()) if err != nil { return nil, nil, err } deps := &api.Dependencies{Stores: stores, Customers: customers, Token: config.Mw.Token, Signature: middleware.SignatureConf(config.Mw), LoginLimits: limits} var client *notifications.Client cleanup := func(context.Context) error { if client != nil { return client.Close() } return nil } defer func() { if result != nil { if err := cleanup(context.Background()); err != nil { logger.Warn("Partial bootstrap cleanup failed", zap.Error(err)) } } }() if c := config.Notifications; c != nil { deps.Auth = &flow.Service{Accounts: stores.Accounts, Customers: customers, Tokens: stores.Verification, Transactions: db.TransactionFactory(), Attempts: stores.LoginAttempts, Secret: deps.Signature.PrivateKey, ActivationURL: c.ActivationURL} if err := deps.Auth.Validate(); err != nil { return nil, nil, err } client, err = notifications.Open(*c) if err != nil { return nil, nil, err } deps.Auth.Sender = client if config.Sendico != nil { provider, err := sendico.Open(*config.Sendico) if err != nil { return nil, nil, err } bindings, err := identity.OpenStore(db) if err != nil { return nil, nil, err } deps.Identity = &identity.Service{Store: bindings, Provider: provider, Logger: logger.Named("identity")} deps.Auth.Facts = deps.Identity logger.Info("Sendico sign-up facts integration enabled") } records, err := factorstore.Open(logger, db) if err != nil { return nil, nil, err } deps.Factors, err = twofactor.New(stores.Accounts, stores.Verification, records, db.TransactionFactory(), deps.Signature.PrivateKey, logger, delivery.Email{Sender: client}) if err != nil { return nil, nil, err } } if config.Sendico != nil && deps.Auth == nil { return nil, nil, merrors.InvalidArgument("Sendico sign-up facts require notifications configuration") } logger.Info("Product dependencies initialized") return deps, cleanup, nil }