43 lines
1.8 KiB
SQL
43 lines
1.8 KiB
SQL
-- Admin users and sessions for the Next.js admin area.
|
|
-- Run after catherine_league schema exists: mysql ... < admin_auth.sql
|
|
|
|
USE `catherine_league`;
|
|
|
|
-- Passwords stored as bcrypt hashes (e.g. from bcryptjs), never plaintext.
|
|
CREATE TABLE IF NOT EXISTS `admin_users` (
|
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`email` VARCHAR(255) NOT NULL,
|
|
`password_hash` VARCHAR(255) NOT NULL,
|
|
`is_approved` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`is_admin` TINYINT(1) NOT NULL DEFAULT 0,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_admin_users_email` (`email`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- Opaque session tokens: store SHA-256 hex of the cookie value; never store raw tokens.
|
|
CREATE TABLE IF NOT EXISTS `admin_sessions` (
|
|
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
|
`user_id` INT UNSIGNED NOT NULL,
|
|
`token_hash` CHAR(64) NOT NULL,
|
|
`expires_at` DATETIME NOT NULL,
|
|
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
PRIMARY KEY (`id`),
|
|
UNIQUE KEY `uk_admin_sessions_token_hash` (`token_hash`),
|
|
KEY `idx_admin_sessions_user_id` (`user_id`),
|
|
KEY `idx_admin_sessions_expires_at` (`expires_at`),
|
|
CONSTRAINT `fk_admin_sessions_user`
|
|
FOREIGN KEY (`user_id`) REFERENCES `admin_users` (`id`) ON DELETE CASCADE
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
-- Seed: first admin (change password immediately in production).
|
|
-- Default password: ChangeMeOnFirstLogin!
|
|
INSERT INTO `admin_users` (`email`, `password_hash`, `is_approved`, `is_admin`)
|
|
SELECT
|
|
'admin@localhost',
|
|
'$2b$12$H6Y71zX/nmefp33e0MaMaOOBGSiVwxVE3L.Ie3Pfq1/6QZdLR7bTa',
|
|
1,
|
|
1
|
|
WHERE NOT EXISTS (SELECT 1 FROM `admin_users` WHERE `email` = 'admin@localhost' LIMIT 1);
|