Files
Momento/_bmad-output/implementation-artifacts/spec-cross-project-audit.md
Antigravity 96e7902f01
Some checks failed
CI / Lint, Unit Tests & Build (push) Failing after 1m22s
CI / Deploy production (on server) (push) Has been skipped
feat: publication IA (magazine/brief/essay) + fixes critique
Publication IA:
- 4 templates (magazine, brief, essay, simple) avec CSS riche
- Rewrite IA (article/exercises/tutorial/reference/mixed)
- Modération avec timeout 12s + fallback safe
- Quotas publish_enhance par tier (basic=2, pro=15, business=100)
- Détection contenu stale (hash)
- Migration DB publishedContent/publishedTemplate/publishedSourceHash

Fixes:
- cheerio v1.2: Element -> AnyNode (domhandler), decodeEntities cast
- _isShared ajouté au type Note (champ virtuel serveur)
- callout colors PDF export: extraction fonction pure testable
- admin/published: guard note.userId null
- Cmd+S fonctionne en mode dialog (pas seulement fullPage)

i18n:
- 23 clés publish* traduites dans les 15 locales
- Extension Web Clipper: 13 locales mise à jour

Tests:
- callout-colors.test.ts (6 tests)
- note-visible-in-view.test.ts (5 tests)
- entitlements.test.ts + byok-entitlements.test.ts: mock usageLog + unstubAllEnvs
- 199/199 tests passent

Tracker: user-stories.md sync avec sprint-status.yaml
2026-06-28 07:32:57 +00:00

6.8 KiB

title, type, created, status, baseline_commit, context
title type created status baseline_commit context
Cross-Project Health Audit chore 2026-06-20 done 40f30155c2
{project-root}/AGENTS.md
{project-root}/CLAUDE.md
{project-root}/memento-note/docs/admin-billing-quotas-guide.md

Intent

Problem: The Memento 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.

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

Suggested Review Order

Upload access control

  • Ownership check before serving note attachments; published notes stay public route.ts:30

  • Prisma lookup tying filename to note content/images upload-access.ts:4

SSRF / image proxy

Billing quotas fail-closed

Auth middleware

MCP multi-tenant isolation

Infrastructure

Tests