155 lines
6.1 KiB
JavaScript
155 lines
6.1 KiB
JavaScript
module.exports = function registerAdminScreenCommandRoutes(app, deps) {
|
|
const pool = deps.pool;
|
|
const forwardPlayerCommand = deps.forwardPlayerCommand;
|
|
const getScreenConnections = deps.getScreenConnections;
|
|
const isClientNameAvailable = deps.isClientNameAvailable;
|
|
const withClientNameReservation = deps.withClientNameReservation;
|
|
const requirePermission = deps.requirePermission;
|
|
|
|
app.post('/admin/screens/:slug/commands', requirePermission('clients.allow'), async function (req, res, next) {
|
|
try {
|
|
const slug = String(req.params.slug || '').trim();
|
|
const command = String((req.body && req.body.command) || req.query.command || '').trim().toLowerCase();
|
|
const connectionId = String((req.body && (req.body.connectionId || req.body.clientId)) || req.query.connectionId || req.query.clientId || '').trim();
|
|
const blackoutValue = req.body && Object.prototype.hasOwnProperty.call(req.body, 'blackout')
|
|
? req.body.blackout
|
|
: req.query.blackout;
|
|
|
|
if (!slug) {
|
|
return res.status(400).json({ error: 'Screen slug is required' });
|
|
}
|
|
if (!command) {
|
|
return res.status(400).json({ error: 'Command is required' });
|
|
}
|
|
|
|
const [screenRows] = await pool.query('SELECT id, name, slug FROM screens WHERE slug = ?', [slug]);
|
|
if (!screenRows.length) {
|
|
return res.status(404).json({ error: 'Screen not found' });
|
|
}
|
|
|
|
if (command === 'setclientname') {
|
|
const deviceId = String((req.body && (req.body.deviceId || req.body.clientId)) || req.query.deviceId || req.query.clientId || '').trim();
|
|
const clientName = String((req.body && req.body.clientName) || req.query.clientName || '').trim();
|
|
if (!deviceId) {
|
|
return res.status(400).json({ error: 'Device ID is required' });
|
|
}
|
|
if (!clientName) {
|
|
return res.status(400).json({ error: 'Client name is required' });
|
|
}
|
|
|
|
const [currentRows] = await pool.query(
|
|
`SELECT client_name
|
|
FROM player_onboarding_devices
|
|
WHERE device_id = ?
|
|
LIMIT 1`,
|
|
[deviceId]
|
|
);
|
|
const onboardingRow = currentRows[0] || null;
|
|
const currentName = String(onboardingRow && onboardingRow.client_name ? onboardingRow.client_name : '').trim();
|
|
if (currentName && currentName.toLowerCase() === clientName.toLowerCase()) {
|
|
return res.json({
|
|
screen: screenRows[0],
|
|
screenSlug: slug,
|
|
command: command,
|
|
connectionId: connectionId || null,
|
|
deviceId: deviceId,
|
|
clientName: currentName,
|
|
ok: true,
|
|
unchanged: true
|
|
});
|
|
}
|
|
if (typeof withClientNameReservation !== 'function') {
|
|
return res.status(500).json({ error: 'Client name reservation is unavailable.' });
|
|
}
|
|
|
|
return withClientNameReservation(pool, clientName, async function () {
|
|
let liveConnections = [];
|
|
try {
|
|
const [screenSlugs] = await pool.query('SELECT slug FROM screens ORDER BY slug ASC');
|
|
const liveResults = await Promise.all((screenSlugs || []).map(async function (row) {
|
|
const screenSlug = String(row && row.slug ? row.slug : '').trim();
|
|
if (!screenSlug || typeof getScreenConnections !== 'function') {
|
|
return [];
|
|
}
|
|
try {
|
|
const liveResponse = await getScreenConnections(screenSlug);
|
|
return Array.isArray(liveResponse && liveResponse.connections) ? liveResponse.connections : [];
|
|
} catch (_error) {
|
|
return [];
|
|
}
|
|
}));
|
|
liveConnections = liveResults.flat();
|
|
} catch (_error) {
|
|
liveConnections = [];
|
|
}
|
|
|
|
const available = await isClientNameAvailable(pool, clientName, deviceId, liveConnections);
|
|
if (!available) {
|
|
return res.status(409).json({ error: 'Client name already exists.' });
|
|
}
|
|
|
|
if (!onboardingRow) {
|
|
await forwardPlayerCommand(slug, {
|
|
command: command,
|
|
clientName: clientName,
|
|
clientId: connectionId || deviceId || null,
|
|
deviceId: deviceId || null
|
|
}, connectionId || deviceId || undefined);
|
|
|
|
return res.json({
|
|
screen: screenRows[0],
|
|
screenSlug: slug,
|
|
command: command,
|
|
connectionId: connectionId || null,
|
|
deviceId: deviceId,
|
|
clientName: clientName,
|
|
ok: true,
|
|
liveOnly: true
|
|
});
|
|
}
|
|
|
|
const [updateResult] = await pool.query(
|
|
`UPDATE player_onboarding_devices pod
|
|
JOIN screens s ON s.id = pod.screen_id
|
|
SET pod.client_name = ?, pod.modified_at = CURRENT_TIMESTAMP
|
|
WHERE s.slug = ? AND pod.device_id = ?`,
|
|
[clientName, slug, deviceId]
|
|
);
|
|
if (!updateResult.affectedRows) {
|
|
return res.status(404).json({ error: 'Client not found' });
|
|
}
|
|
|
|
return res.json({
|
|
screen: screenRows[0],
|
|
screenSlug: slug,
|
|
command: command,
|
|
connectionId: connectionId || null,
|
|
deviceId: deviceId,
|
|
clientName: clientName,
|
|
ok: true
|
|
});
|
|
});
|
|
}
|
|
|
|
const commandPayload = req.body && typeof req.body === 'object' && !Array.isArray(req.body)
|
|
? Object.assign({}, req.body, { command: command })
|
|
: { command: command };
|
|
if (command === 'blackout' && blackoutValue !== undefined && commandPayload && typeof commandPayload === 'object') {
|
|
commandPayload.blackout = blackoutValue;
|
|
}
|
|
|
|
const result = connectionId
|
|
? await forwardPlayerCommand(slug, commandPayload, connectionId)
|
|
: await forwardPlayerCommand(slug, commandPayload);
|
|
|
|
return res.json(Object.assign({
|
|
screen: screenRows[0],
|
|
screenSlug: slug,
|
|
command: command,
|
|
connectionId: connectionId || null
|
|
}, result && typeof result === 'object' ? result : {}));
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
});
|
|
}; |