package setup import ( "bytes" "strings" "time" "github.com/mitchellh/mapstructure" "github.com/spf13/viper" "github.com/zitadel/logging" "github.com/zitadel/zitadel/cmd/encryption" "github.com/zitadel/zitadel/cmd/hooks" "github.com/zitadel/zitadel/internal/actions" "github.com/zitadel/zitadel/internal/api/authz" "github.com/zitadel/zitadel/internal/api/oidc" "github.com/zitadel/zitadel/internal/api/ui/login" "github.com/zitadel/zitadel/internal/command" "github.com/zitadel/zitadel/internal/config/hook" "github.com/zitadel/zitadel/internal/config/systemdefaults" "github.com/zitadel/zitadel/internal/database" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/id" "github.com/zitadel/zitadel/internal/notification/handlers" "github.com/zitadel/zitadel/internal/query/projection" static_config "github.com/zitadel/zitadel/internal/static/config" ) type Config struct { Database database.Config SystemDefaults systemdefaults.SystemDefaults InternalAuthZ authz.Config ExternalDomain string ExternalPort uint16 ExternalSecure bool Log *logging.Config EncryptionKeys *encryption.EncryptionKeyConfig DefaultInstance command.InstanceSetup Machine *id.Config Projections projection.Config Eventstore *eventstore.Config InitProjections InitProjections AssetStorage static_config.AssetStorageConfig OIDC oidc.Config Login login.Config WebAuthNName string Telemetry *handlers.TelemetryPusherConfig SystemAPIUsers map[string]*authz.SystemAPIUser } type InitProjections struct { Enabled bool RetryFailedAfter time.Duration MaxFailureCount uint8 BulkLimit uint64 } func MustNewConfig(v *viper.Viper) *Config { config := new(Config) err := v.Unmarshal(config, viper.DecodeHook(mapstructure.ComposeDecodeHookFunc( hook.Base64ToBytesHookFunc(), hook.TagToLanguageHookFunc(), mapstructure.StringToTimeDurationHookFunc(), mapstructure.StringToTimeHookFunc(time.RFC3339), mapstructure.StringToSliceHookFunc(","), database.DecodeHook, hook.EnumHookFunc(authz.MemberTypeString), actions.HTTPConfigDecodeHook, hooks.MapTypeStringDecode[string, *authz.SystemAPIUser], )), ) logging.OnError(err).Fatal("unable to read default config") err = config.Log.SetLogger() logging.OnError(err).Fatal("unable to set logger") id.Configure(config.Machine) return config } type Steps struct { s1ProjectionTable *ProjectionTable s2AssetsTable *AssetTable FirstInstance *FirstInstance s5LastFailed *LastFailed s6OwnerRemoveColumns *OwnerRemoveColumns s7LogstoreTables *LogstoreTables s8AuthTokens *AuthTokenIndexes CorrectCreationDate *CorrectCreationDate s12AddOTPColumns *AddOTPColumns s13FixQuotaProjection *FixQuotaConstraints s14NewEventsTable *NewEventsTable s15CurrentStates *CurrentProjectionState s16UniqueConstraintsLower *UniqueConstraintToLower s17AddOffsetToUniqueConstraints *AddOffsetToCurrentStates s18AddLowerFieldsToLoginNames *AddLowerFieldsToLoginNames s19AddCurrentStatesIndex *AddCurrentSequencesIndex s20AddByUserSessionIndex *AddByUserIndexToSession s21AddBlockFieldToLimits *AddBlockFieldToLimits s22ActiveInstancesIndex *ActiveInstanceEvents s23CorrectGlobalUniqueConstraints *CorrectGlobalUniqueConstraints s24AddActorToAuthTokens *AddActorToAuthTokens s25AddLowerFieldsToVerifiedEmail *AddLowerFieldsToVerifiedEmail } func MustNewSteps(v *viper.Viper) *Steps { v.AutomaticEnv() v.SetEnvPrefix("ZITADEL") v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) v.SetConfigType("yaml") err := v.ReadConfig(bytes.NewBuffer(defaultSteps)) logging.OnError(err).Fatal("unable to read setup steps") for _, file := range stepFiles { v.SetConfigFile(file) err := v.MergeInConfig() logging.WithFields("file", file).OnError(err).Warn("unable to read setup file") } steps := new(Steps) err = v.Unmarshal(steps, viper.DecodeHook(mapstructure.ComposeDecodeHookFunc( hook.Base64ToBytesHookFunc(), hook.TagToLanguageHookFunc(), mapstructure.StringToTimeDurationHookFunc(), mapstructure.StringToTimeHookFunc(time.RFC3339), mapstructure.StringToSliceHookFunc(","), )), ) logging.OnError(err).Fatal("unable to read steps") return steps }