merge: bring the MCP server onto the v1.23 base

Combine the remote MCP server (stdio + remote /mcp + OAuth 2.1 + read
tools + deep-value reads + a confirmed, audience-bound write surface)
with the v1.23 account-security line (MFA, known/trusted devices,
free-text note encryption).

- schema: keep every v1.23 User relation (MFA, known/trusted devices)
  alongside the McpOAuthConnection relation; the MeasurementSource enum
  carries the MCP value.
- api-handler: the MCP audience guard (a token scoped to
  health:read/health:write is bound to /mcp and refused a REST write)
  and the step-up MFA helpers coexist.
- maintenance queues: register the MCP token-cleanup sweep next to the
  note-encryption backfill and key-rotation queues; shift it to 04:00
  so the two daily discovery ticks do not collide.
- migrations: renumber the MCP migrations to 0206/0207 so they follow
  the v1.23 chain (0199-0205).
- MCP mood writes route the note through the v1.23 at-rest cipher.
This commit is contained in:
Marc-André Bombeck committed 2026-06-28 00:52:04 +02:00
commit fb986bc09d
89 files changed
+10276 -109

No files matched your search

+17
View File
@@ -71,6 +71,13 @@ const PUBLIC_PATHS = [
*/
const WELL_KNOWN_PUBLIC_PATHS = new Set<string>([
"/.well-known/apple-app-site-association",
// v1.22.0 — OAuth discovery for the remote MCP connector. A remote client
// (Claude.ai / ChatGPT) reads these unauthenticated to bootstrap the OAuth
// 2.1 + PKCE flow from the pasted `/mcp` URL alone: RFC 9728 Protected
// Resource Metadata + RFC 8414 Authorization Server Metadata. Both are
// public, deterministic, secret-free discovery documents.
"/.well-known/oauth-protected-resource",
"/.well-known/oauth-authorization-server",
]);
/**
@@ -86,6 +93,16 @@ function isPublicPath(pathname: string): boolean {
if (pathname === "/onboarding" || pathname.startsWith("/onboarding/")) {
return true;
}
// v1.22.0 — the remote MCP endpoint authenticates by `Authorization:
// Bearer hlk_…`, never by a session cookie, so it must skip the page
// cookie-redirect (mirroring the webhook / `/api/c/` header-authed
// surfaces). The route handler resolves the Bearer token itself, gates on
// the off-by-default `mcp` module, and rate-limits per credential. Exact
// `/mcp` plus `/mcp/` only — a `/mcp-something` page can never inherit
// the bypass.
if (pathname === "/mcp" || pathname.startsWith("/mcp/")) {
return true;
}
if (WELL_KNOWN_PUBLIC_PATHS.has(pathname)) {
return true;
}