2026-04-06 12:56:35 +02:00

65 lines
1.8 KiB
TypeScript

import { Router } from 'express';
import type { Request, Response } from 'express';
import { getDb } from '../../db/index';
import { buildDisplayJson } from '../../modules/display/display-builder';
const router = Router();
/**
* GET /api/display/:id
* ESP32 endpoint — returns display JSON.
* Optional token auth via ?token=... or Authorization: Bearer ...
* If the display has an api_token set, the token MUST match.
*/
router.get('/:id', (req: Request, res: Response): void => {
try {
const db = getDb();
const displayId = parseInt(req.params.id);
const display = db
.prepare('SELECT id, api_token FROM displays WHERE id = ?')
.get(displayId) as { id: number; api_token: string | null } | undefined;
if (!display) {
res.status(404).json({ error: 'Display not found' });
return;
}
// Check token if display has one configured
if (display.api_token) {
const authHeader = req.headers.authorization;
const queryToken = req.query.token as string | undefined;
let provided: string | null = null;
if (authHeader && authHeader.startsWith('Bearer ')) {
provided = authHeader.slice(7);
} else if (queryToken) {
provided = queryToken;
}
if (!provided || provided !== display.api_token) {
res.status(401).json({ error: 'Invalid or missing token' });
return;
}
}
// Update last_seen
db.run(
`UPDATE displays SET last_seen = datetime('now') WHERE id = ?`,
[displayId]
);
const json = buildDisplayJson(displayId);
if (!json) {
res.status(404).json({ error: 'Display configuration not found' });
return;
}
res.json(json);
} catch (err) {
res.status(500).json({ error: (err as Error).message });
}
});
export default router;