document password reset flow in CLAUDE.md and reset-password page
This commit is contained in:
@@ -235,6 +235,23 @@ Key facts:
|
||||
`fetch('/api/me')` auth wall; `/login/` and `/register/` have `public={true}` to skip it
|
||||
- Incremental rebuild: `POST /api/activity/{id}` triggers `bincio render --handle {user}`
|
||||
as a fire-and-forget subprocess (only if `--site-dir` was passed to `bincio serve`)
|
||||
|
||||
### Password reset (no email — out-of-band code)
|
||||
|
||||
There is no email infrastructure. Password resets work via admin-generated one-time codes:
|
||||
|
||||
1. **Admin** opens `/admin/` → clicks **"Reset pwd"** next to the user → a code appears
|
||||
inline (monospace, click to copy). Valid for **24 hours**, tied to that handle.
|
||||
2. **Admin** sends the code out-of-band (Signal, Telegram, etc.).
|
||||
3. **User** goes to `/reset-password/`, enters handle + code + new password → done.
|
||||
|
||||
API:
|
||||
- `POST /api/admin/users/{handle}/reset-password-code` (admin) → `{code, expires_in_hours: 24}`
|
||||
- `POST /api/auth/reset-password` (public) → body `{handle, code, password}`
|
||||
|
||||
DB: `reset_codes` table `(code, handle, created_by, created_at, expires_at, used_at)`.
|
||||
Generating a new code invalidates any prior unused code for the same handle.
|
||||
Used codes are kept for audit. `change_password()` in `db.py` updates the bcrypt hash.
|
||||
- Write API in `bincio serve` delegates to `bincio.edit.server._apply_sidecar_edit`; the
|
||||
Strava sync delegates to `bincio.edit.server.strava_sync` with a temporary data_dir swap
|
||||
|
||||
|
||||
Reference in New Issue
Block a user