console: sync the registration wizard and issue real API tokens

Mirror the Console registration feature: native hook catalog with
activation plans, one-command install that embeds both credentials in
exclusively created owner-only files (mktemp on POSIX, icacls on
Windows), sh/PowerShell tabs, never-expiring default token, focus-visible
styles, merged i18n keys, and the matching e2e specs.

The server previously answered /v1/auth/token with the 7-day Better Auth
session token and ignored ttl_seconds. It now issues opaque 32-byte API
tokens stored as SHA-256 hashes (migration 003), honours ttl_seconds with
null meaning no expiry, and resolves bearer values as API tokens before
session validation. Issuance requires a session credential.

Claude-Session: https://claude.ai/code/session_01QoUjdc7HGKTsgj5GhG8HvF
This commit is contained in:
雷电芽衣 committed 2026-09-02 09:56:40 -04:00
1 parent 1bb9d4d49d
commit edf9d73c3e
21 files changed
+967 -163

No files matched your search

+15
View File
@@ -231,6 +231,17 @@ services:
CREATE INDEX IF NOT EXISTS idx_exports_org_status ON exports (org_id, status);
CREATE TABLE IF NOT EXISTS api_tokens (
token_id TEXT NOT NULL PRIMARY KEY,
user_id TEXT NOT NULL REFERENCES users (user_id),
org_id TEXT NOT NULL REFERENCES organizations (org_id),
token_hash TEXT NOT NULL UNIQUE,
issued_at BIGINT NOT NULL,
expires_at BIGINT
);
CREATE INDEX IF NOT EXISTS idx_api_tokens_user_id ON api_tokens (user_id);
INSERT INTO schema_versions (version, applied_at, description)
VALUES (1, EXTRACT(EPOCH FROM NOW())::BIGINT * 1000, 'Initial schema')
ON CONFLICT DO NOTHING;
@@ -238,6 +249,10 @@ services:
INSERT INTO schema_versions (version, applied_at, description)
VALUES (2, EXTRACT(EPOCH FROM NOW())::BIGINT * 1000, 'Require supported agent integration type')
ON CONFLICT DO NOTHING;
INSERT INTO schema_versions (version, applied_at, description)
VALUES (3, EXTRACT(EPOCH FROM NOW())::BIGINT * 1000, 'Opaque API tokens')
ON CONFLICT DO NOTHING;
"
restart: on-failure