mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-23 07:52:15 +00:00
# Which Problems Are Solved Adds a repository implementation to add/remove recovery codes to the users relational table. # How the Problems Are Solved This is achieved by: * adding the following columns to the users table: `recovery_codes`, `recovery_code_last_successful_check`, `recovery_code_failed_attempts` * adding the `RecoveryCodes` field to the `HumanUser` domain with fields to set recovery `codes`, `lastSuccessfullyCheckedAt` timestamp, and `failedAttempts` * setting `recoveryCodes` in the `Get` user query statement to return a json object with details related to the recovery codes * adding the repository-layer implementation to add/remove recovery codes and set fields related to recovery code checks. * adding projection reducers to handle the following events: `HumanRecoveryCodesAddedEvent`, `HumanRecoveryCodesRemovedEvent`, `HumanRecoveryCodeCheckSucceededEvent`, and `HumanRecoveryCodeCheckFailedEvent` * adding unit tests # Additional Changes * fix the error message when the recovery is empty in `internal/command/user_human_recovery_codes.go` * add a new error message for empty recovery code during checks in `en.yaml` # Additional Context - Closes https://github.com/zitadel/zitadel/issues/11212 - Follow-up: integration tests for the reducers will be added in a different PR after this [PR](https://github.com/zitadel/zitadel/pull/11478) is merged
2252 lines
71 KiB
Go
2252 lines
71 KiB
Go
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"
|
|
)
|
|
|
|
const (
|
|
UserRelationProjectionTable = "zitadel.users"
|
|
)
|
|
|
|
type userRelationalProjection struct{}
|
|
|
|
func (*userRelationalProjection) Name() string {
|
|
return UserRelationProjectionTable
|
|
}
|
|
|
|
func newUserRelationalProjection(ctx context.Context, config handler.Config) *handler.Handler {
|
|
return handler.NewHandler(ctx, &config, new(userRelationalProjection))
|
|
}
|
|
|
|
func (p *userRelationalProjection) Reducers() []handler.AggregateReducer {
|
|
return []handler.AggregateReducer{
|
|
{
|
|
Aggregate: user.AggregateType,
|
|
EventReducers: []handler.EventReducer{
|
|
{
|
|
Event: user.UserV1AddedType,
|
|
Reduce: p.reduceHumanAdded,
|
|
},
|
|
{
|
|
Event: user.HumanAddedType,
|
|
Reduce: p.reduceHumanAdded,
|
|
},
|
|
{
|
|
Event: user.UserV1RegisteredType,
|
|
Reduce: p.reduceHumanRegistered,
|
|
},
|
|
{
|
|
Event: user.HumanRegisteredType,
|
|
Reduce: p.reduceHumanRegistered,
|
|
},
|
|
{
|
|
Event: user.UserLockedType,
|
|
Reduce: p.reduceUserLocked,
|
|
},
|
|
{
|
|
Event: user.UserUnlockedType,
|
|
Reduce: p.reduceUserUnlocked,
|
|
},
|
|
{
|
|
Event: user.UserDeactivatedType,
|
|
Reduce: p.reduceUserDeactivated,
|
|
},
|
|
{
|
|
Event: user.UserReactivatedType,
|
|
Reduce: p.reduceUserReactivated,
|
|
},
|
|
{
|
|
Event: user.UserRemovedType,
|
|
Reduce: p.reduceUserRemoved,
|
|
},
|
|
|
|
{
|
|
Event: user.UserUserNameChangedType,
|
|
Reduce: p.reduceUsernameChanged,
|
|
},
|
|
{
|
|
Event: user.UserDomainClaimedType,
|
|
Reduce: p.reduceDomainClaimed,
|
|
},
|
|
|
|
{
|
|
Event: user.HumanProfileChangedType,
|
|
Reduce: p.reduceHumanProfileChanged,
|
|
},
|
|
{
|
|
Event: user.UserV1ProfileChangedType,
|
|
Reduce: p.reduceHumanProfileChanged,
|
|
},
|
|
|
|
{
|
|
Event: user.HumanEmailChangedType,
|
|
Reduce: p.reduceHumanEmailChanged,
|
|
},
|
|
{
|
|
Event: user.UserV1EmailChangedType,
|
|
Reduce: p.reduceHumanEmailChanged,
|
|
},
|
|
{
|
|
Event: user.HumanEmailVerifiedType,
|
|
Reduce: p.reduceHumanEmailVerified,
|
|
},
|
|
{
|
|
Event: user.UserV1EmailVerifiedType,
|
|
Reduce: p.reduceHumanEmailVerified,
|
|
},
|
|
{
|
|
Event: user.HumanEmailCodeAddedType,
|
|
Reduce: p.reduceHumanEmailCodeAdded,
|
|
},
|
|
{
|
|
Event: user.UserV1EmailCodeAddedType,
|
|
Reduce: p.reduceHumanEmailCodeAdded,
|
|
},
|
|
{
|
|
Event: user.HumanEmailVerificationFailedType,
|
|
Reduce: p.reduceHumanEmailVerificationFailed,
|
|
},
|
|
{
|
|
Event: user.UserV1EmailVerificationFailedType,
|
|
Reduce: p.reduceHumanEmailVerificationFailed,
|
|
},
|
|
{
|
|
Event: user.HumanPhoneChangedType,
|
|
Reduce: p.reduceHumanPhoneChanged,
|
|
},
|
|
{
|
|
Event: user.UserV1PhoneChangedType,
|
|
Reduce: p.reduceHumanPhoneChanged,
|
|
},
|
|
{
|
|
Event: user.HumanPhoneRemovedType,
|
|
Reduce: p.reduceHumanPhoneRemoved,
|
|
},
|
|
{
|
|
Event: user.UserV1PhoneRemovedType,
|
|
Reduce: p.reduceHumanPhoneRemoved,
|
|
},
|
|
{
|
|
Event: user.HumanPhoneVerifiedType,
|
|
Reduce: p.reduceHumanPhoneVerified,
|
|
},
|
|
{
|
|
Event: user.UserV1PhoneVerifiedType,
|
|
Reduce: p.reduceHumanPhoneVerified,
|
|
},
|
|
{
|
|
Event: user.HumanPhoneCodeAddedType,
|
|
Reduce: p.reduceHumanPhoneCodeAdded,
|
|
},
|
|
{
|
|
Event: user.UserV1PhoneCodeAddedType,
|
|
Reduce: p.reduceHumanPhoneCodeAdded,
|
|
},
|
|
{
|
|
Event: user.HumanPhoneVerificationFailedType,
|
|
Reduce: p.reduceHumanPhoneVerificationFailed,
|
|
},
|
|
{
|
|
Event: user.UserV1PhoneVerificationFailedType,
|
|
Reduce: p.reduceHumanPhoneVerificationFailed,
|
|
},
|
|
|
|
{
|
|
Event: user.HumanAvatarAddedType,
|
|
Reduce: p.reduceHumanAvatarAdded,
|
|
},
|
|
{
|
|
Event: user.HumanAvatarRemovedType,
|
|
Reduce: p.reduceHumanAvatarRemoved,
|
|
},
|
|
|
|
{
|
|
Event: user.HumanPasswordChangedType,
|
|
Reduce: p.reduceHumanPasswordChanged,
|
|
},
|
|
{
|
|
Event: user.UserV1PasswordChangedType,
|
|
Reduce: p.reduceHumanPasswordChanged,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordCodeAddedType,
|
|
Reduce: p.reduceHumanPasswordCodeAdded,
|
|
},
|
|
{
|
|
Event: user.UserV1PasswordCodeAddedType,
|
|
Reduce: p.reduceHumanPasswordCodeAdded,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordCheckSucceededType,
|
|
Reduce: p.reduceHumanPasswordCheckSucceeded,
|
|
},
|
|
{
|
|
Event: user.UserV1PasswordCheckSucceededType,
|
|
Reduce: p.reduceHumanPasswordCheckSucceeded,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordCheckFailedType,
|
|
Reduce: p.reduceHumanPasswordCheckFailed,
|
|
},
|
|
{
|
|
Event: user.UserV1PasswordCheckFailedType,
|
|
Reduce: p.reduceHumanPasswordCheckFailed,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordHashUpdatedType,
|
|
Reduce: p.reduceHumanPasswordHashUpdated,
|
|
},
|
|
|
|
{
|
|
Event: user.MachineAddedEventType,
|
|
Reduce: p.reduceMachineAdded,
|
|
},
|
|
{
|
|
Event: user.MachineChangedEventType,
|
|
Reduce: p.reduceMachineChanged,
|
|
},
|
|
|
|
{
|
|
Event: user.MachineSecretSetType,
|
|
Reduce: p.reduceMachineSecretSet,
|
|
},
|
|
{
|
|
Event: user.MachineSecretHashUpdatedType,
|
|
Reduce: p.reduceMachineSecretHashUpdated,
|
|
},
|
|
{
|
|
Event: user.MachineSecretRemovedType,
|
|
Reduce: p.reduceMachineSecretRemoved,
|
|
},
|
|
|
|
{
|
|
Event: user.MachineKeyAddedEventType,
|
|
Reduce: p.reduceMachineKeyAdded,
|
|
},
|
|
{
|
|
Event: user.MachineKeyRemovedEventType,
|
|
Reduce: p.reduceMachineKeyRemoved,
|
|
},
|
|
{
|
|
Event: user.UserV1MFAInitSkippedType,
|
|
Reduce: p.reduceMFAInitSkipped,
|
|
},
|
|
{
|
|
Event: user.HumanMFAInitSkippedType,
|
|
Reduce: p.reduceMFAInitSkipped,
|
|
},
|
|
|
|
{
|
|
Event: user.PersonalAccessTokenAddedType,
|
|
Reduce: p.reducePersonalAccessTokenAdded,
|
|
},
|
|
{
|
|
Event: user.PersonalAccessTokenRemovedType,
|
|
Reduce: p.reducePersonalAccessTokenRemoved,
|
|
},
|
|
|
|
{
|
|
Event: user.MetadataSetType,
|
|
Reduce: p.reduceMetadataSet,
|
|
},
|
|
{
|
|
Event: user.MetadataRemovedType,
|
|
Reduce: p.reduceMetadataRemoved,
|
|
},
|
|
{
|
|
Event: user.MetadataRemovedAllType,
|
|
Reduce: p.reduceMetadataRemovedAll,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordlessTokenAddedType,
|
|
Reduce: p.reducePasskeyAdded,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordlessTokenVerifiedType,
|
|
Reduce: p.reducePasskeyVerified,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordlessTokenSignCountChangedType,
|
|
Reduce: p.reducePasskeySignCountSet,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordlessTokenRemovedType,
|
|
Reduce: p.reducePasskeyRemoved,
|
|
},
|
|
|
|
{
|
|
Event: user.HumanU2FTokenAddedType,
|
|
Reduce: p.reducePasskeyAdded,
|
|
},
|
|
{
|
|
Event: user.HumanU2FTokenVerifiedType,
|
|
Reduce: p.reducePasskeyVerified,
|
|
},
|
|
{
|
|
Event: user.HumanU2FTokenSignCountChangedType,
|
|
Reduce: p.reducePasskeySignCountSet,
|
|
},
|
|
{
|
|
Event: user.HumanU2FTokenRemovedType,
|
|
Reduce: p.reducePasskeyRemoved,
|
|
},
|
|
|
|
{
|
|
Event: user.HumanPasswordlessInitCodeAddedType,
|
|
Reduce: p.reducePasskeyInitCodeAdded,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordlessInitCodeCheckFailedType,
|
|
Reduce: p.reducePasskeyInitCodeCheckFailed,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordlessInitCodeCheckSucceededType,
|
|
Reduce: p.reducePasskeyInitCodeCheckSucceeded,
|
|
},
|
|
{
|
|
Event: user.HumanPasswordlessInitCodeRequestedType,
|
|
Reduce: p.reducePasskeyInitCodeRequested,
|
|
},
|
|
{
|
|
Event: user.UserIDPLinkAddedType,
|
|
Reduce: p.reduceIDPLinkAdded,
|
|
},
|
|
{
|
|
Event: user.UserIDPLinkCascadeRemovedType,
|
|
Reduce: p.reduceIDPLinkCascadeRemoved,
|
|
},
|
|
{
|
|
Event: user.UserIDPLinkRemovedType,
|
|
Reduce: p.reduceIDPLinkRemoved,
|
|
},
|
|
{
|
|
Event: user.UserIDPExternalIDMigratedType,
|
|
Reduce: p.reduceIDPLinkUserIDMigrated,
|
|
},
|
|
{
|
|
Event: user.UserIDPExternalUsernameChangedType,
|
|
Reduce: p.reduceIDPLinkUsernameChanged,
|
|
},
|
|
{
|
|
Event: user.HumanMFAOTPAddedType,
|
|
Reduce: p.reduceTOTPAdded,
|
|
},
|
|
{
|
|
Event: user.UserV1MFAOTPAddedType,
|
|
Reduce: p.reduceTOTPAdded,
|
|
},
|
|
{
|
|
Event: user.HumanMFAOTPVerifiedType,
|
|
Reduce: p.reduceTOTPVerified,
|
|
},
|
|
{
|
|
Event: user.UserV1MFAOTPVerifiedType,
|
|
Reduce: p.reduceTOTPVerified,
|
|
},
|
|
{
|
|
Event: user.HumanMFAOTPRemovedType,
|
|
Reduce: p.reduceTOTPRemoved,
|
|
},
|
|
{
|
|
Event: user.UserV1MFAOTPRemovedType,
|
|
Reduce: p.reduceTOTPRemoved,
|
|
},
|
|
{
|
|
Event: user.HumanMFAOTPCheckSucceededType,
|
|
Reduce: p.reduceTOTPCheckSucceeded,
|
|
},
|
|
{
|
|
Event: user.UserV1MFAOTPCheckSucceededType,
|
|
Reduce: p.reduceTOTPCheckSucceeded,
|
|
},
|
|
{
|
|
Event: user.HumanMFAOTPCheckFailedType,
|
|
Reduce: p.reduceTOTPCheckFailed,
|
|
},
|
|
{
|
|
Event: user.UserV1MFAOTPCheckFailedType,
|
|
Reduce: p.reduceTOTPCheckFailed,
|
|
},
|
|
{
|
|
Event: user.HumanOTPSMSAddedType,
|
|
Reduce: p.reduceOTPSMSEnabled,
|
|
},
|
|
{
|
|
Event: user.HumanOTPSMSRemovedType,
|
|
Reduce: p.reduceOTPSMSDisabled,
|
|
},
|
|
{
|
|
Event: user.HumanOTPSMSCheckSucceededType,
|
|
Reduce: p.reduceOTPSMSCheckSucceeded,
|
|
},
|
|
{
|
|
Event: user.HumanOTPSMSCheckFailedType,
|
|
Reduce: p.reduceOTPSMSCheckFailed,
|
|
},
|
|
{
|
|
Event: user.HumanOTPEmailAddedType,
|
|
Reduce: p.reduceOTPEmailEnabled,
|
|
},
|
|
{
|
|
Event: user.HumanOTPEmailRemovedType,
|
|
Reduce: p.reduceOTPEmailDisabled,
|
|
},
|
|
{
|
|
Event: user.HumanOTPEmailCheckSucceededType,
|
|
Reduce: p.reduceOTPEmailCheckSucceeded,
|
|
},
|
|
{
|
|
Event: user.HumanOTPEmailCheckFailedType,
|
|
Reduce: p.reduceOTPEmailCheckFailed,
|
|
},
|
|
{
|
|
Event: user.HumanInviteCodeAddedType,
|
|
Reduce: p.reduceInviteCodeAdded,
|
|
},
|
|
{
|
|
Event: user.HumanInviteCheckSucceededType,
|
|
Reduce: p.reduceInviteCheckSucceeded,
|
|
},
|
|
{
|
|
Event: user.HumanInviteCheckFailedType,
|
|
Reduce: p.reduceInviteCheckFailed,
|
|
},
|
|
{
|
|
Event: user.HumanRecoveryCodesAddedType,
|
|
Reduce: p.reduceRecoveryCodesAdded,
|
|
},
|
|
{
|
|
Event: user.HumanRecoveryCodesRemovedType,
|
|
Reduce: p.reduceRecoveryCodesRemoved,
|
|
},
|
|
{
|
|
Event: user.HumanRecoveryCodeCheckSucceededType,
|
|
Reduce: p.reduceRecoveryCodeCheckSucceeded,
|
|
},
|
|
{
|
|
Event: user.HumanRecoveryCodeCheckFailedType,
|
|
Reduce: p.reduceRecoveryCodeCheckFailed,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func (u *userRelationalProjection) 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, projectionName 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(),
|
|
// TODO check when to set username unique
|
|
// IsUsernameOrgUnique: ,
|
|
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 *userRelationalProjection) 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, projectionName 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(),
|
|
// TODO check when to set username unique
|
|
// IsUsernameOrgUnique: ,
|
|
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 *userRelationalProjection) reduceUserLocked(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserLockedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName 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
|
|
}), nil
|
|
}
|
|
|
|
func (p *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) reduceUserDeactivated(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.UserDeactivatedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName 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
|
|
}), nil
|
|
}
|
|
|
|
func (p *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) reduceDomainClaimed(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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) reduceHumanPasswordChanged(event eventstore.Event) (*handler.Statement, error) {
|
|
e, err := assertEvent[*user.HumanPasswordChangedEvent](event)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName 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
|
|
}), nil
|
|
}
|
|
|
|
func (p *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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,
|
|
// TODO check when to set username unique
|
|
// IsUsernameOrgUnique: ,
|
|
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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) reduceMetadataSet(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, projectionName 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 *userRelationalProjection) reduceMetadataRemoved(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, projectionName 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 *userRelationalProjection) reduceMetadataRemovedAll(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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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 *userRelationalProjection) 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, projectionName 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
|
|
}
|
|
}
|