-- Migration: Secure token storage and add authorization codes -- Date: 2025-11-24 -- Version: 0.10.0 (BREAKING CHANGE) -- ADR: ADR-029 Micropub IndieAuth Integration Strategy -- -- SECURITY FIX: Migrate tokens table to use SHA256 hashed storage -- BREAKING CHANGE: All existing tokens will be invalidated -- -- This migration: -- 1. Creates new secure tokens table with token_hash column -- 2. Drops old insecure tokens table (invalidates all existing tokens) -- 3. Creates authorization_codes table for IndieAuth token exchange -- 4. Adds appropriate indexes for performance -- Step 1: Drop the old insecure tokens table -- This invalidates all existing tokens (necessary security fix) DROP TABLE IF EXISTS tokens; -- Step 2: Create new secure tokens table CREATE TABLE tokens ( id INTEGER PRIMARY KEY AUTOINCREMENT, token_hash TEXT UNIQUE NOT NULL, -- SHA256 hash of token (never store plain text) me TEXT NOT NULL, -- User identity URL client_id TEXT, -- Client application URL scope TEXT DEFAULT 'create', -- Granted scopes (V1: only 'create') created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, expires_at TIMESTAMP NOT NULL, -- Token expiration (90 days default) last_used_at TIMESTAMP, -- Track last usage for auditing revoked_at TIMESTAMP -- Soft revocation support ); -- Step 3: Create authorization_codes table for token exchange CREATE TABLE authorization_codes ( id INTEGER PRIMARY KEY AUTOINCREMENT, code_hash TEXT UNIQUE NOT NULL, -- SHA256 hash of authorization code me TEXT NOT NULL, -- User identity URL client_id TEXT NOT NULL, -- Client application URL redirect_uri TEXT NOT NULL, -- Client's redirect URI (must match on exchange) scope TEXT, -- Requested scopes (can be empty per IndieAuth spec) state TEXT, -- Client's state parameter code_challenge TEXT, -- Optional PKCE code challenge code_challenge_method TEXT, -- PKCE method (S256 if used) created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, expires_at TIMESTAMP NOT NULL, -- Short expiry (10 minutes default) used_at TIMESTAMP -- Prevent replay attacks (code can only be used once) ); -- Step 4: Create indexes for performance CREATE INDEX idx_tokens_hash ON tokens(token_hash); CREATE INDEX idx_tokens_me ON tokens(me); CREATE INDEX idx_tokens_expires ON tokens(expires_at); CREATE INDEX idx_auth_codes_hash ON authorization_codes(code_hash); CREATE INDEX idx_auth_codes_expires ON authorization_codes(expires_at); -- Migration complete -- Security notice: All users must re-authenticate after this migration