feat(panel): implement user management administration panel with sessions and minecraft link support

This commit is contained in:
Lemon-miaow committed 2026-07-04 04:08:14 +08:00
1 parent 83e57b4c45
commit 3347cc05d5
28 files changed
+4263 -68

No files matched your search

@@ -0,0 +1,40 @@
-- User management hardening: production-grade admin CRUD (spec §7 user admin).
-- Adds soft delete, disable toggle, audit timestamps, and an auto-updating
-- timestamp trigger so the admin user list reflects the last mutation without
-- every query re-deriving it from audit_logs.
-- Per-row lifecycle markers on the users table.
ALTER TABLE users
ADD COLUMN disabled boolean NOT NULL DEFAULT false,
ADD COLUMN deleted_at timestamptz,
ADD COLUMN updated_at timestamptz NOT NULL DEFAULT now();
-- updated_at auto-trigger, shared by any table that carries the column.
CREATE OR REPLACE FUNCTION felis_set_updated_at()
RETURNS trigger AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_users_updated_at
BEFORE UPDATE ON users
FOR EACH ROW EXECUTE FUNCTION felis_set_updated_at();
-- quotas gains its own audit timestamp so an admin change (including who made it)
-- is visible downstream.
ALTER TABLE quotas
ADD COLUMN updated_at timestamptz NOT NULL DEFAULT now(),
ADD COLUMN updated_by text;
CREATE TRIGGER trg_quotas_updated_at
BEFORE UPDATE ON quotas
FOR EACH ROW EXECUTE FUNCTION felis_set_updated_at();
-- Efficient lookups for the admin user list: filter by role and exclude
-- soft-deleted rows in one pass.
CREATE INDEX idx_users_role_active ON users (role)
WHERE deleted_at IS NULL AND disabled = false;
CREATE INDEX idx_users_deleted ON users (deleted_at)
WHERE deleted_at IS NOT NULL;
@@ -0,0 +1,18 @@
-- Owner role: a platform-level identity above admin. Only an owner may manage
-- users (create / edit / disable / delete / reset password / manage quotas and
-- sessions). The role is added at the end of the enum so it sorts after 'user'
-- and 'admin' — safe for existing data and type comparisons.
--
-- The Owner account is minted by `felis breakGlass` at first-run bootstrap;
-- additional Operators created later are role='admin'. The Owner is the one
-- identity that can never be demoted or deleted through the panel — only
-- another owner (the break-glass console) may reset a lost owner.
--
-- UPGRADE NOTE: after applying this migration, your existing first admin
-- account is still role='admin'. Re-provision it via `felis breakGlass` (the
-- Owner path) to promote it to role='owner'. That path is idempotent — it
-- preserves the existing user id and resets the credential, now with the owner
-- role. Alternatively, run directly:
-- UPDATE users SET role = 'owner' WHERE id = '<your-owner-user-id>';
ALTER TYPE user_role ADD VALUE 'owner';