fix: wizard.* déplacé au TOP NIVEAU des locales FR/EN
Les clés étaient sous richTextEditor.wizard mais le code appelle
t('wizard.studyPlanner') qui cherche au niveau racine.
48 clés déplacées de richTextEditor.wizard → wizard au niveau racine.
FR et EN corrigés.
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
---
|
||||
title: 'Cross-Project Health Audit'
|
||||
type: 'chore'
|
||||
created: '2026-06-20'
|
||||
status: 'in-progress'
|
||||
baseline_commit: 'HEAD'
|
||||
context:
|
||||
- '{project-root}/AGENTS.md'
|
||||
- '{project-root}/CLAUDE.md'
|
||||
- '{project-root}/memento-note/docs/admin-billing-quotas-guide.md'
|
||||
---
|
||||
|
||||
<frozen-after-approval reason="human-owned intent — do not modify unless human renegotiates">
|
||||
|
||||
## Intent
|
||||
|
||||
**Problem:** The Momento workspace spans multiple deployable and reference projects (memento-note, mcp-server, extension, mobile, monitoring, CI/CD, prototypes) without a consolidated security and quality audit; several P0 issues were found (open uploads, MCP auth bypass, fail-open quotas).
|
||||
|
||||
**Approach:** Deliver a prioritized cross-project audit report (bugs + improvements) and, upon approval, remediate Phase 1 P0 security items first — app uploads/auth, MCP tenant isolation, extension Store readiness — before UX/i18n/prototype parity work.
|
||||
|
||||
## Boundaries & Constraints
|
||||
|
||||
**Always:** No destructive DB commands; backup via `dump-db.sh` before any schema change; i18n via 15 locales when touching UI; follow prototype `architectural-grid` for UX gaps; fail-closed for billing quotas in production.
|
||||
|
||||
**Ask First:** Whether to fail-open vs fail-closed quotas during Redis outage; whether MCP `x-user-id` should be removed entirely or restricted to internal network; Chrome Web Store host_permissions scope; archiving `architectural-grid1` vs keeping both prototypes.
|
||||
|
||||
**Never:** `prisma migrate reset`, `db push --force-reset`, `pg_dump --clean` in deploy scripts; exposing API keys in client bundles; shipping extension with dev `host_permissions`; implementing all audit items in one PR.
|
||||
|
||||
</frozen-after-approval>
|
||||
|
||||
## Code Map
|
||||
|
||||
- `memento-note/app/api/uploads/[...path]/route.ts` -- uploads served without session check
|
||||
- `memento-note/app/api/image-proxy/route.ts` -- open SSRF proxy
|
||||
- `memento-note/lib/entitlements.ts` -- Redis fail-open on AI quotas
|
||||
- `memento-note/auth.config.ts` -- `/insights`, `/graph`, `/revision`, `/support` not gated
|
||||
- `memento-note/context/notebooks-context.tsx` -- broken AI toast note move (no home refresh)
|
||||
- `mcp-server/index-sse.js` -- `x-user-id` header auth bypass
|
||||
- `mcp-server/tools.js` -- missing userId filter + `ensureUserId()` first-user fallback
|
||||
- `memento-note/extension/dist-chrome-store/` -- missing PNG icons, wide host_permissions
|
||||
- `memento-mobile/app.json` -- references missing `assets/`
|
||||
- `monitoring/metrics-token` -- placeholder secret committed
|
||||
- `scripts/deploy-prod.sh` -- `pg_dump --clean`, full Docker build fallback
|
||||
- `docker-compose.yml` -- MCP/Ollama ports bound 0.0.0.0
|
||||
|
||||
## Tasks & Acceptance
|
||||
|
||||
**Execution (Phase 1 — P0 security only, if approved):**
|
||||
- [ ] `memento-note/app/api/uploads/[...path]/route.ts` -- require auth + verify note ownership for file path -- prevent private attachment leak
|
||||
- [ ] `memento-note/app/api/image-proxy/route.ts` -- require auth + domain allowlist -- close SSRF/abuse
|
||||
- [ ] `memento-note/lib/entitlements.ts` -- fail-closed when Redis unavailable in production -- align with billing policy
|
||||
- [ ] `memento-note/auth.config.ts` -- add `/insights`, `/graph`, `/revision`, `/support` to protected routes -- match API 401 behavior
|
||||
- [ ] `mcp-server/index-sse.js` -- remove or restrict `x-user-id`; require API key on all tool paths -- close identity spoofing
|
||||
- [ ] `mcp-server/tools.js` -- always scope queries to authenticated userId; remove `ensureUserId()` fallback -- multi-tenant isolation
|
||||
- [ ] `docker-compose.yml` -- bind MCP `127.0.0.1:3001:3001` -- reduce network exposure
|
||||
|
||||
**Acceptance Criteria:**
|
||||
- Given an unauthenticated request, when GET `/api/uploads/notes/{uuid}.png`, then response is 401/403
|
||||
- Given Redis down in production, when AI quota check runs, then request is denied (not unlimited)
|
||||
- Given unauthenticated browser, when navigating to `/insights`, then redirect to login
|
||||
- Given MCP request with only `x-user-id` header and no API key, when tool invoked, then 401
|
||||
- Given authenticated user A, when MCP lists notes, then only user A notes returned
|
||||
|
||||
## Spec Change Log
|
||||
|
||||
## Design Notes
|
||||
|
||||
Full audit by project (2026-06-20):
|
||||
|
||||
**memento-note CRITICAL:** open uploads; image-proxy SSRF; fail-open quotas; middleware gaps; XSS via `dangerouslySetInnerHTML` (published pages, peek, SVG gallery); weak mobile HMAC; broken AI toast note move.
|
||||
|
||||
**mcp-server CRITICAL:** `x-user-id` spoofing; null userId returns all users' data; port 3001 public; Prisma schema drift vs main app.
|
||||
|
||||
**extension CRITICAL:** Store build missing PNG icons; `host_permissions` too broad for CWS.
|
||||
|
||||
**mobile CRITICAL:** missing assets folder; NativeWind configured but not installed.
|
||||
|
||||
**monitoring CRITICAL:** placeholder metrics token in git; Grafana on 0.0.0.0:3002.
|
||||
|
||||
**CI/CD CRITICAL:** manual deploy triggers full Docker build (fails on prod); `pg_dump --clean` in deploy script.
|
||||
|
||||
**prototypes MEDIUM:** Gemini API key in Vite client bundle; port 3000 conflict; grid vs grid1 divergence.
|
||||
|
||||
**Deferred phases:** P1 insights i18n + GraphKnowledgeMap; P2 editor drag-handle migration; P3 mobile EAS/CI; P4 monitoring alert cleanup.
|
||||
|
||||
## Verification
|
||||
|
||||
**Commands:**
|
||||
- `cd memento-note && npm run test:unit` -- expected: pass (no regressions on touched modules)
|
||||
- Manual curl unauthenticated upload URL -- expected: 401/403 after Phase 1
|
||||
|
||||
**Manual checks:**
|
||||
- Logged-out visit to `/insights` redirects to login
|
||||
- MCP tool call without API key returns 401
|
||||
Reference in New Issue
Block a user