package projection import ( "context" "database/sql" "time" "github.com/zitadel/zitadel/backend/v3/domain" "github.com/zitadel/zitadel/backend/v3/storage/database" v3_sql "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/sql" "github.com/zitadel/zitadel/backend/v3/storage/database/repository" "github.com/zitadel/zitadel/internal/crypto" old_domain "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/eventstore/handler/v2" "github.com/zitadel/zitadel/internal/repository/user" "github.com/zitadel/zitadel/internal/zerrors" ) func (p *relationalTablesProjection) reduceHumanAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } v3Tx := v3_sql.SQLTx(tx) userRepo := repository.UserRepository() var phone *domain.HumanPhone if e.PhoneNumber != "" { phone = &domain.HumanPhone{ UnverifiedNumber: string(e.PhoneNumber), } } password := domain.HumanPassword{ IsChangeRequired: e.ChangeRequired, } if hash := crypto.SecretOrEncodedHash(e.Secret, e.EncodedHash); hash != "" { password.Hash = hash password.ChangedAt = e.CreatedAt() } return userRepo.Create(ctx, v3Tx, &domain.User{ InstanceID: e.Aggregate().InstanceID, OrganizationID: e.Aggregate().ResourceOwner, ID: e.Aggregate().ID, Username: e.UserName, State: domain.UserStateActive, CreatedAt: e.CreatedAt(), UpdatedAt: e.CreatedAt(), Human: &domain.HumanUser{ FirstName: e.FirstName, LastName: e.LastName, Nickname: e.NickName, DisplayName: e.DisplayName, PreferredLanguage: e.PreferredLanguage, Gender: mapHumanGender(e.Gender), Email: domain.HumanEmail{ UnverifiedAddress: string(e.EmailAddress), }, Phone: phone, Password: password, }, }) }), nil } func (p *relationalTablesProjection) reduceHumanRegistered(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanRegisteredEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } v3Tx := v3_sql.SQLTx(tx) userRepo := repository.UserRepository() var phone *domain.HumanPhone if e.PhoneNumber != "" { phone = &domain.HumanPhone{ UnverifiedNumber: string(e.PhoneNumber), } } password := domain.HumanPassword{ IsChangeRequired: e.ChangeRequired, } if hash := crypto.SecretOrEncodedHash(e.Secret, e.EncodedHash); hash != "" { password.Hash = hash password.ChangedAt = e.CreatedAt() } return userRepo.Create(ctx, v3Tx, &domain.User{ InstanceID: e.Aggregate().InstanceID, OrganizationID: e.Aggregate().ResourceOwner, ID: e.Aggregate().ID, Username: e.UserName, State: domain.UserStateActive, CreatedAt: e.CreatedAt(), UpdatedAt: e.CreatedAt(), Human: &domain.HumanUser{ FirstName: e.FirstName, LastName: e.LastName, Nickname: e.NickName, DisplayName: e.DisplayName, PreferredLanguage: e.PreferredLanguage, Gender: mapHumanGender(e.Gender), Email: domain.HumanEmail{ UnverifiedAddress: string(e.EmailAddress), }, Phone: phone, Password: password, }, }) }), nil } func (p *relationalTablesProjection) reduceUserLocked(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserLockedEvent](event) if err != nil { return nil, err } return handler.NewMultiStatement(e, handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() _, err := repo.Update( ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID), repo.SetState(domain.UserStateLocked), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-fcxV68", "reduce.wrong.db.pool %T", ex) } v3Tx := v3_sql.SQLTx(tx) sessionRepo := repository.SessionRepository() condition := database.And( sessionRepo.InstanceIDCondition(event.Aggregate().InstanceID), sessionRepo.UserIDCondition(event.Aggregate().ID), ) _, err := sessionRepo.Delete(ctx, v3Tx, condition) return err }), ), nil } func (p *relationalTablesProjection) reduceUserUnlocked(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserUnlockedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() _, err := repo.Update( ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID), repo.SetState(domain.UserStateActive), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceUserDeactivated(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserDeactivatedEvent](event) if err != nil { return nil, err } return handler.NewMultiStatement(event, handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() _, err := repo.Update( ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID), repo.SetState(domain.UserStateInactive), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-fcxV68", "reduce.wrong.db.pool %T", ex) } v3Tx := v3_sql.SQLTx(tx) sessionRepo := repository.SessionRepository() condition := database.And( sessionRepo.InstanceIDCondition(event.Aggregate().InstanceID), sessionRepo.UserIDCondition(event.Aggregate().ID), ) _, err := sessionRepo.Delete(ctx, v3Tx, condition) return err }), ), nil } func (p *relationalTablesProjection) reduceUserReactivated(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserReactivatedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() _, err := repo.Update( ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID), repo.SetState(domain.UserStateActive), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceUserRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() _, err := repo.Delete( ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID), ) return err }), nil } func (p *relationalTablesProjection) reduceUsernameChanged(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UsernameChangedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() _, err := repo.Update( ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID), repo.SetUsername(e.UserName), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceUserDomainClaimed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.DomainClaimedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } userRepo := repository.UserRepository() _, err := userRepo.Update(ctx, v3_sql.SQLTx(tx), userRepo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), userRepo.SetUsername(e.UserName), userRepo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanProfileChanged(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanProfileChangedEvent](event) if err != nil { return nil, err } repo := repository.UserRepository().Human() changes := make([]database.Change, 0, 7) if e.FirstName != "" { changes = append(changes, repo.SetFirstName(e.FirstName)) } if e.LastName != "" { changes = append(changes, repo.SetLastName(e.LastName)) } if e.NickName != nil { changes = append(changes, repo.SetNickname(*e.NickName)) } if e.DisplayName != nil { changes = append(changes, repo.SetDisplayName(*e.DisplayName)) } if e.PreferredLanguage != nil { changes = append(changes, repo.SetPreferredLanguage(*e.PreferredLanguage)) } if e.Gender != nil { changes = append(changes, repo.SetGender(mapHumanGender(*e.Gender))) } changes = append(changes, repo.SetUpdatedAt(e.CreatedAt())) return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Agg.InstanceID, e.Aggregate().ID), changes..., ) return err }), nil } func (p *relationalTablesProjection) reduceHumanPhoneChanged(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPhoneChangedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetUnverifiedPhone(string(e.PhoneNumber)), repo.SetPhoneVerification(&domain.VerificationTypeInit{ CreatedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanPhoneRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPhoneRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemovePhone(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanPhoneVerified(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPhoneVerifiedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetPhoneVerification(&domain.VerificationTypeSucceeded{ VerifiedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanPhoneCodeAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPhoneCodeAddedEvent](event) if err != nil { return nil, err } var expiry *time.Duration if e.Expiry > 0 { expiry = &e.Expiry } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Human() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetPhoneVerification(&domain.VerificationTypeUpdate{ Code: e.Code, Expiry: expiry, }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanPhoneVerificationFailed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPhoneVerificationFailedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Human() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetPhoneVerification(&domain.VerificationTypeFailed{ FailedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanEmailChanged(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanEmailChangedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Human() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetUnverifiedEmail(string(e.EmailAddress)), repo.SetEmailVerification(&domain.VerificationTypeInit{ CreatedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanEmailVerified(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanEmailVerifiedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Human() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetEmailVerification(&domain.VerificationTypeSucceeded{ VerifiedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanEmailCodeAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanEmailCodeAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Human() var expiry *time.Duration if e.Expiry > 0 { expiry = &e.Expiry } _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetEmailVerification(&domain.VerificationTypeUpdate{ Code: e.Code, Expiry: expiry, }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanEmailVerificationFailed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanEmailVerificationFailedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Human() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetEmailVerification(&domain.VerificationTypeFailed{ FailedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanAvatarAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanAvatarAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Human() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetAvatarKey(&e.StoreKey), repo.SetUpdatedAt(e.CreationDate()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanAvatarRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanAvatarRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Human() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetAvatarKey(nil), repo.SetUpdatedAt(e.CreationDate()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanPasswordChanged(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPasswordChangedEvent](event) if err != nil { return nil, err } return handler.NewMultiStatement(e, handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetPasswordChangeRequired(e.ChangeRequired), repo.SetPassword(crypto.SecretOrEncodedHash(e.Secret, e.EncodedHash)), repo.SetResetPasswordVerification(&domain.VerificationTypeSucceeded{VerifiedAt: e.CreatedAt()}), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), handler.AddStatement(func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } v3Tx := v3_sql.SQLTx(tx) sessionRepo := repository.SessionRepository() condition := database.And( sessionRepo.InstanceIDCondition(e.Aggregate().InstanceID), sessionRepo.UserIDCondition(e.Aggregate().ID), sessionRepo.ExistsFactor( database.And( sessionRepo.FactorConditions().FactorTypeCondition(domain.SessionFactorTypePassword), sessionRepo.FactorConditions().LastVerifiedBeforeCondition(e.CreatedAt()), ), ), ) _, err = sessionRepo.Update(ctx, v3Tx, condition, sessionRepo.SetUpdatedAt(e.CreatedAt()), sessionRepo.ClearFactor(domain.SessionFactorTypePassword), ) return err }), ), nil } func (p *relationalTablesProjection) reduceHumanPasswordCodeAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPasswordCodeAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() var expiry *time.Duration if e.Expiry > 0 { expiry = &e.Expiry } _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetResetPasswordVerification(&domain.VerificationTypeUpdate{ Code: e.Code, Expiry: expiry, }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanPasswordCheckSucceeded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPasswordCheckSucceededEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetLastSuccessfulPasswordCheck(e.CreatedAt()), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanPasswordCheckFailed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPasswordCheckFailedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.IncrementPasswordFailedAttempts(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceHumanPasswordHashUpdated(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPasswordHashUpdatedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetPassword(e.EncodedHash), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceMachineSecretSet(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MachineSecretSetEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.MachineUserRepository() secret := crypto.SecretOrEncodedHash(e.ClientSecret, e.HashedSecret) _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetSecret(&secret), repo.SetUpdatedAt(e.CreationDate()), ) return err }), nil } func (p *relationalTablesProjection) reduceMachineSecretHashUpdated(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MachineSecretHashUpdatedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Machine() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetSecret(&e.HashedSecret), repo.SetUpdatedAt(e.CreationDate()), ) return err }), nil } func (p *relationalTablesProjection) reduceMachineSecretRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MachineSecretRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository().Machine() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetSecret(nil), repo.SetUpdatedAt(e.CreationDate()), ) return err }), nil } func (p *relationalTablesProjection) reduceMachineKeyAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MachineKeyAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.MachineUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.AddKey(&domain.MachineKey{ ID: e.KeyID, Type: mapMachineKeyType(e.KeyType), PublicKey: e.PublicKey, CreatedAt: e.CreatedAt(), ExpiresAt: e.ExpirationDate, }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceMachineKeyRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MachineKeyRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.MachineUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemoveKey(e.KeyID), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceMachineAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MachineAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() return repo.Create(ctx, v3_sql.SQLTx(tx), &domain.User{ ID: e.Aggregate().ID, InstanceID: e.Aggregate().InstanceID, OrganizationID: e.Aggregate().ResourceOwner, Username: e.UserName, State: domain.UserStateActive, CreatedAt: e.CreatedAt(), UpdatedAt: e.CreatedAt(), Machine: &domain.MachineUser{ Name: e.Name, Description: e.Description, AccessTokenType: mapMachineAccessTokenType(e.AccessTokenType), }, }, ) }), nil } func (p *relationalTablesProjection) reduceMachineChanged(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MachineChangedEvent](event) if err != nil { return nil, err } repo := repository.MachineUserRepository() changes := make([]database.Change, 0, 4) if e.Name != nil { changes = append(changes, repo.SetName(*e.Name)) } if e.Description != nil { changes = append(changes, repo.SetDescription(*e.Description)) } if e.AccessTokenType != nil { changes = append(changes, repo.SetAccessTokenType(mapMachineAccessTokenType(*e.AccessTokenType))) } changes = append(changes, repo.SetUpdatedAt(e.CreatedAt())) return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } _, err := repo.Update(ctx, v3_sql.SQLTx(tx), database.And( repo.InstanceIDCondition(e.Aggregate().InstanceID), repo.IDCondition(e.Aggregate().ID), ), changes..., ) return err }), nil } func (p *relationalTablesProjection) reducePersonalAccessTokenAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.PersonalAccessTokenAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.MachineUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.AddPersonalAccessToken(&domain.PersonalAccessToken{ ID: e.TokenID, Scopes: e.Scopes, ExpiresAt: e.Expiration, CreatedAt: e.CreatedAt(), }), ) return err }), nil } func (p *relationalTablesProjection) reducePersonalAccessTokenRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.PersonalAccessTokenRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.MachineUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemovePersonalAccessToken(e.TokenID), ) return err }), nil } func (p *relationalTablesProjection) reduceUserMetadataSet(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MetadataSetEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-xg4IJ", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetMetadata(&domain.Metadata{ Key: e.Key, Value: e.Value, CreatedAt: e.CreationDate(), UpdatedAt: e.CreationDate(), }), ) return err }), nil } func (p *relationalTablesProjection) reduceUserMetadataRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MetadataRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-xg4IJ", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemoveMetadata(repo.MetadataConditions().MetadataKeyCondition(database.TextOperationEqual, e.Key)), ) return err }), nil } func (p *relationalTablesProjection) reduceUserMetadataRemovedAll(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.MetadataRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-xg4IJ", "reduce.wrong.db.pool %T", ex) } repo := repository.UserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemoveMetadata(nil), ) return err }), nil } func (p *relationalTablesProjection) reducePasskeyAdded(event eventstore.Event) (*handler.Statement, error) { var ( e user.HumanWebAuthNAddedEvent typ domain.PasskeyType ) switch typed := event.(type) { case *user.HumanPasswordlessAddedEvent: e = typed.HumanWebAuthNAddedEvent typ = domain.PasskeyTypePasswordless case *user.HumanU2FAddedEvent: e = typed.HumanWebAuthNAddedEvent typ = domain.PasskeyTypeU2F default: return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-nd7f3", "reduce.wrong.event.type for passkey %s", event.Type()) } return handler.NewStatement(&e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), database.And( repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), ), repo.AddPasskey(&domain.Passkey{ ID: e.WebAuthNTokenID, Challenge: []byte(e.Challenge), RelyingPartyID: e.RPID, CreatedAt: e.CreatedAt(), UpdatedAt: e.CreatedAt(), Type: typ, }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reducePasskeyVerified(event eventstore.Event) (*handler.Statement, error) { var ( e user.HumanWebAuthNVerifiedEvent ) switch typed := event.(type) { case *user.HumanPasswordlessVerifiedEvent: e = typed.HumanWebAuthNVerifiedEvent case *user.HumanU2FVerifiedEvent: e = typed.HumanWebAuthNVerifiedEvent default: return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-nd7f3", "reduce.wrong.event.type for passkey %s", event.Type()) } return handler.NewStatement(&e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.UpdatePasskey( repo.PasskeyConditions().IDCondition(e.WebAuthNTokenID), repo.SetPasskeyKeyID(e.KeyID), repo.SetPasskeyPublicKey(e.PublicKey), repo.SetPasskeyAttestationType(e.AttestationType), repo.SetPasskeyAuthenticatorAttestationGUID(e.AAGUID), repo.SetPasskeySignCount(e.SignCount), repo.SetPasskeyName(e.WebAuthNTokenName), repo.SetPasskeyUpdatedAt(e.CreatedAt()), ), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reducePasskeySignCountSet(event eventstore.Event) (*handler.Statement, error) { var ( e user.HumanWebAuthNSignCountChangedEvent ) switch typed := event.(type) { case *user.HumanPasswordlessSignCountChangedEvent: e = typed.HumanWebAuthNSignCountChangedEvent case *user.HumanU2FSignCountChangedEvent: e = typed.HumanWebAuthNSignCountChangedEvent default: return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-nd7f3", "reduce.wrong.event.type for passkey %s", event.Type()) } return handler.NewStatement(&e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.UpdatePasskey( repo.PasskeyConditions().IDCondition(e.WebAuthNTokenID), repo.SetPasskeySignCount(e.SignCount), ), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reducePasskeyRemoved(event eventstore.Event) (*handler.Statement, error) { var ( e user.HumanWebAuthNRemovedEvent ) switch typed := event.(type) { case *user.HumanPasswordlessRemovedEvent: e = typed.HumanWebAuthNRemovedEvent case *user.HumanU2FRemovedEvent: e = typed.HumanWebAuthNRemovedEvent default: return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-nd7f3", "reduce.wrong.event.type for passkey %s", event.Type()) } return handler.NewStatement(&e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } userRepo := repository.UserRepository() humanRepo := userRepo.Human() _, err := userRepo.Update(ctx, v3_sql.SQLTx(tx), userRepo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), humanRepo.RemovePasskey(humanRepo.PasskeyConditions().IDCondition(e.WebAuthNTokenID)), humanRepo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reducePasskeyInitCodeAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPasswordlessInitCodeAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetVerification(&domain.VerificationTypeInit{ ID: &e.ID, Code: e.Code, CreatedAt: e.CreatedAt(), Expiry: &e.Expiry, }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reducePasskeyInitCodeCheckFailed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPasswordlessInitCodeCheckFailedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetVerification(&domain.VerificationTypeFailed{ ID: &e.ID, FailedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reducePasskeyInitCodeCheckSucceeded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPasswordlessInitCodeCheckSucceededEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetVerification(&domain.VerificationTypeSucceeded{ ID: &e.ID, VerifiedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reducePasskeyInitCodeRequested(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanPasswordlessInitCodeRequestedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetVerification(&domain.VerificationTypeInit{ ID: &e.ID, Code: e.Code, CreatedAt: e.CreatedAt(), Expiry: &e.Expiry, }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceMFAInitSkipped(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanMFAInitSkippedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SkipMultifactorInitializationAt(e.CreatedAt()), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceIDPLinkAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserIDPLinkAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.AddIdentityProviderLink(&domain.IdentityProviderLink{ ProviderID: e.IDPConfigID, ProvidedUserID: e.ExternalUserID, ProvidedUsername: e.DisplayName, CreatedAt: e.CreatedAt(), UpdatedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceIDPLinkCascadeRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserIDPLinkCascadeRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemoveIdentityProviderLink(e.IDPConfigID, e.ExternalUserID), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceIDPLinkRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserIDPLinkRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemoveIdentityProviderLink(e.IDPConfigID, e.ExternalUserID), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceIDPLinkUserIDMigrated(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserIDPExternalIDMigratedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.UpdateIdentityProviderLink( database.And(repo.IdentityProviderLinkConditions().ProviderIDCondition(e.IDPConfigID), repo.IdentityProviderLinkConditions().ProvidedUserIDCondition(e.PreviousID)), repo.SetIdentityProviderLinkProvidedID(e.NewID), ), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceIDPLinkUsernameChanged(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.UserIDPExternalUsernameEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.UpdateIdentityProviderLink( database.And(repo.IdentityProviderLinkConditions().ProviderIDCondition(e.IDPConfigID), repo.IdentityProviderLinkConditions().ProvidedUserIDCondition(e.ExternalUserID)), repo.SetIdentityProviderLinkUsername(e.ExternalUsername), ), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceTOTPAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetTOTPSecret(e.Secret), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceTOTPVerified(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPVerifiedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetTOTPVerifiedAt(e.CreatedAt()), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceTOTPRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemoveTOTP(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceTOTPCheckSucceeded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPCheckSucceededEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetLastSuccessfulTOTPCheck(e.CreatedAt()), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceTOTPCheckFailed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPCheckFailedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.IncrementTOTPFailedAttempts(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceOTPSMSEnabled(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPSMSAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.EnableSMSOTPAt(e.CreatedAt()), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceOTPSMSDisabled(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPSMSRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.DisableSMSOTP(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceOTPSMSCheckSucceeded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPSMSCheckSucceededEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetLastSuccessfulSMSOTPCheck(e.CreatedAt()), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceOTPSMSCheckFailed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPSMSCheckFailedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.IncrementSMSOTPFailedAttempts(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceOTPEmailEnabled(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPEmailAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.EnableEmailOTPAt(e.CreatedAt()), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceOTPEmailDisabled(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPEmailRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.DisableEmailOTP(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceOTPEmailCheckSucceeded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPEmailCheckSucceededEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetLastSuccessfulEmailOTPCheck(e.CreatedAt()), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceOTPEmailCheckFailed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanOTPEmailCheckFailedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.IncrementEmailOTPFailedAttempts(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceInviteCodeAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanInviteCodeAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } var expiry *time.Duration if e.Expiry > 0 { expiry = &e.Expiry } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetInviteVerification(&domain.VerificationTypeInit{ CreatedAt: e.CreatedAt(), Code: e.Code, Expiry: expiry, }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceInviteCheckSucceeded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanInviteCheckSucceededEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetInviteVerification(&domain.VerificationTypeSucceeded{ VerifiedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceInviteCheckFailed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanInviteCheckFailedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-iZGH3", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.SetInviteVerification(&domain.VerificationTypeFailed{ FailedAt: e.CreatedAt(), }), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceRecoveryCodesAdded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanRecoveryCodesAddedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-oqwfuV", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.AddRecoveryCodes(e.Codes), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceRecoveryCodesRemoved(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanRecoveryCodesRemovedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-ZueNKs", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemoveAllRecoveryCodes(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceRecoveryCodeCheckSucceeded(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanRecoveryCodeCheckSucceededEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-wr8WuW", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.RemoveRecoveryCode(e.CodeChecked), repo.SetLastSuccessfulRecoveryCodeCheck(e.CreatedAt()), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func (p *relationalTablesProjection) reduceRecoveryCodeCheckFailed(event eventstore.Event) (*handler.Statement, error) { e, err := assertEvent[*user.HumanRecoveryCodeCheckFailedEvent](event) if err != nil { return nil, err } return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, _ string) error { tx, ok := ex.(*sql.Tx) if !ok { return zerrors.ThrowInvalidArgumentf(nil, "HANDL-mWuV7a", "reduce.wrong.db.pool %T", ex) } repo := repository.HumanUserRepository() _, err := repo.Update(ctx, v3_sql.SQLTx(tx), repo.PrimaryKeyCondition(e.Aggregate().InstanceID, e.Aggregate().ID), repo.IncrementRecoveryCodeFailedAttempts(), repo.SetUpdatedAt(e.CreatedAt()), ) return err }), nil } func mapHumanGender(gender old_domain.Gender) domain.HumanGender { switch gender { case old_domain.GenderFemale: return domain.HumanGenderFemale case old_domain.GenderMale: return domain.HumanGenderMale case old_domain.GenderDiverse: return domain.HumanGenderDiverse case old_domain.GenderUnspecified: fallthrough default: return domain.HumanGenderUnspecified } } func mapMachineAccessTokenType(tokenType old_domain.OIDCTokenType) domain.AccessTokenType { switch tokenType { case old_domain.OIDCTokenTypeBearer: return domain.AccessTokenTypeBearer case old_domain.OIDCTokenTypeJWT: return domain.AccessTokenTypeJWT default: return domain.AccessTokenTypeUnspecified } } func mapMachineKeyType(keyType old_domain.AuthNKeyType) domain.MachineKeyType { switch keyType { case old_domain.AuthNKeyTypeJSON: return domain.MachineKeyTypeJSON case old_domain.AuthNKeyTypeNONE: fallthrough default: return domain.MachineKeyTypeNone } }