package lagoon import ( "github.com/go-gormigrate/gormigrate/v2" "gorm.io/gorm" ) // BackendJWTBlacklistTable is the framework-owned jti table for admin tokens. // It is distinct from the frontend jwt_blacklist table. const BackendJWTBlacklistTable = "backend_jwt_blacklist" // BackendAdminMigrations creates Winter-shaped backend identity tables and // seeds the developer and publisher system roles. History is isolated under // the summercms.cabana plugin id. DDL is re-runnable so the system-role seed // stays idempotent if the history row is removed. var BackendAdminMigrations = []*gormigrate.Migration{ { ID: "202609240001_backend_admin_identity", Migrate: func(tx *gorm.DB) error { stmts := []string{ `CREATE TABLE IF NOT EXISTS backend_user_roles ( id SERIAL PRIMARY KEY, name TEXT NOT NULL UNIQUE, code TEXT, description TEXT, permissions TEXT, is_system BOOLEAN NOT NULL DEFAULT FALSE, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() )`, `CREATE TABLE IF NOT EXISTS backend_users ( id SERIAL PRIMARY KEY, first_name TEXT, last_name TEXT, login TEXT NOT NULL UNIQUE, email TEXT NOT NULL UNIQUE, password TEXT NOT NULL, activation_code TEXT, persist_code TEXT, reset_password_code TEXT, permissions TEXT, is_activated BOOLEAN NOT NULL DEFAULT FALSE, is_superuser BOOLEAN NOT NULL DEFAULT FALSE, role_id INTEGER REFERENCES backend_user_roles(id), activated_at TIMESTAMPTZ, last_login TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), deleted_at TIMESTAMPTZ, tokens_valid_after TIMESTAMPTZ )`, `CREATE TABLE IF NOT EXISTS backend_jwt_blacklist ( jti TEXT PRIMARY KEY, expires_at TIMESTAMPTZ NOT NULL, valid_until TIMESTAMPTZ NOT NULL )`, `CREATE INDEX IF NOT EXISTS backend_users_role_id_index ON backend_users (role_id)`, `CREATE INDEX IF NOT EXISTS backend_users_deleted_at_index ON backend_users (deleted_at)`, `CREATE INDEX IF NOT EXISTS backend_users_activation_code_index ON backend_users (activation_code)`, `CREATE INDEX IF NOT EXISTS backend_users_reset_password_code_index ON backend_users (reset_password_code)`, `CREATE INDEX IF NOT EXISTS backend_user_roles_code_index ON backend_user_roles (code)`, `INSERT INTO backend_user_roles (name, code, description, permissions, is_system) VALUES ('Developer', 'developer', 'Site administrator with access to developer tools.', '{}', TRUE), ('Publisher', 'publisher', 'Site editor with access to publishing tools.', '{}', TRUE) ON CONFLICT (name) DO NOTHING`, } for _, stmt := range stmts { if err := tx.Exec(stmt).Error; err != nil { return err } } return nil }, Rollback: func(tx *gorm.DB) error { for _, stmt := range []string{ `DROP TABLE IF EXISTS backend_jwt_blacklist`, `DROP TABLE IF EXISTS backend_users`, `DROP TABLE IF EXISTS backend_user_roles`, } { if err := tx.Exec(stmt).Error; err != nil { return err } } return nil }, }, }