- 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
- 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
Generate a unique mention handle on API register and admin create, and fire user.Created from both paths so listeners run in the same write.
Co-authored-by: Cursor <cursoragent@cursor.com>
One conditional UPDATE writes it at most once per five minutes per
user. A failed write is logged and never fails authentication, and no
user payload carries the column.
- 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
Prefix replacement of the old application-nested module path in go.mod
and every import. No identifier, string, table, migration ID, config key
or comment changes.
Match PHP payloads, already-activated Winter 500 HTML, and direct-DB
seeding so the corpus can flip those routes to ported without onboarding.
Co-authored-by: Cursor <cursoragent@cursor.com>
Reset and activation codes expire on a TTL, and a missing issued-at still accepts a cutover code. Forgot-password always returns the same 200 body.
Co-authored-by: Cursor <cursoragent@cursor.com>
Registration follows activate_mode and hides a disabled or throttled cause in production. Fonoteka adds organisation fields through GetApiArrayEvent.
Co-authored-by: Cursor <cursoragent@cursor.com>
Wire the user API session loop to the JWT blacklist and a pre-password throttle gate so a logged-out token cannot be fetched again.
Co-authored-by: Cursor <cursoragent@cursor.com>