package command import ( "time" "github.com/zitadel/zitadel/internal/domain" "github.com/zitadel/zitadel/internal/eventstore" "github.com/zitadel/zitadel/internal/repository/user" ) type UserAccessTokenWriteModel struct { eventstore.WriteModel TokenID string ApplicationID string UserAgentID string Audience []string Scopes []string Expiration time.Time PreferredLanguage string Reason domain.TokenReason Actor *domain.TokenActor UserState domain.UserState } func NewUserAccessTokenWriteModel(userID, resourceOwner, tokenID string) *UserAccessTokenWriteModel { return &UserAccessTokenWriteModel{ WriteModel: eventstore.WriteModel{ AggregateID: userID, ResourceOwner: resourceOwner, }, TokenID: tokenID, } } func (wm *UserAccessTokenWriteModel) AppendEvents(events ...eventstore.Event) { for _, event := range events { switch e := event.(type) { case *user.UserTokenAddedEvent: if wm.TokenID != e.TokenID { continue } wm.WriteModel.AppendEvents(e) case *user.UserTokenRemovedEvent: if wm.TokenID != e.TokenID { continue } wm.WriteModel.AppendEvents(e) case *user.HumanSignedOutEvent: if wm.UserAgentID != e.UserAgentID { continue } wm.WriteModel.AppendEvents(e) case *user.UserLockedEvent, *user.UserDeactivatedEvent, *user.UserRemovedEvent: wm.WriteModel.AppendEvents(e) } } } func (wm *UserAccessTokenWriteModel) Reduce() error { for _, event := range wm.Events { switch e := event.(type) { case *user.UserTokenAddedEvent: wm.TokenID = e.TokenID wm.ApplicationID = e.ApplicationID wm.UserAgentID = e.UserAgentID wm.Audience = e.Audience wm.Scopes = e.Scopes wm.Expiration = e.Expiration wm.PreferredLanguage = e.PreferredLanguage wm.UserState = domain.UserStateActive wm.Reason = e.Reason wm.Actor = e.Actor if e.Expiration.Before(time.Now()) { wm.UserState = domain.UserStateDeleted } case *user.UserTokenRemovedEvent, *user.HumanSignedOutEvent, *user.UserLockedEvent, *user.UserDeactivatedEvent, *user.UserRemovedEvent: wm.UserState = domain.UserStateDeleted } } return wm.WriteModel.Reduce() } func (wm *UserAccessTokenWriteModel) Query() *eventstore.SearchQueryBuilder { query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent). AddQuery(). AggregateTypes(user.AggregateType). AggregateIDs(wm.AggregateID). EventTypes( user.UserTokenAddedType, user.UserTokenRemovedType, user.HumanSignedOutType, user.UserLockedType, user.UserDeactivatedType, user.UserRemovedType). Builder() if wm.ResourceOwner != "" { query.ResourceOwner(wm.ResourceOwner) } return query }