# Accounts

Optional PostgreSQL accounts using installable app API 1. This source module uses
`replace github.com/fauzaanu/cicadel => ../..` for repository development; no remote
module release is claimed.

In a generated application's `project.InstalledApps(db)`, construct
`accounts.New(accounts.Options{DB: db, DeliverRecovery: deliver})`, handle its
error, and append `service.HTTPApp("/accounts")`. Run `manage.go migrate` before
serving. The migration is recorded SQL, never AutoMigrate. Removing registration
preserves data. The host owns its database pool.

The HTTP endpoints accept POST JSON with `Content-Type: application/json`:

| Path | Fields | Authentication |
| --- | --- | --- |
| login | Username, Password | Credentials; returns token |
| logout | empty object | Bearer token |
| change-password | OldPassword, Password | Bearer token |
| request-recovery | Username | Public; invokes delivery callback |
| reset-password | Token, Password | Recovery token |
| revoke | empty object | Bearer token; revokes every session |

Clients send `Authorization: Bearer <token>`. These routes use no ambient cookies.
Install `service.Middleware` explicitly on host routes requiring current-user
context; use `UserFromContext` and reject anonymous requests where needed. The
middleware does not itself require authentication. For browser applications, construct `service.Browser(sessions)` and wrap routes
with `browser.Middleware`. This composes SCS LoadAndSave, CSRF validation and
account resolution in order. Use `browser.Login`, `browser.Logout`,
`browser.CSRFToken` and `browser.RequireLogin` in HTML handlers. The account token
is held only in the server-side session; disablement and revocation are checked
on every request. Do not additionally wrap these routes with SCS/CSRF middleware.
SCS login alone does not create an accounts session. Existing
SCS APIs remain compatible. This package does not change forms, uploads or admin.

Tokens contain cryptographic randomness and only SHA-256 digests are stored.
Password changes and recovery revoke all sessions and recovery tokens in one
transaction. Recovery consumption locks the user and rechecks token deletion,
so concurrent redemption succeeds once. Session creation serializes with password
changes. `SetActive(false)` revokes sessions and recovery tokens. Disabled users cannot
log in, resolve current-user context or use permissions.

Passwords must contain 12–72 bytes. `Policy` adds application validation; bcrypt
cost defaults to 12 (configurable 10–16). Successful password authentication
upgrades lower costs without downgrading stronger hashes or overwriting a
concurrent password change. `Backend` can verify another credential source but
must return an existing local account; central disabled-user checks still apply.

`SessionLifetime` defaults to 24 hours and `RecoveryLifetime` to 30 minutes;
both are absolute lifetimes of at least one minute. Optional `IdleTimeout` expires
sessions after inactivity; successful current-user resolution refreshes activity. PostgreSQL is the persistent
store. Schedule `manage.go accounts:cleanup` to remove expired sessions/recovery
records. No background worker is started. Transport security, request rate limits,
and recovery delivery belong to the host. Delivery must send the raw token only
to the account's previously verified recovery destination; never to an arbitrary
request-supplied address. Avoid logging tokens or credentials.

Groups use `CreateGroup`, `AddMember`, `RemoveMember`, `Grant`, and `Deny`.
`HasPermission` checks exact application-defined model/action strings such as
`posts.change`. There is no superuser bypass or implicit object access. Apply an
explicit host policy for each object in addition to model permissions.

OAuth/OIDC, social login and MFA remain outside scope. The `accountui` package supplies compiled HTML account screens. Administration integration remains separate.

Run `CICADEL_TEST_DATABASE_URL=postgres://...?... go test -race ./...` with a
disposable PostgreSQL database and schema creation privileges. Tests isolate and
remove their schema. Parent module tests do not include this nested module.

`sh contrib/accounts/verify-host.sh` generates a separate application, registers
the package via local module replacements, applies its public migration contract,
and verifies login/logout over HTTP. Use a disposable database; the verification
applies accounts migrations and removes its test user afterward.


## Browser pages

Use `service.Browser(sessions)` and `browser.HTMLApp(Pages{Brand: "My app"})`
for the default compiled HTML screens. Register that app once and migrate before
serving. It owns its cookie/CSRF middleware and embedded CSS; other protected
routes apply `browser.Middleware` followed by `browser.RequireLogin`.
`UserFromContext` is shared with the bearer adapter. The browser stores the
account token only in the server-side SCS store, rotates login cookies and checks
revocation/disablement on every request.

Migration 002 adds the PostgreSQL `accounts_browser_sessions` table used by the
starter. Custom session stores remain supported. Use
`cicadel startproject DIRECTORY MODULE` for a wired project, including
verified account provisioning and SMTP recovery delivery. Read the
[complete authentication guide](https://cicadel.fauzaanu.com/en/dev/topics/authentication/index.md) for the route table,
configuration, middleware ownership and testing. There is no public signup or
administrator panel in this starter.

This module owns `.templ` source and generated Go/CSS. Run `ui build` and
`ui check --json` using the matching framework CLI, in addition to its tests.
