Prepare v2.0.0 release
This commit is contained in:
+31
-119
@@ -1,31 +1,6 @@
|
||||
const mysql = require('mysql2/promise');
|
||||
const { hashPassword } = require('../auth');
|
||||
const { PERMISSIONS, DEFAULT_ROLE } = require('../rbac');
|
||||
const migrations = require('./migrations');
|
||||
|
||||
function createPool() {
|
||||
return mysql.createPool({
|
||||
host: process.env.DB_HOST || '127.0.0.1',
|
||||
port: Number(process.env.DB_PORT || 3306),
|
||||
user: process.env.DB_USER || 'signage_user',
|
||||
password: process.env.DB_PASSWORD || 'signage_password',
|
||||
database: process.env.DB_NAME || 'signage',
|
||||
waitForConnections: true,
|
||||
connectionLimit: 10,
|
||||
namedPlaceholders: true
|
||||
});
|
||||
}
|
||||
|
||||
async function pruneStaleOnboardingDevices(pool) {
|
||||
await pool.query(
|
||||
`DELETE FROM player_onboarding_devices
|
||||
WHERE modified_at < (CURRENT_TIMESTAMP - INTERVAL 1 MINUTE)`
|
||||
);
|
||||
}
|
||||
|
||||
async function ensureSchema(pool, options) {
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS canvas_sizes (
|
||||
CREATE TABLE IF NOT EXISTS c_canvas_sizes (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
width INT NOT NULL,
|
||||
@@ -39,7 +14,7 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS playlists (
|
||||
CREATE TABLE IF NOT EXISTS c_playlists (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
fade_between_slides TINYINT(1) NOT NULL DEFAULT 0,
|
||||
@@ -52,7 +27,7 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS slide_templates (
|
||||
CREATE TABLE IF NOT EXISTS c_templates (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
canvas_size_id INT NULL,
|
||||
@@ -66,7 +41,7 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
INSERT IGNORE INTO canvas_sizes (name, width, height) VALUES
|
||||
INSERT IGNORE INTO c_canvas_sizes (name, width, height) VALUES
|
||||
('Full HD', 1920, 1080),
|
||||
('HD', 1280, 720),
|
||||
('4K UHD', 3840, 2160),
|
||||
@@ -75,12 +50,13 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS slide_template_regions (
|
||||
CREATE TABLE IF NOT EXISTS c_template_regions (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
template_id INT NOT NULL,
|
||||
region_key VARCHAR(100) NOT NULL,
|
||||
region_type VARCHAR(20) NOT NULL,
|
||||
label VARCHAR(255) NOT NULL,
|
||||
font_family VARCHAR(100) NULL,
|
||||
lock_ratio VARCHAR(20) NULL,
|
||||
x INT NOT NULL DEFAULT 0,
|
||||
y INT NOT NULL DEFAULT 0,
|
||||
@@ -95,14 +71,11 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS slides (
|
||||
CREATE TABLE IF NOT EXISTS c_slides (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
body TEXT NULL,
|
||||
template_id INT NULL,
|
||||
content_json JSON NULL,
|
||||
media_path VARCHAR(512) NULL,
|
||||
media_type VARCHAR(100) NULL,
|
||||
thumbnail_path VARCHAR(512) NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by INT NULL,
|
||||
@@ -112,7 +85,7 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS playlist_slides (
|
||||
CREATE TABLE IF NOT EXISTS c_playlist_slides (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
playlist_id INT NOT NULL,
|
||||
slide_id INT NOT NULL,
|
||||
@@ -129,27 +102,28 @@ async function ensureSchema(pool, options) {
|
||||
created_by INT NULL,
|
||||
modified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
modified_by INT NULL,
|
||||
CONSTRAINT fk_playlist_slides_playlist FOREIGN KEY (playlist_id) REFERENCES playlists(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_playlist_slides_slide FOREIGN KEY (slide_id) REFERENCES slides(id) ON DELETE CASCADE
|
||||
CONSTRAINT fk_playlist_slides_playlist FOREIGN KEY (playlist_id) REFERENCES c_playlists(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_playlist_slides_slide FOREIGN KEY (slide_id) REFERENCES c_slides(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS screens (
|
||||
CREATE TABLE IF NOT EXISTS d_screens (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
slug VARCHAR(255) NOT NULL UNIQUE,
|
||||
playlist_id INT NULL,
|
||||
player_id INT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by INT NULL,
|
||||
modified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
modified_by INT NULL,
|
||||
CONSTRAINT fk_screens_playlist FOREIGN KEY (playlist_id) REFERENCES playlists(id) ON DELETE SET NULL
|
||||
CONSTRAINT fk_screens_playlist FOREIGN KEY (playlist_id) REFERENCES c_playlists(id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS rss_feeds (
|
||||
CREATE TABLE IF NOT EXISTS i_rss_feeds (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
feed_url VARCHAR(1024) NOT NULL,
|
||||
@@ -164,7 +138,7 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS rss_feed_items (
|
||||
CREATE TABLE IF NOT EXISTS i_rss_feed_items (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
rss_feed_id INT NOT NULL,
|
||||
position INT NOT NULL,
|
||||
@@ -173,13 +147,13 @@ async function ensureSchema(pool, options) {
|
||||
created_by INT NULL,
|
||||
modified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
modified_by INT NULL,
|
||||
CONSTRAINT fk_rss_feed_items_rss_feed FOREIGN KEY (rss_feed_id) REFERENCES rss_feeds(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_rss_feed_items_rss_feed FOREIGN KEY (rss_feed_id) REFERENCES i_rss_feeds(id) ON DELETE CASCADE,
|
||||
UNIQUE KEY uq_rss_feed_items_feed_position (rss_feed_id, position)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS api_sources (
|
||||
CREATE TABLE IF NOT EXISTS i_api_sources (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
api_url VARCHAR(1024) NOT NULL,
|
||||
@@ -198,7 +172,7 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS player_onboarding_devices (
|
||||
CREATE TABLE IF NOT EXISTS d_onboarding_devices (
|
||||
device_id VARCHAR(128) PRIMARY KEY,
|
||||
client_name VARCHAR(255) NULL,
|
||||
screen_id INT NULL,
|
||||
@@ -206,12 +180,12 @@ async function ensureSchema(pool, options) {
|
||||
created_by INT NULL,
|
||||
modified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
modified_by INT NULL,
|
||||
CONSTRAINT fk_player_onboarding_devices_screen FOREIGN KEY (screen_id) REFERENCES screens(id) ON DELETE SET NULL
|
||||
CONSTRAINT fk_player_onboarding_devices_screen FOREIGN KEY (screen_id) REFERENCES d_screens(id) ON DELETE SET NULL
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
CREATE TABLE IF NOT EXISTS a_users (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(255) NULL,
|
||||
username VARCHAR(255) NOT NULL UNIQUE,
|
||||
@@ -226,7 +200,7 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
CREATE TABLE IF NOT EXISTS a_roles (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
role_key VARCHAR(100) NOT NULL UNIQUE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
@@ -239,7 +213,7 @@ async function ensureSchema(pool, options) {
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS permissions (
|
||||
CREATE TABLE IF NOT EXISTS a_permissions (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
permission_key VARCHAR(100) NOT NULL UNIQUE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
@@ -252,17 +226,8 @@ async function ensureSchema(pool, options) {
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
|
||||
for (const permission of PERMISSIONS) {
|
||||
await pool.query(
|
||||
`INSERT INTO permissions (permission_key, name, section_name, description, created_by, modified_by)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE name = VALUES(name), section_name = VALUES(section_name), description = VALUES(description), modified_by = VALUES(modified_by)` ,
|
||||
[permission.key, permission.name, permission.sectionName, permission.description || null, null, null]
|
||||
);
|
||||
}
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS role_permissions (
|
||||
CREATE TABLE IF NOT EXISTS a_role_permissions (
|
||||
role_id INT NOT NULL,
|
||||
permission_id INT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
@@ -270,13 +235,13 @@ async function ensureSchema(pool, options) {
|
||||
modified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
modified_by INT NULL,
|
||||
PRIMARY KEY (role_id, permission_id),
|
||||
CONSTRAINT fk_role_permissions_role FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_role_permissions_permission FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE
|
||||
CONSTRAINT fk_role_permissions_role FOREIGN KEY (role_id) REFERENCES a_roles(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_role_permissions_permission FOREIGN KEY (permission_id) REFERENCES a_permissions(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS user_roles (
|
||||
CREATE TABLE IF NOT EXISTS a_user_roles (
|
||||
user_id INT NOT NULL,
|
||||
role_id INT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
@@ -284,13 +249,13 @@ async function ensureSchema(pool, options) {
|
||||
modified_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
modified_by INT NULL,
|
||||
PRIMARY KEY (user_id, role_id),
|
||||
CONSTRAINT fk_user_roles_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_user_roles_role FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE
|
||||
CONSTRAINT fk_user_roles_user FOREIGN KEY (user_id) REFERENCES a_users(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_user_roles_role FOREIGN KEY (role_id) REFERENCES a_roles(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS auth_sessions (
|
||||
CREATE TABLE IF NOT EXISTS a_sessions (
|
||||
session_hash CHAR(64) PRIMARY KEY,
|
||||
user_id INT NOT NULL,
|
||||
expires_at DATETIME NOT NULL,
|
||||
@@ -298,12 +263,12 @@ async function ensureSchema(pool, options) {
|
||||
created_by INT NULL,
|
||||
last_used_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
modified_by INT NULL,
|
||||
CONSTRAINT fk_auth_sessions_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
CONSTRAINT fk_auth_sessions_user FOREIGN KEY (user_id) REFERENCES a_users(id) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
|
||||
await pool.query(`
|
||||
CREATE TABLE IF NOT EXISTS background_tasks (
|
||||
CREATE TABLE IF NOT EXISTS o_background_tasks (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
task_key VARCHAR(191) NULL,
|
||||
task_type VARCHAR(100) NOT NULL,
|
||||
@@ -322,61 +287,8 @@ async function ensureSchema(pool, options) {
|
||||
INDEX idx_background_tasks_type (task_type)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
|
||||
`);
|
||||
|
||||
const [userCountRows] = await pool.query('SELECT COUNT(*) AS user_count FROM users');
|
||||
const username = String(process.env.DEFAULT_ADMIN_USERNAME || 'admin').trim() || 'admin';
|
||||
if (!userCountRows.length || Number(userCountRows[0].user_count) === 0) {
|
||||
const name = String(process.env.DEFAULT_ADMIN_NAME || 'Admin').trim() || 'Admin';
|
||||
const password = String(process.env.DEFAULT_ADMIN_PASSWORD || 'admin').trim() || 'admin';
|
||||
const passwordRecord = hashPassword(password);
|
||||
await pool.query(
|
||||
'INSERT INTO users (name, username, password_hash, password_salt, password_iterations, created_by, modified_by) VALUES (?, ?, ?, ?, ?, ?, ?)',
|
||||
[name, username, passwordRecord.hash, passwordRecord.salt, passwordRecord.iterations, null, null]
|
||||
);
|
||||
}
|
||||
|
||||
await pool.query('UPDATE users SET name = username WHERE name IS NULL OR name = ""');
|
||||
|
||||
await pool.query(
|
||||
`INSERT INTO roles (role_key, name, description, created_by, modified_by)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE name = VALUES(name), description = VALUES(description), modified_by = VALUES(modified_by)`,
|
||||
[DEFAULT_ROLE.key, DEFAULT_ROLE.name, DEFAULT_ROLE.description || null, null, null]
|
||||
);
|
||||
|
||||
await migrations.runMigrations(pool, options || {});
|
||||
|
||||
if (!userCountRows.length || Number(userCountRows[0].user_count) === 0) {
|
||||
const [roleRows] = await pool.query('SELECT id FROM roles WHERE role_key = ? LIMIT 1', [DEFAULT_ROLE.key]);
|
||||
const defaultRoleId = roleRows.length ? Number(roleRows[0].id) : null;
|
||||
if (defaultRoleId) {
|
||||
await pool.query(
|
||||
`INSERT IGNORE INTO user_roles (user_id, role_id, created_by, modified_by)
|
||||
SELECT id, ?, NULL, NULL FROM users`,
|
||||
[defaultRoleId]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const [defaultAdminRows] = await pool.query('SELECT id FROM users WHERE username = ? LIMIT 1', [username]);
|
||||
if (defaultAdminRows.length) {
|
||||
const defaultAdminId = Number(defaultAdminRows[0].id);
|
||||
const [defaultAdminRoleRows] = await pool.query('SELECT COUNT(*) AS role_count FROM user_roles WHERE user_id = ?', [defaultAdminId]);
|
||||
if (!defaultAdminRoleRows.length || Number(defaultAdminRoleRows[0].role_count) === 0) {
|
||||
const [roleRows] = await pool.query('SELECT id FROM roles WHERE role_key = ? LIMIT 1', [DEFAULT_ROLE.key]);
|
||||
const defaultRoleId = roleRows.length ? Number(roleRows[0].id) : null;
|
||||
if (defaultRoleId) {
|
||||
await pool.query(
|
||||
'INSERT IGNORE INTO user_roles (user_id, role_id, created_by, modified_by) VALUES (?, ?, ?, ?)',
|
||||
[defaultAdminId, defaultRoleId, null, null]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
createPool,
|
||||
ensureSchema,
|
||||
pruneStaleOnboardingDevices
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user