docs: complete code-reality alignment for remaining docs + reconcile issue set

Remaining docs updated to match code (the docs that the first pass had not covered):
- Flows: Chat, Referral, Rating, Registration, Google OAuth, Negotiation, Payout,
  Trezor Safekeeping — corrected endpoints, socket events, status enums, auth gaps
- API Reference: User API, Trezor API — admin route prefix/verb/status corrections,
  added undocumented endpoints (ton-proof challenge, profile email verify,
  GET /trezor/account, POST /trezor/verify-operation)
- Data Models: Chat, Notification, Payment, PointTransaction, User — corrected
  enums (PaymentProvider, escrowState, PointTransaction.type, User.status),
  90-day notification TTL, soft-delete semantics, wallet fields

Trezor "zero frontend" finding (audit C31/C32) corrected as STALE:
- Verified current code HAS a full frontend Trezor implementation (admin/trezor
  page, TrezorSettingsView, trezorConnector via @trezor/connect-web,
  TrezorSignDialog, actions/trezor.ts building the {message,signature} object)
- Fixed Trezor Safekeeping Flow doc (removed false "no frontend" warnings)
- Reclassified ISSUE-012 as invalid/superseded with explanation

Issue set reconciled to a single canonical numbering (ISSUE-001..054):
- Adopted the comprehensive 51-issue set (long-slug, fully indexed)
- Removed 35 superseded short-slug duplicates from the first pass
- Removed a duplicate ISSUE-046 file
- Added 3 issues the 51-set lacked: ISSUE-052 (completed-not-counted-in-stats),
  ISSUE-053 (axios 401-only interceptor), ISSUE-054 (rate limiter counts all attempts)
- Regenerated Issues Index: 53 open (14 critical, 39 major) + 1 invalid

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Siavash Sameni
2026-05-29 15:15:02 +04:00
parent 9698ec5809
commit 7a616744f4
118 changed files with 2833 additions and 1788 deletions

View File

@@ -5,6 +5,8 @@ related_models: ["[[User]]"]
related_apis: ["POST /api/auth/request-password-reset", "POST /api/auth/reset-password-with-code", "POST /api/auth/reset-password"]
---
> **Last updated:** 2026-05-29 — aligned with code (see Doc vs Code Audit Report)
> [!caution] Audit note — last reviewed 2026-05-29
> Several discrepancies between frontend code, backend code, and this document were identified and corrected in this revision. See inline ⚠️ markers for known bugs and mismatches.
@@ -47,7 +49,7 @@ The primary UI-driven path uses the **code-based** endpoint. The token-based end
6. User receives the email and enters the code + new password on `/auth/jwt/update-password`.
7. Frontend POSTs `POST /api/auth/reset-password-with-code { email, code, password }`.
8. Backend `authController.resetPasswordWithCode` (`:611-657`):
- Validates code format `/^\d{6}$/` a code of any other length (e.g., 8 digits) will **always fail** here.
- Validates code format `/^\d{6}$/` — codes of any other length will **always fail** here.
- `User.findOne({ email, passwordResetCode: code, passwordResetCodeExpires: { $gt: now }, status: "active" })`. Mismatch → `400 Invalid or expired reset code`.
- Hashes the new password with bcrypt cost 12. **No password complexity validation is applied** — weak passwords such as `123456` or `aaaaaa` are accepted without error.
- Sets `user.password = hashed`, clears `passwordResetCode` and `passwordResetCodeExpires`, **wipes `user.refreshTokens = []`** to invalidate all existing sessions.
@@ -100,7 +102,7 @@ sequenceDiagram
>
> **`POST /api/auth/reset-password-with-code`** (primary UI path)
> - Uses a 6-digit numeric code delivered by email.
> - `isValidVerificationCode()` validates with `/^\d{6}$/`. An 8-digit code will always fail.
> - `isValidVerificationCode()` validates with `/^\d{6}$/`.
> - Has **no password complexity middleware**. Any string is accepted as the new password.
>
> **`POST /api/auth/reset-password`** (legacy token-based path)
@@ -126,7 +128,7 @@ sequenceDiagram
## Error / edge cases
- **Unknown email** → always `200`, generic message. No enumeration.
- **Invalid code format** → `400` from `isValidVerificationCode` guard before DB lookup. Note: the `authController.ts` comment mentions "8 digits" but the actual implementation generates and validates exactly 6 digits — any 8-digit code will be rejected.
- **Invalid code format** → `400` from `isValidVerificationCode` guard before DB lookup.
- **Expired code** (>1h) → `400 Invalid or expired reset code`.
- **Multiple parallel requests** → each overwrites the previous `passwordResetCode`; the latest email wins, prior codes silently invalidated.
- **User attempts reset on deleted account** → treated as unknown (no email sent, `200` returned).
@@ -136,15 +138,11 @@ sequenceDiagram
> [!warning] Plaintext code in logs
> Same as [[Registration Flow]]: the reset code is `console.log`-ed by the controller in all environments. Restrict log access in production or gate the log behind `NODE_ENV !== 'production'`.
> [!bug] Controller comment says "8 digits" but code generates 6
> The comment in `authController.ts` describes an 8-digit code, but `authService.generateVerificationCode()` uses `Math.floor(100000 + Math.random() * 900000)`, which produces a number in the range 100000999999 (exactly 6 digits). `isValidVerificationCode()` enforces `/^\d{6}$/`. Any 8-digit value sent to `reset-password-with-code` will always be rejected. The comment is wrong; the 6-digit implementation and validation are correct and consistent.
## Known issues summary
| Issue | Severity | Details |
|---|---|---|
| No password complexity on code-based reset | Security gap | `POST /api/auth/reset-password-with-code` has no complexity middleware; weak passwords accepted |
| Controller comment says 8 digits | Doc bug | Comment is wrong; code generates and validates exactly 6 digits |
| Inconsistent complexity between reset endpoints | Security gap | Token-based reset enforces complexity; code-based reset does not |
## Linked flows