Implement OAuth 2.0 login via GitHub as an alternative to email/password. Uses a provider registry pattern (internal/auth/oauth/) so adding Google or other providers later requires only a new Provider implementation. Flow: GET /v1/auth/oauth/github redirects to GitHub, callback exchanges the code for a user profile, upserts the user + team atomically, and redirects to the frontend with a JWT token. Key changes: - Migration: make password_hash nullable, add oauth_providers table - Provider registry with GitHubProvider (profile + email fallback) - CSRF state cookie with HMAC-SHA256 validation - Race-safe registration (23505 collision retries as login) - Startup validation: CP_PUBLIC_URL required when OAuth is configured Not fully tested — needs integration tests with a real GitHub OAuth app and end-to-end testing with the frontend callback page.
23 lines
606 B
SQL
23 lines
606 B
SQL
-- +goose Up
|
|
|
|
ALTER TABLE users
|
|
ALTER COLUMN password_hash DROP NOT NULL;
|
|
|
|
CREATE TABLE oauth_providers (
|
|
provider TEXT NOT NULL,
|
|
provider_id TEXT NOT NULL,
|
|
user_id TEXT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
email TEXT NOT NULL,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
PRIMARY KEY (provider, provider_id)
|
|
);
|
|
|
|
CREATE INDEX idx_oauth_providers_user ON oauth_providers(user_id);
|
|
|
|
-- +goose Down
|
|
|
|
DROP TABLE oauth_providers;
|
|
|
|
UPDATE users SET password_hash = '' WHERE password_hash IS NULL;
|
|
ALTER TABLE users ALTER COLUMN password_hash SET NOT NULL;
|