package classes import ( "time" "git.golem15.com/golem15/sm-user-plugin/models" "gorm.io/gorm" ) // CreatedEventName is the festival name of CreatedEvent (D-13 / RESEARCH A6). const CreatedEventName = "user.Created" // DeletingEventName is the festival name of DeletingEvent (D-13 / RESEARCH A6). const DeletingEventName = "user.Deleting" // DeactivatingEventName is the festival name of DeactivatingEvent. const DeactivatingEventName = "user.Deactivating" // BackendLinkedEventName is the festival name of BackendLinkedEvent. const BackendLinkedEventName = "user.BackendLinked" // BackendUnlinkedEventName is the festival name of BackendUnlinkedEvent. const BackendUnlinkedEventName = "user.BackendUnlinked" // AccessRevokedEventName is the festival name of AccessRevokedEvent. const AccessRevokedEventName = "user.AccessRevoked" // GetApiArrayEvent is the fire-and-collect payload other plugins extend. type GetApiArrayEvent struct { User *models.User data map[string]any } // Collected returns the map listeners merge into the user payload. func (e *GetApiArrayEvent) Collected() map[string]any { if e.data == nil { e.data = map[string]any{} } return e.data } // RegisterEvent is fired after a user row is created (Winter's // golem15.user.register). type RegisterEvent struct { User *models.User // Payload is a copy of the register input, mirroring the data array // Winter passes with golem15.user.register, so a listener can read // extra keys a client sent (an invitation token, for example). // password and password_confirmation are never included, in plaintext // or hashed. Listeners must treat it as read-only input. Payload map[string]any } // CreatedEvent fires from every user create path (API register and admin // create) so listeners can run inside the same write, including handle // generation (D-13, D-15). Tx is the create transaction when there is one. type CreatedEvent struct { User *models.User Tx *gorm.DB } // DeletingEvent fires from FormAfterDelete before ForceDeleteCleanup / // unscoped delete, inside the same transaction, so listeners (chatchannels // GDPR) can sever rows before the user row is gone (D-13, T-19-07). type DeletingEvent struct { User *models.User Tx *gorm.DB } // DeactivatingEvent fires after a user is soft-deleted (deactivated, the // PHP $user->delete()) by the admin deactivate action, inside the same // transaction, so listeners can revoke what a deactivated account must not // keep (OAuth grants, for example) while leaving what a restore needs. The // user's session JWTs and personal API tokens are already revoked when it // fires (DeactivateUsers calls RevokeUserAccess). A listener error rolls the // deactivation back. type DeactivatingEvent struct { User *models.User Tx *gorm.DB } // BackendLinkedEvent fires inside the write transaction after a link was // stored, by the frontend user's confirmation (Link.LinkedBy nil) or by an // administrator (Link.LinkedBy set). A listener error rolls the link back. type BackendLinkedEvent struct { Link *models.BackendLink Tx *gorm.DB } // BackendUnlinkedEvent fires inside the write transaction after a link was // removed, from My account, the Administrators screen or because one of the // accounts was deleted or deactivated. A listener error rolls the removal // back. type BackendUnlinkedEvent struct { Link *models.BackendLink Tx *gorm.DB } // AccessRevokedEvent fires inside the write transaction when users lose // every credential issued before Before: a ban, a password reset, a password // an administrator set, or the user's own password change (FireAccessRevoked; // Reason names which). Listeners revoke what such a credential still holds // elsewhere, for example OAuth access and refresh tokens created before // Before. Before is the untruncated instant of the revocation, while the // users' tokens_valid_after keeps its whole-second value. A listener error // rolls the write back. Deactivation and deletion keep their own events // (DeactivatingEvent, DeletingEvent). type AccessRevokedEvent struct { UserIDs []uint Before time.Time Reason string Tx *gorm.DB }