Skip to content

Audit fixes#1

Merged
dillonstreator merged 4 commits into
mainfrom
audit-fixes
Jul 3, 2026
Merged

Audit fixes#1
dillonstreator merged 4 commits into
mainfrom
audit-fixes

Conversation

@dillonstreator

Copy link
Copy Markdown
Member

No description provided.

dillonstreator and others added 2 commits July 2, 2026 09:48
…rivacy

Fixes the FATAL + MAJOR items from the full-spectrum audit.

FATAL
- F1 ship the viral loop: metadataBase + default and per-referrer OG images
  (next/og), a referrer hook card consuming /api/referrer, clickedRef
  recognize-and-celebrate, and an SSE live-join ticker wired to /api/live.
- F2 keep reads off the graph: rank now counts the indexed cached_metrics only
  (no per-poll O(N*subtree) union scan); leaderboard bounds solo rows in SQL
  (ORDER BY reach DESC LIMIT) instead of streaming every human node into JS and
  slicing; leaderboard route gains an s-maxage cache header; statement_timeout
  set on both drivers.

MAJOR
- M1 cached max_depth stored absolute but read relative; subtract node depth at
  read so cached and live agree (verified equal on seeded data).
- M2/M9 add /api/cron/reconcile (recompute cached_metrics from live subtree +
  reap expired tokens, CRON_SECRET-guarded) and a suspect flag: high-risk nodes
  are created+rendered but excluded from reach/leaderboard; ipShared crowd
  signal now computed instead of hardcoded false.
- M3 exclude verified/account-linked nodes from fingerprint re-link to prevent
  node/account takeover via replayed or colliding visitorIds.
- M4 drop @vercel/analytics so "no third-party trackers" is true; add
  /api/auth/delete (GDPR erasure keyed by wh_lid cookie) + retention copy.
- M5 gate /api/me on wh_lid cookie ownership so the public share code no longer
  exposes every linked device's coordinates.
- M6 await magic send and delete the token row on failure so a send outage no
  longer locks the user out for the TTL.
- M7 surface registration failures with a retry banner and auto-recover
  identity_mismatch by clearing the cookie and retrying once.
- M8 provision Postgres in CI and run migrations so integration tests actually
  execute.

Verified: typecheck, build, 24/24 tests (incl. integration) against local
Postgres; OG PNGs render 1200x630; /api/me returns 200 owner / 403 wrong / 401
none; cached==live metrics after reconcile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Remove dead exports never called anywhere: reads.meDetail (superseded by
  meBundle), reads.rankOf, graph.ancestry, format.fmtFull, magic-verify.peekMagicToken.
- error.tsx: stop rendering raw error.message to users (info leak); show a
  generic message + digest ref, and align to design tokens instead of ad-hoc
  zinc/sky colors.
- About copy honesty: drop the "precise placement is strictly opt-in" claim (the
  opt-in precise-geo path was never built) and the analytics reference is already
  gone; add a plain-language note on why the fingerprint exists and that it's
  never used for cross-site tracking.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

Deployment failed with the following error:

Hobby accounts are limited to daily cron jobs. This cron expression (17 * * * *) would run more than once per day. Upgrade to the Pro plan to unlock all Cron Jobs features on Vercel.

Learn More: https://vercel.link/3Fpeeb1

The reconcile cron was scheduled hourly (`17 * * * *`), which fails Vercel
deployment on Hobby accounts ("limited to daily cron jobs. This cron expression
would run more than once per day"). Reconciliation and token reaping don't need
hourly cadence, so switch to once-daily (`17 4 * * *`, ~04:17 UTC) — valid on
Hobby, Pro, and Enterprise.

The route's Bearer-token guard already matches Vercel's documented pattern:
Vercel sends `Authorization: Bearer $CRON_SECRET` only when CRON_SECRET is set in
project env, and the handler 503s without a secret / 401s on mismatch. Set
CRON_SECRET in the Vercel project for the job to run (documented in .env.example).

Also add the $schema reference to vercel.json for config validation.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jul 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldhello.io Ready Ready Preview, Comment Jul 2, 2026 4:25pm

Neon deploys don't run migrations automatically, and drizzle-kit isn't available
in the serverless runtime, so schema changes (like the new suspect column) would
never reach production. Add an idempotent, secret-guarded runner that CI invokes
after each production deploy.

- /api/migrate (POST, Bearer MIGRATE_SECRET): applies pending Drizzle migrations
  against the UNPOOLED endpoint (DDL + advisory lock need a direct connection).
  503 without the secret, 401 on mismatch, 200 on apply/no-op. Chooses the
  neon-http or node-postgres migrator by URL, mirroring src/db/migrate.ts.
- next.config.ts outputFileTracingIncludes bundles src/db/migrations/** into that
  function — the migrator reads the raw SQL + journal at runtime and the tracer
  won't include non-imported files otherwise. Verified 10 migration files land in
  the function's .nft trace.
- .github/workflows/deploy-migrate.yml listens for a successful Production
  deployment_status (Vercel's Git integration reports these to GitHub) and POSTs
  the endpoint at the deployment URL with the MIGRATE_SECRET GitHub secret.

Verified end-to-end against a wiped local DB: all tables, the suspect column, the
ltree extension, and the set_node_path trigger apply; re-run is a clean no-op;
auth rejects missing/wrong tokens.

Set MIGRATE_SECRET in both Vercel project env and GitHub Actions secrets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@dillonstreator dillonstreator merged commit fac84bb into main Jul 3, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant