-- Migration 0016_jwt_revocations.up.sql -- -- Introduces server-side JWT revocation for the SolaceScan backend. -- -- Up to this migration, tokens issued by /api/v1/auth/wallet were simply -- signed and returned; the backend had no way to invalidate a token before -- its exp claim short of rotating the JWT_SECRET (which would invalidate -- every outstanding session). PR #8 introduces per-token revocation keyed -- on the `jti` claim. -- -- The table is append-only: a row exists iff that jti has been revoked. -- ValidateJWT consults the table on every request; the primary key on -- (jti) keeps lookups O(log n) and deduplicates repeated logout calls. CREATE TABLE IF NOT EXISTS jwt_revocations ( jti TEXT PRIMARY KEY, address TEXT NOT NULL, track INT NOT NULL, -- original exp of the revoked token, so a background janitor can -- reap rows after they can no longer matter. token_expires_at TIMESTAMPTZ NOT NULL, revoked_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), reason TEXT NOT NULL DEFAULT 'logout' ); CREATE INDEX IF NOT EXISTS idx_jwt_revocations_address ON jwt_revocations (address); CREATE INDEX IF NOT EXISTS idx_jwt_revocations_expires ON jwt_revocations (token_expires_at);