feat(panel): implement user management administration panel with sessions and minecraft link support
This commit is contained in:
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';
|
||||
Reference in new issue
Block a user