| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- // @vitest-environment node
- /**
- * Smoke test: a hand-minted HS256 JWT (mintAccessToken) is accepted by
- * PostgREST. RLS resolves `auth.uid()` to the JWT's `sub` and returns
- * exactly the rows that user is allowed to see.
- *
- * Gated on RUN_INTEGRATION=1; skipped otherwise.
- *
- * We test PostgREST rather than Realtime directly because:
- * - Realtime accepts the same JWT via the same HS256 verification path,
- * so PostgREST acceptance proves the load-bearing claim.
- * - The Realtime ws client adds harness complexity disproportionate to
- * the assertion.
- */
- import { describe, it, expect } from "vitest";
- import { createClient } from "@supabase/supabase-js";
- import { randomUUID } from "node:crypto";
- const RUN = process.env.RUN_INTEGRATION === "1";
- const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL ?? "";
- const SUPABASE_ANON = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY ?? "";
- const SUPABASE_SERVICE = process.env.SUPABASE_SERVICE_ROLE_KEY ?? "";
- (RUN ? describe : describe.skip)("integration: minted JWT accepted by PostgREST", () => {
- it("a JWT signed with JWT_SECRET resolves auth.uid() under RLS", async () => {
- expect(process.env.JWT_SECRET).toBeTruthy();
- // Sign an anon user up (real auth.users row required for FKs / RLS).
- const anon = createClient(SUPABASE_URL, SUPABASE_ANON, {
- auth: { persistSession: false, autoRefreshToken: false },
- });
- const { data: signin } = await anon.auth.signInAnonymously();
- const uid = signin.user!.id;
- // Persist a session row so isSessionLive() would pass — not strictly
- // required for PostgREST but matches the production token shape.
- const admin = createClient(SUPABASE_URL, SUPABASE_SERVICE, {
- auth: { persistSession: false, autoRefreshToken: false },
- });
- await admin.from("user_sessions").insert({ user_id: uid, id: randomUUID() });
- const { mintAccessToken } = await import("@/lib/auth/jwt");
- const token = await mintAccessToken({
- sub: uid,
- session_id: randomUUID(),
- iat_original: Math.floor(Date.now() / 1000),
- });
- // Construct an anon client and inject our minted token. PostgREST will
- // verify the HS256 signature and resolve auth.uid() = uid for RLS.
- const minted = createClient(SUPABASE_URL, SUPABASE_ANON, {
- auth: { persistSession: false, autoRefreshToken: false },
- global: { headers: { Authorization: `Bearer ${token}` } },
- });
- // Read the user's own row (RLS allows: auth.uid() = id).
- const { data, error } = await minted.from("users").select("id").eq("id", uid).maybeSingle();
- expect(error).toBeNull();
- expect(data?.id).toBe(uid);
- }, 30_000);
- });
|