Appearance
July 17, 2026 — Backend
Release date: Friday, July 17, 2026
Summary
This week shipped self-service password recovery for local accounts: users request a reset email, open a one-time link on the frontend, and set a new password without admin help. The API stays anti-enumeration and does not auto-login after reset.
Shipped
- Password reset APIs:
POST /api/v1/auth/password-reset/request,…/validate, and…/confirm(no JWT); request always returns204; confirm returns204and revokes all refresh tokens. - Email:
PASSWORD_RESETnotification template (SECURITY / EMAIL) withresetUrlpointing at{APP_FRONTEND_BASE_URL}{APP_FRONTEND_PASSWORD_RESET_PATH}?token=…(default path/reset-password). - Schema: New
PasswordResetTokentable (hashed token, expiry, usedAt); migration20260717120000_auth_add_password_reset_token. - Hardening: Per-IP rate limits on the three routes, per-email send cooldown, single-use tokens, reject same-as-current password, audit actions
auth.password_reset_requested/auth.password_reset_completed. - Docs: Password-reset section and frontend integration guide in
docs/AUTH_FLOW.md; updates toNOTIFICATIONS.md,AUDIT_LOG.md, auth README, andhttp/api.http.
Engineering (commit recap)
Backend — week of July 13 – July 17, 2026
Window: 2026-07-12 < commit date < 2026-07-18 (git log --no-merges).
Summary
One feature commit landed on July 17. Auth gains a dedicated PasswordResetService, DTOs, controller routes, and an in-memory IP rate-limit guard. Tokens are stored as SHA-256 hashes; plaintext appears only in the emailed link. Confirm updates bcrypt passwordHash and revokes sessions via existing revokeAllRefreshTokensForUser.
Themes
- Password reset flow: Request → email with opaque token → validate → confirm; eligible users only (
deletedAtnull and localpasswordHash); unknown/soft-deleted/no-password emails get the same success with no mail. - Config:
AUTH_PASSWORD_RESET_EXPIRES_IN_MINUTES,AUTH_PASSWORD_RESET_REQUEST_COOLDOWN_MINUTES,APP_FRONTEND_PASSWORD_RESET_PATH(see.env.example). - Testing: DTO, service, controller, and rate-limit guard specs covering happy path, unknown email, cooldown, expired/used token, soft-delete, and session revoke.
- Docs for UI: Frontend instructions live in
AUTH_FLOW.md(forgot-password +/reset-passwordscreens; no cookies/JWT on these calls).
Notable fixes or risks (if any)
- Deploy: Run migration
auth_add_password_reset_token, re-seed notification templates (or upsertPASSWORD_RESET), and setEMAIL_ENABLED=trueplus SMTP for real mail; setAPP_FRONTEND_BASE_URL/ reset path so links hit the correct SPA route. - No auto-login: Clients must send users to login after confirm; existing sessions are invalidated.
- Admin password change:
PATCH /users/:idstill does not revoke sessions (unchanged); self-service reset does.