Prepare v2.0.0 release
This commit is contained in:
@@ -66,7 +66,7 @@ function registerBackgroundTaskHandlers(options) {
|
||||
}
|
||||
|
||||
const [slides] = await pool.query(
|
||||
'SELECT id, thumbnail_path FROM slides WHERE template_id = ? ORDER BY id ASC',
|
||||
'SELECT id, thumbnail_path FROM c_slides WHERE template_id = ? ORDER BY id ASC',
|
||||
[templateId]
|
||||
);
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ function createBackgroundTaskQueue(options) {
|
||||
|
||||
const record = buildTaskRecord(task);
|
||||
const [result] = await pool.query(
|
||||
`INSERT INTO background_tasks (
|
||||
`INSERT INTO o_background_tasks (
|
||||
task_key,
|
||||
task_type,
|
||||
title,
|
||||
@@ -196,7 +196,7 @@ function createBackgroundTaskQueue(options) {
|
||||
|
||||
const record = buildTaskRecord(task);
|
||||
await pool.query(
|
||||
`UPDATE background_tasks
|
||||
`UPDATE o_background_tasks
|
||||
SET task_key = ?, task_type = ?, title = ?, category = ?, status = ?, payload_json = ?, metadata_json = ?, attempts = ?, started_at = ?, finished_at = ?, error_message = ?
|
||||
WHERE id = ?`,
|
||||
[
|
||||
@@ -221,7 +221,7 @@ function createBackgroundTaskQueue(options) {
|
||||
return;
|
||||
}
|
||||
|
||||
await pool.query('DELETE FROM background_tasks WHERE id = ?', [taskId]);
|
||||
await pool.query('DELETE FROM o_background_tasks WHERE id = ?', [taskId]);
|
||||
}
|
||||
|
||||
async function initialize() {
|
||||
@@ -235,7 +235,7 @@ function createBackgroundTaskQueue(options) {
|
||||
}
|
||||
|
||||
const [rows] = await pool.query(
|
||||
'SELECT id, task_key, task_type, title, category, status, payload_json, metadata_json, attempts, created_at, started_at, finished_at, error_message FROM background_tasks ORDER BY id ASC'
|
||||
'SELECT id, task_key, task_type, title, category, status, payload_json, metadata_json, attempts, created_at, started_at, finished_at, error_message FROM o_background_tasks ORDER BY id ASC'
|
||||
);
|
||||
|
||||
let highestTaskId = 0;
|
||||
@@ -254,7 +254,7 @@ function createBackgroundTaskQueue(options) {
|
||||
task.finishedAt = '';
|
||||
task.errorMessage = '';
|
||||
await pool.query(
|
||||
'UPDATE background_tasks SET status = ?, started_at = NULL, finished_at = NULL, error_message = NULL WHERE id = ?',
|
||||
'UPDATE o_background_tasks SET status = ?, started_at = NULL, finished_at = NULL, error_message = NULL WHERE id = ?',
|
||||
['queued', task.id]
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ function registerBackgroundTaskScheduling(options) {
|
||||
const removeUnusedUploadFiles = options && options.removeUnusedUploadFiles;
|
||||
const refreshApiSource = options && options.refreshApiSource;
|
||||
const refreshRssFeed = options && options.refreshRssFeed;
|
||||
const uploadsDir = String(options && options.uploadsDir || '').trim();
|
||||
const mediaDir = String(options && options.mediaDir || '').trim();
|
||||
const dataSourceStartupRefreshStaggerMs = Math.max(100, Number(options && options.dataSourceStartupRefreshStaggerMs || 250));
|
||||
|
||||
if (!pool || !common || !backgroundTaskQueue || !collectUploadPathsFromDirectory || !removeUnusedUploadFiles || !refreshApiSource || !refreshRssFeed || !uploadsDir) {
|
||||
if (!pool || !common || !backgroundTaskQueue || !collectUploadPathsFromDirectory || !removeUnusedUploadFiles || !refreshApiSource || !refreshRssFeed || !mediaDir) {
|
||||
throw new Error('registerBackgroundTaskScheduling requires the background task dependencies.');
|
||||
}
|
||||
|
||||
@@ -55,12 +55,12 @@ function registerBackgroundTaskScheduling(options) {
|
||||
|
||||
async function registerRecurringMaintenanceTasks() {
|
||||
async function runUnusedUploadSweep() {
|
||||
const uploadPaths = await collectUploadPathsFromDirectory(uploadsDir);
|
||||
const uploadPaths = await collectUploadPathsFromDirectory(mediaDir);
|
||||
if (!uploadPaths.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
await removeUnusedUploadFiles(pool, uploadsDir, uploadPaths);
|
||||
await removeUnusedUploadFiles(pool, mediaDir, uploadPaths);
|
||||
}
|
||||
|
||||
backgroundTaskQueue.registerRecurringTask({
|
||||
@@ -69,7 +69,7 @@ function registerBackgroundTaskScheduling(options) {
|
||||
category: 'media-sync',
|
||||
intervalMs: 24 * 60 * 60 * 1000,
|
||||
metadata: {
|
||||
uploadDir: uploadsDir
|
||||
mediaDir: mediaDir
|
||||
},
|
||||
run: runUnusedUploadSweep
|
||||
});
|
||||
|
||||
@@ -67,8 +67,8 @@ function createDashboardStateService(options) {
|
||||
|
||||
const [onboardingRows] = await pool.query(
|
||||
`SELECT s.slug, pod.device_id, pod.client_name
|
||||
FROM player_onboarding_devices pod
|
||||
JOIN screens s ON s.id = pod.screen_id
|
||||
FROM d_onboarding_devices pod
|
||||
JOIN d_screens s ON s.id = pod.screen_id
|
||||
WHERE pod.client_name IS NOT NULL
|
||||
AND TRIM(pod.client_name) <> ''`
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ async function refreshApiSource(pool, common, apiSourceId, apiUrl, actorId) {
|
||||
|
||||
await connection.beginTransaction();
|
||||
await connection.query(
|
||||
'UPDATE api_sources SET last_pulled_at = ?, last_pull_error = ?, last_response_status = ?, last_response_content_type = ?, last_response_json = ?, modified_by = ? WHERE id = ?',
|
||||
'UPDATE i_api_sources SET last_pulled_at = ?, last_pull_error = ?, last_response_status = ?, last_response_content_type = ?, last_response_json = ?, modified_by = ? WHERE id = ?',
|
||||
[new Date(), pullError || null, responseDetails ? responseDetails.responseStatus : null, responseDetails ? responseDetails.responseContentType : null, responseDetails ? responseDetails.responseJson : null, actorId, apiSourceId]
|
||||
);
|
||||
await connection.commit();
|
||||
|
||||
+11
-11
@@ -91,10 +91,10 @@ function getCanvasSignature(width, height) {
|
||||
async function fetchPlaylistCanvasSignature(pool, playlistId) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT DISTINCT cs.width AS canvas_width, cs.height AS canvas_height
|
||||
FROM playlist_slides ps
|
||||
JOIN slides sl ON sl.id = ps.slide_id
|
||||
LEFT JOIN slide_templates st ON st.id = sl.template_id
|
||||
LEFT JOIN canvas_sizes cs ON cs.id = st.canvas_size_id
|
||||
FROM c_playlist_slides ps
|
||||
JOIN c_slides sl ON sl.id = ps.slide_id
|
||||
LEFT JOIN c_templates st ON st.id = sl.template_id
|
||||
LEFT JOIN c_canvas_sizes cs ON cs.id = st.canvas_size_id
|
||||
WHERE ps.playlist_id = ?
|
||||
AND cs.width IS NOT NULL
|
||||
AND cs.height IS NOT NULL`,
|
||||
@@ -111,7 +111,7 @@ async function fetchPlaylistCanvasSignature(pool, playlistId) {
|
||||
|
||||
async function fetchScreensByPlaylistId(connection, playlistId) {
|
||||
const [rows] = await connection.query(
|
||||
'SELECT slug FROM screens WHERE playlist_id = ? AND slug IS NOT NULL',
|
||||
'SELECT slug FROM d_screens WHERE playlist_id = ? AND slug IS NOT NULL',
|
||||
[playlistId]
|
||||
);
|
||||
return rows.map(function (row) {
|
||||
@@ -122,8 +122,8 @@ async function fetchScreensByPlaylistId(connection, playlistId) {
|
||||
async function fetchScreensBySlideId(connection, slideId) {
|
||||
const [rows] = await connection.query(
|
||||
`SELECT DISTINCT s.slug
|
||||
FROM screens s
|
||||
JOIN playlist_slides ps ON ps.playlist_id = s.playlist_id
|
||||
FROM d_screens s
|
||||
JOIN c_playlist_slides ps ON ps.playlist_id = s.playlist_id
|
||||
WHERE ps.slide_id = ?
|
||||
AND s.slug IS NOT NULL`,
|
||||
[slideId]
|
||||
@@ -136,9 +136,9 @@ async function fetchScreensBySlideId(connection, slideId) {
|
||||
async function fetchScreensByTemplateId(connection, templateId) {
|
||||
const [rows] = await connection.query(
|
||||
`SELECT DISTINCT s.slug
|
||||
FROM screens s
|
||||
JOIN playlist_slides ps ON ps.playlist_id = s.playlist_id
|
||||
JOIN slides sl ON sl.id = ps.slide_id
|
||||
FROM d_screens s
|
||||
JOIN c_playlist_slides ps ON ps.playlist_id = s.playlist_id
|
||||
JOIN c_slides sl ON sl.id = ps.slide_id
|
||||
WHERE sl.template_id = ?
|
||||
AND s.slug IS NOT NULL`,
|
||||
[templateId]
|
||||
@@ -150,7 +150,7 @@ async function fetchScreensByTemplateId(connection, templateId) {
|
||||
|
||||
async function fetchOrderedPlaylistSlides(connection, playlistId) {
|
||||
const [rows] = await connection.query(
|
||||
'SELECT id, position FROM playlist_slides WHERE playlist_id = ? ORDER BY position ASC, id ASC',
|
||||
'SELECT id, position FROM c_playlist_slides WHERE playlist_id = ? ORDER BY position ASC, id ASC',
|
||||
[playlistId]
|
||||
);
|
||||
return rows;
|
||||
|
||||
@@ -68,7 +68,7 @@ function createPlayerActionService(options) {
|
||||
}
|
||||
|
||||
async function getScreenDeleteBlockMessage(pool, screen, getScreenConnections) {
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM player_onboarding_devices WHERE screen_id = ?', [screen.id]);
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM d_onboarding_devices WHERE screen_id = ?', [screen.id]);
|
||||
if (Number(rows[0] && rows[0].ref_count) > 0) {
|
||||
return 'This screen is still linked to onboarding devices.';
|
||||
}
|
||||
@@ -89,22 +89,22 @@ function createPlayerActionService(options) {
|
||||
}
|
||||
|
||||
async function getSlideDeleteBlockMessage(pool, slide) {
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM playlist_slides WHERE slide_id = ?', [slide.id]);
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM c_playlist_slides WHERE slide_id = ?', [slide.id]);
|
||||
return Number(rows[0] && rows[0].ref_count) > 0 ? 'This slide is still used by one or more playlists.' : '';
|
||||
}
|
||||
|
||||
async function getTemplateDeleteBlockMessage(pool, template) {
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM slides WHERE template_id = ?', [template.id]);
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM c_slides WHERE template_id = ?', [template.id]);
|
||||
return Number(rows[0] && rows[0].ref_count) > 0 ? 'This template is still used by one or more slides.' : '';
|
||||
}
|
||||
|
||||
async function getCanvasSizeDeleteBlockMessage(pool, canvasSize) {
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM slide_templates WHERE canvas_size_id = ?', [canvasSize.id]);
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM c_templates WHERE canvas_size_id = ?', [canvasSize.id]);
|
||||
return Number(rows[0] && rows[0].ref_count) > 0 ? 'This canvas size is still used by one or more templates.' : '';
|
||||
}
|
||||
|
||||
async function getPlaylistDeleteBlockMessage(pool, playlist) {
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM screens WHERE playlist_id = ?', [playlist.id]);
|
||||
const [rows] = await pool.query('SELECT COUNT(*) AS ref_count FROM d_screens WHERE playlist_id = ?', [playlist.id]);
|
||||
return Number(rows[0] && rows[0].ref_count) > 0 ? 'This playlist is still assigned to one or more screens.' : '';
|
||||
}
|
||||
|
||||
|
||||
+34
-34
@@ -13,16 +13,16 @@ function parseCsvIds(value) {
|
||||
}
|
||||
|
||||
async function fetchPermissions(pool) {
|
||||
const [rows] = await pool.query('SELECT id, permission_key, name, section_name, description FROM permissions ORDER BY section_name ASC, name ASC');
|
||||
const [rows] = await pool.query('SELECT id, permission_key, name, section_name, description FROM a_permissions ORDER BY section_name ASC, name ASC');
|
||||
return rows || [];
|
||||
}
|
||||
|
||||
async function fetchRoles(pool) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT r.id, r.role_key, r.name, r.description, r.created_at, r.modified_at,
|
||||
(SELECT COUNT(*) FROM user_roles ur WHERE ur.role_id = r.id) AS user_count,
|
||||
(SELECT COUNT(*) FROM role_permissions rp WHERE rp.role_id = r.id) AS permission_count
|
||||
FROM roles r
|
||||
(SELECT COUNT(*) FROM a_user_roles ur WHERE ur.role_id = r.id) AS user_count,
|
||||
(SELECT COUNT(*) FROM a_role_permissions rp WHERE rp.role_id = r.id) AS permission_count
|
||||
FROM a_roles r
|
||||
ORDER BY r.name ASC`
|
||||
);
|
||||
return rows || [];
|
||||
@@ -31,11 +31,11 @@ async function fetchRoles(pool) {
|
||||
async function fetchRolesPage(pool, page, pageSize, searchTerm, sortKey, sortDirection) {
|
||||
const paged = await fetchPagedRows(pool, {
|
||||
selectSql: `SELECT r.id, r.role_key, r.name, r.description, r.created_at, r.modified_at,
|
||||
(SELECT COUNT(*) FROM user_roles ur WHERE ur.role_id = r.id) AS user_count,
|
||||
(SELECT COUNT(*) FROM role_permissions rp WHERE rp.role_id = r.id) AS permission_count
|
||||
FROM roles r
|
||||
(SELECT COUNT(*) FROM a_user_roles ur WHERE ur.role_id = r.id) AS user_count,
|
||||
(SELECT COUNT(*) FROM a_role_permissions rp WHERE rp.role_id = r.id) AS permission_count
|
||||
FROM a_roles r
|
||||
ORDER BY r.name ASC`,
|
||||
countSql: 'SELECT COUNT(*) AS count FROM roles',
|
||||
countSql: 'SELECT COUNT(*) AS count FROM a_roles',
|
||||
searchColumns: ['r.role_key', 'r.name', 'r.description'],
|
||||
searchTerm: searchTerm,
|
||||
sortColumns: {
|
||||
@@ -58,9 +58,9 @@ async function fetchRolesPage(pool, page, pageSize, searchTerm, sortKey, sortDir
|
||||
async function fetchRoleById(pool, roleId) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT r.id, r.role_key, r.name, r.description, r.created_at, r.modified_at,
|
||||
(SELECT COUNT(*) FROM user_roles ur WHERE ur.role_id = r.id) AS user_count,
|
||||
(SELECT COUNT(*) FROM role_permissions rp WHERE rp.role_id = r.id) AS permission_count
|
||||
FROM roles r
|
||||
(SELECT COUNT(*) FROM a_user_roles ur WHERE ur.role_id = r.id) AS user_count,
|
||||
(SELECT COUNT(*) FROM a_role_permissions rp WHERE rp.role_id = r.id) AS permission_count
|
||||
FROM a_roles r
|
||||
WHERE r.id = ?
|
||||
LIMIT 1`,
|
||||
[roleId]
|
||||
@@ -71,8 +71,8 @@ async function fetchRoleById(pool, roleId) {
|
||||
async function fetchRolePermissionKeys(pool, roleId) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT p.permission_key
|
||||
FROM role_permissions rp
|
||||
JOIN permissions p ON p.id = rp.permission_id
|
||||
FROM a_role_permissions rp
|
||||
JOIN a_permissions p ON p.id = rp.permission_id
|
||||
WHERE rp.role_id = ?
|
||||
ORDER BY p.section_name ASC, p.name ASC`,
|
||||
[roleId]
|
||||
@@ -85,7 +85,7 @@ async function fetchRolePermissionKeys(pool, roleId) {
|
||||
async function fetchRoleUserIds(pool, roleId) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT ur.user_id
|
||||
FROM user_roles ur
|
||||
FROM a_user_roles ur
|
||||
WHERE ur.role_id = ?
|
||||
ORDER BY ur.user_id ASC`,
|
||||
[roleId]
|
||||
@@ -100,8 +100,8 @@ async function fetchRoleUserIds(pool, roleId) {
|
||||
async function fetchRolesForUser(pool, userId) {
|
||||
const [rows] = await pool.query(
|
||||
`SELECT r.id, r.role_key, r.name, r.description
|
||||
FROM user_roles ur
|
||||
JOIN roles r ON r.id = ur.role_id
|
||||
FROM a_user_roles ur
|
||||
JOIN a_roles r ON r.id = ur.role_id
|
||||
WHERE ur.user_id = ?
|
||||
ORDER BY r.name ASC`,
|
||||
[userId]
|
||||
@@ -114,13 +114,13 @@ async function fetchUsersWithRoles(pool) {
|
||||
`SELECT u.id, u.name, u.username, u.created_at, u.modified_at,
|
||||
COALESCE(role_data.role_names, '') AS role_names,
|
||||
COALESCE(role_data.role_ids_csv, '') AS role_ids_csv
|
||||
FROM users u
|
||||
FROM a_users u
|
||||
LEFT JOIN (
|
||||
SELECT ur.user_id,
|
||||
GROUP_CONCAT(DISTINCT r.name ORDER BY r.name SEPARATOR ', ') AS role_names,
|
||||
GROUP_CONCAT(DISTINCT r.id ORDER BY r.name SEPARATOR ',') AS role_ids_csv
|
||||
FROM user_roles ur
|
||||
JOIN roles r ON r.id = ur.role_id
|
||||
FROM a_user_roles ur
|
||||
JOIN a_roles r ON r.id = ur.role_id
|
||||
GROUP BY ur.user_id
|
||||
) role_data ON role_data.user_id = u.id
|
||||
ORDER BY u.id ASC`
|
||||
@@ -143,18 +143,18 @@ async function fetchUsersWithRolesPage(pool, page, pageSize, searchTerm, sortKey
|
||||
selectSql: `SELECT u.id, u.name, u.username, u.created_at, u.modified_at,
|
||||
COALESCE(role_data.role_names, '') AS role_names,
|
||||
COALESCE(role_data.role_ids_csv, '') AS role_ids_csv
|
||||
FROM users u
|
||||
FROM a_users u
|
||||
LEFT JOIN (
|
||||
SELECT ur.user_id,
|
||||
GROUP_CONCAT(DISTINCT r.name ORDER BY r.name SEPARATOR ', ') AS role_names,
|
||||
GROUP_CONCAT(DISTINCT r.id ORDER BY r.name SEPARATOR ',') AS role_ids_csv
|
||||
FROM user_roles ur
|
||||
JOIN roles r ON r.id = ur.role_id
|
||||
FROM a_user_roles ur
|
||||
JOIN a_roles r ON r.id = ur.role_id
|
||||
GROUP BY ur.user_id
|
||||
) role_data ON role_data.user_id = u.id
|
||||
${whereSql}
|
||||
ORDER BY u.id ASC`,
|
||||
countSql: `SELECT COUNT(*) AS count FROM users u ${whereSql}`,
|
||||
countSql: `SELECT COUNT(*) AS count FROM a_users u ${whereSql}`,
|
||||
params: queryArgs,
|
||||
searchColumns: ['u.name', 'u.username', 'role_data.role_names'],
|
||||
searchTerm: searchTerm,
|
||||
@@ -190,13 +190,13 @@ async function fetchUserWithRoles(pool, userId) {
|
||||
`SELECT u.id, u.name, u.username, u.created_at, u.modified_at,
|
||||
COALESCE(role_data.role_names, '') AS role_names,
|
||||
COALESCE(role_data.role_ids_csv, '') AS role_ids_csv
|
||||
FROM users u
|
||||
FROM a_users u
|
||||
LEFT JOIN (
|
||||
SELECT ur.user_id,
|
||||
GROUP_CONCAT(DISTINCT r.name ORDER BY r.name SEPARATOR ', ') AS role_names,
|
||||
GROUP_CONCAT(DISTINCT r.id ORDER BY r.name SEPARATOR ',') AS role_ids_csv
|
||||
FROM user_roles ur
|
||||
JOIN roles r ON r.id = ur.role_id
|
||||
FROM a_user_roles ur
|
||||
JOIN a_roles r ON r.id = ur.role_id
|
||||
GROUP BY ur.user_id
|
||||
) role_data ON role_data.user_id = u.id
|
||||
WHERE u.id = ?
|
||||
@@ -221,9 +221,9 @@ async function syncUserRoles(pool, userId, roleIds) {
|
||||
return Number.isInteger(roleId) && roleId > 0;
|
||||
})));
|
||||
|
||||
await pool.query('DELETE FROM user_roles WHERE user_id = ?', [userId]);
|
||||
await pool.query('DELETE FROM a_user_roles WHERE user_id = ?', [userId]);
|
||||
for (const roleId of uniqueRoleIds) {
|
||||
await pool.query('INSERT IGNORE INTO user_roles (user_id, role_id, created_by, modified_by) VALUES (?, ?, ?, ?)', [userId, roleId, null, null]);
|
||||
await pool.query('INSERT IGNORE INTO a_user_roles (user_id, role_id, created_by, modified_by) VALUES (?, ?, ?, ?)', [userId, roleId, null, null]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,9 +234,9 @@ async function syncRoleUsers(pool, roleId, userIds) {
|
||||
return Number.isInteger(userId) && userId > 0;
|
||||
})));
|
||||
|
||||
await pool.query('DELETE FROM user_roles WHERE role_id = ?', [roleId]);
|
||||
await pool.query('DELETE FROM a_user_roles WHERE role_id = ?', [roleId]);
|
||||
for (const userId of uniqueUserIds) {
|
||||
await pool.query('INSERT IGNORE INTO user_roles (user_id, role_id, created_by, modified_by) VALUES (?, ?, ?, ?)', [userId, roleId, null, null]);
|
||||
await pool.query('INSERT IGNORE INTO a_user_roles (user_id, role_id, created_by, modified_by) VALUES (?, ?, ?, ?)', [userId, roleId, null, null]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,18 +244,18 @@ async function syncRolePermissions(pool, roleId, permissionKeys) {
|
||||
const uniquePermissionKeys = normalizePermissionKeys(permissionKeys);
|
||||
|
||||
if (!uniquePermissionKeys.length) {
|
||||
await pool.query('DELETE FROM role_permissions WHERE role_id = ?', [roleId]);
|
||||
await pool.query('DELETE FROM a_role_permissions WHERE role_id = ?', [roleId]);
|
||||
return;
|
||||
}
|
||||
|
||||
const [permissionRows] = await pool.query('SELECT id, permission_key FROM permissions WHERE permission_key IN (?)', [uniquePermissionKeys]);
|
||||
const [permissionRows] = await pool.query('SELECT id, permission_key FROM a_permissions WHERE permission_key IN (?)', [uniquePermissionKeys]);
|
||||
if (permissionRows.length !== uniquePermissionKeys.length) {
|
||||
throw new Error('One or more selected permissions are invalid.');
|
||||
}
|
||||
|
||||
await pool.query('DELETE FROM role_permissions WHERE role_id = ?', [roleId]);
|
||||
await pool.query('DELETE FROM a_role_permissions WHERE role_id = ?', [roleId]);
|
||||
for (const permissionRow of permissionRows) {
|
||||
await pool.query('INSERT IGNORE INTO role_permissions (role_id, permission_id, created_by, modified_by) VALUES (?, ?, ?, ?)', [roleId, Number(permissionRow.id), null, null]);
|
||||
await pool.query('INSERT IGNORE INTO a_role_permissions (role_id, permission_id, created_by, modified_by) VALUES (?, ?, ?, ?)', [roleId, Number(permissionRow.id), null, null]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,8 +57,8 @@ function createSessionService(options) {
|
||||
const tokenHash = hashSessionToken(token);
|
||||
const [rows] = await pool.query(
|
||||
`SELECT s.user_id, u.id, u.name, u.username
|
||||
FROM auth_sessions s
|
||||
JOIN users u ON u.id = s.user_id
|
||||
FROM a_sessions s
|
||||
JOIN a_users u ON u.id = s.user_id
|
||||
WHERE s.session_hash = ?
|
||||
AND s.expires_at > NOW()
|
||||
LIMIT 1`,
|
||||
@@ -71,23 +71,23 @@ function createSessionService(options) {
|
||||
const userId = Number(rows[0].id);
|
||||
const [roleRows] = await pool.query(
|
||||
`SELECT r.role_key
|
||||
FROM user_roles ur
|
||||
JOIN roles r ON r.id = ur.role_id
|
||||
FROM a_user_roles ur
|
||||
JOIN a_roles r ON r.id = ur.role_id
|
||||
WHERE ur.user_id = ?
|
||||
ORDER BY r.name ASC`,
|
||||
[userId]
|
||||
);
|
||||
const [permissionRows] = await pool.query(
|
||||
`SELECT p.permission_key
|
||||
FROM user_roles ur
|
||||
JOIN role_permissions rp ON rp.role_id = ur.role_id
|
||||
JOIN permissions p ON p.id = rp.permission_id
|
||||
FROM a_user_roles ur
|
||||
JOIN a_role_permissions rp ON rp.role_id = ur.role_id
|
||||
JOIN a_permissions p ON p.id = rp.permission_id
|
||||
WHERE ur.user_id = ?
|
||||
ORDER BY p.section_name ASC, p.name ASC`,
|
||||
[userId]
|
||||
);
|
||||
|
||||
await pool.query('UPDATE auth_sessions SET last_used_at = CURRENT_TIMESTAMP, modified_by = ? WHERE session_hash = ?', [rows[0].user_id, tokenHash]);
|
||||
await pool.query('UPDATE a_sessions SET last_used_at = CURRENT_TIMESTAMP, modified_by = ? WHERE session_hash = ?', [rows[0].user_id, tokenHash]);
|
||||
return Object.assign({}, rows[0], {
|
||||
roleKeys: roleRows.map(function (row) {
|
||||
return String(row.role_key || '').trim();
|
||||
@@ -103,7 +103,7 @@ function createSessionService(options) {
|
||||
const tokenHash = hashSessionToken(token);
|
||||
const expiresAt = new Date(Date.now() + sessionMaxAgeMs);
|
||||
await pool.query(
|
||||
'INSERT INTO auth_sessions (session_hash, user_id, expires_at, created_by, modified_by) VALUES (?, ?, ?, ?, ?)',
|
||||
'INSERT INTO a_sessions (session_hash, user_id, expires_at, created_by, modified_by) VALUES (?, ?, ?, ?, ?)',
|
||||
[tokenHash, userId, expiresAt, userId, userId]
|
||||
);
|
||||
return token;
|
||||
|
||||
@@ -276,13 +276,13 @@ async function captureSlideThumbnail(options) {
|
||||
}
|
||||
});
|
||||
|
||||
await pool.query('UPDATE slides SET thumbnail_path = ? WHERE id = ?', [thumbnailPath, slide.id]);
|
||||
await pool.query('UPDATE c_slides SET thumbnail_path = ? WHERE id = ?', [thumbnailPath, slide.id]);
|
||||
return {
|
||||
slideId: slide.id,
|
||||
thumbnailPath: thumbnailPath,
|
||||
filePath: filePath,
|
||||
fullSizePath: fullSizePath,
|
||||
mediaKind: mediaKind(slide.media_path || '')
|
||||
mediaKind: mediaKind('')
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+17
-12
@@ -76,11 +76,15 @@ function createUploadSyncService(options) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const mediaRoot = path.basename(normalizedUploadDir) === 'uploads'
|
||||
? path.dirname(normalizedUploadDir)
|
||||
: normalizedUploadDir;
|
||||
|
||||
if (relativePath.startsWith('uploads/')) {
|
||||
return path.join(normalizedUploadDir, relativePath.slice('uploads/'.length));
|
||||
return path.join(mediaRoot, relativePath);
|
||||
}
|
||||
|
||||
return path.join(path.dirname(normalizedUploadDir), relativePath);
|
||||
return path.join(mediaRoot, relativePath);
|
||||
}
|
||||
|
||||
function collectUploadReferencesFromValue(value, refs) {
|
||||
@@ -117,7 +121,6 @@ function createUploadSyncService(options) {
|
||||
if (!slide) {
|
||||
return refs;
|
||||
}
|
||||
collectUploadReferencesFromValue(slide.media_path, refs);
|
||||
collectUploadReferencesFromValue(common.parseJsonSafe(slide.content_json), refs);
|
||||
return refs;
|
||||
}
|
||||
@@ -136,7 +139,6 @@ function createUploadSyncService(options) {
|
||||
if (!payload) {
|
||||
return refs;
|
||||
}
|
||||
collectUploadReferencesFromValue(payload.mediaPath, refs);
|
||||
collectUploadReferencesFromValue(common.parseJsonSafe(payload.contentJson), refs);
|
||||
collectUploadReferencesFromValue(payload.backgroundImagePath, refs);
|
||||
return refs;
|
||||
@@ -145,16 +147,19 @@ function createUploadSyncService(options) {
|
||||
async function countUploadReferences(pool, uploadPath) {
|
||||
const [slideRows] = await pool.query(
|
||||
`SELECT COUNT(*) AS ref_count
|
||||
FROM slides
|
||||
WHERE media_path = ?
|
||||
OR JSON_SEARCH(COALESCE(content_json, JSON_OBJECT()), 'one', ?) IS NOT NULL`,
|
||||
[uploadPath, uploadPath]
|
||||
);
|
||||
const [templateRows] = await pool.query(
|
||||
'SELECT COUNT(*) AS ref_count FROM slide_templates WHERE background_image_path = ?',
|
||||
FROM c_slides
|
||||
WHERE JSON_SEARCH(COALESCE(content_json, JSON_OBJECT()), 'one', ?) IS NOT NULL`,
|
||||
[uploadPath]
|
||||
);
|
||||
return Number(slideRows[0].ref_count || 0) + Number(templateRows[0].ref_count || 0);
|
||||
const [thumbnailRows] = await pool.query(
|
||||
'SELECT COUNT(*) AS ref_count FROM c_slides WHERE thumbnail_path = ?',
|
||||
[uploadPath]
|
||||
);
|
||||
const [templateRows] = await pool.query(
|
||||
'SELECT COUNT(*) AS ref_count FROM c_templates WHERE background_image_path = ?',
|
||||
[uploadPath]
|
||||
);
|
||||
return Number(slideRows[0].ref_count || 0) + Number(thumbnailRows[0].ref_count || 0) + Number(templateRows[0].ref_count || 0);
|
||||
}
|
||||
|
||||
async function removeUnusedUploadFiles(pool, uploadDir, uploadPaths) {
|
||||
|
||||
Reference in New Issue
Block a user