feat(mindspace): gate published page delivery
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import crypto from 'node:crypto';
|
||||
|
||||
export function normalizeDeliveryRelativePath(value) {
|
||||
const path = String(value ?? '').replace(/\\/g, '/').replace(/^\/+/, '');
|
||||
if (!path.startsWith('public/') || !path.toLowerCase().endsWith('.html')) return null;
|
||||
if (path.split('/').some((part) => !part || part === '.' || part === '..')) return null;
|
||||
return path;
|
||||
}
|
||||
|
||||
export async function preparePageDeliveryContract({ pool, userId, requestId, relativePath, pgRequired = false }) {
|
||||
const workspaceRelativePath = normalizeDeliveryRelativePath(relativePath);
|
||||
if (!pool || !userId || !requestId || !workspaceRelativePath) return null;
|
||||
const now = Date.now();
|
||||
const id = crypto.randomUUID();
|
||||
await pool.query(
|
||||
`INSERT INTO h5_page_delivery_contracts
|
||||
(id, user_id, request_id, workspace_relative_path, data_mode, status, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?, ?, 'preparing', ?, ?)
|
||||
ON DUPLICATE KEY UPDATE data_mode = VALUES(data_mode), status = 'preparing', failure_reason = NULL, updated_at = VALUES(updated_at)`,
|
||||
[id, userId, requestId, workspaceRelativePath, pgRequired ? 'pg_required' : 'static', now, now],
|
||||
);
|
||||
return { id, userId, requestId, workspaceRelativePath, dataMode: pgRequired ? 'pg_required' : 'static', status: 'preparing' };
|
||||
}
|
||||
|
||||
export async function getPageDeliveryContract({ pool, userId, relativePath }) {
|
||||
const workspaceRelativePath = normalizeDeliveryRelativePath(relativePath);
|
||||
if (!pool || !userId || !workspaceRelativePath) return null;
|
||||
const [rows] = await pool.query(
|
||||
`SELECT id, data_mode, status, failure_reason FROM h5_page_delivery_contracts
|
||||
WHERE user_id = ? AND workspace_relative_path = ?
|
||||
ORDER BY updated_at DESC LIMIT 1`,
|
||||
[userId, workspaceRelativePath],
|
||||
);
|
||||
return rows?.[0] ?? null;
|
||||
}
|
||||
|
||||
export async function markPageDeliveryContractReady({ pool, userId, relativePath }) {
|
||||
const workspaceRelativePath = normalizeDeliveryRelativePath(relativePath);
|
||||
if (!pool || !userId || !workspaceRelativePath) return false;
|
||||
const now = Date.now();
|
||||
const [result] = await pool.query(
|
||||
`UPDATE h5_page_delivery_contracts
|
||||
SET status = 'ready', ready_at = ?, failure_reason = NULL, updated_at = ?
|
||||
WHERE user_id = ? AND workspace_relative_path = ? AND status = 'preparing'`,
|
||||
[now, now, userId, workspaceRelativePath],
|
||||
);
|
||||
return Number(result?.affectedRows ?? 0) > 0;
|
||||
}
|
||||
Reference in New Issue
Block a user