Rate-limiting on messages.send, reports.create, reactions.toggle, follows.create, reposts.create. Unique constraints on Report to stop report-flooding. Mux webhook now fails hard in production without a signing secret instead of skipping verification. Admin-panel outline buttons fixed on 4 more pages (same white-on-dark bug as the Users page). Timing-safe comparison for ADMIN_SECRET/CRON_SECRET. Fixed duplicate HSTS header (Cloudflare's stronger one was being shadowed by the app's own). tRPC now returns clean JSON 401s instead of HTML redirects when unauthenticated, and no longer blocks public procedures for logged-out visitors. 14 previously-silent catch blocks now log to GlitchTip. invite/page.tsx and EmergencyVetSection.tsx fully localized (were 100% hardcoded German). Stale TODO comments removed, auth.test.ts scaffold rewritten to match the actual lazy-upsert pattern instead of a Clerk webhook flow that was never built.
34 lines
1.8 KiB
TypeScript
34 lines
1.8 KiB
TypeScript
/**
|
|
* Authentication — coverage notes
|
|
*
|
|
* AUTH-01 (owner row created with Clerk id, no password in app DB) is real,
|
|
* passing coverage, not a placeholder: `pets.create` lazily upserts the
|
|
* Owner row keyed by `ctx.userId` (see `src/trpc/routers/pets.ts`,
|
|
* `owner.upsert({ where: { id: ctx.userId }, create: { id: ctx.userId } })`),
|
|
* verified in `pet-profile.test.ts` ("pets.create upserts the owner row
|
|
* before inserting the pet"). There never was a Clerk `user.created` webhook
|
|
* — this file previously described one that was never built; the lazy-upsert
|
|
* pattern is the actual, working design (Owner row appears on first pet
|
|
* creation, not at sign-up). The `Owner` Prisma model has no password/
|
|
* credential field at all — Clerk is the sole auth store, structurally
|
|
* impossible to accidentally duplicate credentials into the app DB.
|
|
*
|
|
* AUTH-02 (email verification) is a genuine, currently-unimplemented gap,
|
|
* not a stale scaffold: `protectedProcedure` (src/trpc/init.ts) only checks
|
|
* `ctx.userId !== null`, with no check on Clerk's email-verification status.
|
|
* In practice this relies entirely on Clerk's hosted sign-up flow not
|
|
* issuing a session before verification — there is no server-side fallback
|
|
* if that assumption ever breaks (e.g. a future custom auth UI, or a Clerk
|
|
* config change). Left as `.todo` because building it requires a product
|
|
* decision (verified-only enforcement point, UX for unverified sessions),
|
|
* not just missing test coverage.
|
|
*/
|
|
|
|
import { describe, it } from "vitest";
|
|
|
|
describe("AUTH-02: Email verification (known gap, not yet enforced server-side)", () => {
|
|
it.todo(
|
|
"unverified owner cannot access protected tRPC procedures — protectedProcedure currently only checks ctx.userId, not verification status"
|
|
);
|
|
});
|