User.RegisterFillable lists what a registration body may set: name,
surname, email, password, preferred_locale and marketing_consent.
RegisterUser fills from it instead of Fillable, so organisation_id,
organisation_role, is_onboarded and must_change_password can no longer be
mass-assigned through POST /register, and created_ip_address and
last_ip_address come only from RegisterOptions.IP. Fillable is unchanged
for the admin form and trusted application code.
Every command gets long help and examples, descriptions in imperative
sentence case, and a warn-only TestCommandsDocumented over bonfire.CheckDocs.
The plugin logs through a diary component logger instead of the process
default logger. Requires SummerCMS v0.4.0; command names and flags unchanged.
user:token:create and user:token:list gain --json, user:backfill-handles a
progress bar; planning IDs leave the descriptions.
- /update clears email_verified_at in the same write when the email changes (case-only changes keep it)
- the admin Users form clears it in FormBeforeUpdate; storedEmail helper shared with guardCredentials
- README: the proof follows the address, never mass-assigned, no backfill
- additive migration 202610210001_add_users_email_verified_at (ADD COLUMN IF NOT EXISTS, no backfill, no-op rollback)
- User.EmailVerifiedAt (json:"-", not fillable)
- VerifyActivationCode and ResetPassword stamp it in the write that activates or stores the password
- without a published *gorm.DB the command opens one with lagoon.OpenFromApp
for its run and closes it, as the plugin's other commands do (withDB)
- TestBackfillHandlesOpensFromConfigWhenUnpublished; README CLI note
- OAuthIdentitiesDestroy locks the users row (SELECT ... FOR UPDATE) and runs
the PHP guarded DELETE in one transaction: a self-set password or another
identity allows the unlink; otherwise 409 with the unchanged body
- the default allow-list adds microsoft, and an OAuthProviderSource's known
names are used when the host passes no Providers
- TestOAuthIdentitiesDestroyLastIdentityWithPassword (204),
TestOAuthIdentitiesDestroyConcurrentSmoke; README
- gofmt of the forgotPasswordBody line touched in the previous commit
- classes.OAuthProvider and classes.OAuthProviderSource; GET /oauth-providers
looks the source up per request and keeps the empty body without one
- exported RegistrationSettings, RegistrationsFromIP, RefreshTTL, RemoteIP
- RegisterOptions.PasswordLess (has_self_set_password=false) and FinishLogin
(restore + reactivate mail, last_ip_address, last_seen; no event)
- TestOAuthProvidersSourceSmoke, TestSocialHooksSmoke; README
- empty (default) adds nothing; open or closed appends turnstile:{mode} to
POST /login and /register only; any other value fails boot naming the key
- TestTurnstileRoutesSmoke records the declared routes with a recording router
- DeactivatingEvent and DeactivatingEventName in classes
- FireDeactivatingEvent modelled on FireDeletingEvent
- the deactivate bulk action runs DeactivateUsers unchanged, then fires
the event per newly deactivated user in the action's transaction
- AvatarURL returns the avatar thumbnail, the file path when the thumbnail
fails, or the gravatar URL, the rule of the user payload
- applyAvatar takes avatar_url from it; the payload is unchanged
- RequestUser resolves the signed-in user exactly like the jwt guard
(bearer, token and auth_token cookies, blacklist, tokens_valid_after)
and returns nil for anonymous or invalid requests
- EndRequestSession blacklists the session JWT and forgets the token
cookie with the configured cookie attributes, best effort
Register lighthouse user:{id} if the namespace is free, fire user.Deleting before unscoped delete, and backfill missing handles.
Co-authored-by: Cursor <cursoragent@cursor.com>
- RegisterEvent.Payload: a copy of the register input without password and
password_confirmation (Winter's golem15.user.register data array)
- RegisterUser, RegisterOptions, FireRegisterEvent, IssueToken and APIArray:
the steps POST /register runs, now called by Register itself; its status
codes and bodies are unchanged
- README documents the exports and Payload
- user_groups (seeded with the guest and registered groups) and the
users_groups pivot, folded from the PHP v1.1.1 and v2.8.0 migrations
into migration 202610020001_create_user_groups
- models.UserGroup and a User.Groups relation that is never serialized
- classes.UserGroupCodes and classes.HasGroupCode for server-side checks
such as the site-admin group code admin
- additive only: no route, payload or existing column changes; the user
payload still answers "groups":[]