API keys (roadmap: 'API key management per license'):
- migration 023_api_keys; ApiKey entity; ApiKeysModule (@Global, exports
ApiKeysService) wired into app.module.
- Service: create (corr_<prefix>_<secret>, returns plaintext once, stores
sha256 hash + prefix), list (no hash), revoke, and validateKey(rawKey) ->
{ license_id } for a future API-key auth guard. Controller license-scoped +
RBAC (apikeys.view/manage).
Roadmap: moved the shipped multi-game items (multi-instance host runtime,
per-game wipe + event scheduling) into a 'Phase 2 — Multi-game runtime' shipped
group; Dune/Conan/Soulmask Formulae stay in-progress.
Backend tsc + frontend build green. Migration applies on a fresh DB (Saturday host).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
18 lines
773 B
SQL
18 lines
773 B
SQL
-- Per-license API key management
|
|
-- Each row represents one issued key: the plaintext is shown once at creation
|
|
-- and never stored; only the SHA-256 hex digest is persisted.
|
|
|
|
CREATE TABLE IF NOT EXISTS api_keys (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE,
|
|
name VARCHAR(100) NOT NULL,
|
|
key_prefix VARCHAR(16) NOT NULL,
|
|
key_hash VARCHAR(128) NOT NULL,
|
|
last_used_at TIMESTAMPTZ NULL,
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_api_keys_license ON api_keys(license_id);
|
|
CREATE INDEX IF NOT EXISTS idx_api_keys_key_hash ON api_keys(key_hash);
|