Add snapshot management to API and enhance user-agent validation for v2 routes
This commit is contained in:
71
v2Routes.js
71
v2Routes.js
@@ -3,7 +3,7 @@ const fs = require('fs');
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const router = express.Router();
|
||||
const { createSession, getSession, updateSession, deleteSession } = require('./db');
|
||||
const { createSession, getSession, updateSession, deleteSession, createSnapshot, getSnapshot, touchSnapshot } = require('./db');
|
||||
const { renderHtml } = require('./browserPool');
|
||||
|
||||
const CACHE_DIR = path.join(__dirname, 'cache');
|
||||
@@ -207,9 +207,11 @@ async function generateQuoteBuffer(config) {
|
||||
// POST /v2/quote - create new session
|
||||
router.post('/quote', (req, res) => {
|
||||
try {
|
||||
const username = req.body.username?.trim();
|
||||
|
||||
const data = {
|
||||
displayName: req.body.displayName,
|
||||
username: req.body.username?.trim(),
|
||||
displayName: req.body.displayName?.trim(),
|
||||
username: (username && username !== "@") ? username : undefined,
|
||||
text: req.body.text,
|
||||
avatarUrl: fixDataUri(req.body.avatarUrl),
|
||||
imageUrl: fixDataUri(req.body.imageUrl),
|
||||
@@ -250,8 +252,11 @@ router.patch('/quote/:id', (req, res) => {
|
||||
|
||||
const data = {};
|
||||
|
||||
if (req.body.displayName !== undefined) data.displayName = req.body.displayName;
|
||||
if (req.body.username !== undefined) data.username = req.body.username?.trim();
|
||||
if (req.body.displayName !== undefined) data.displayName = req.body.displayName?.trim();
|
||||
if (req.body.username !== undefined) {
|
||||
const username = req.body.username?.trim();
|
||||
data.username = (username && username !== "@") ? username : undefined;
|
||||
}
|
||||
if (req.body.text !== undefined) data.text = req.body.text;
|
||||
if (req.body.avatarUrl !== undefined) data.avatarUrl = fixDataUri(req.body.avatarUrl);
|
||||
if (req.body.imageUrl !== undefined) data.imageUrl = fixDataUri(req.body.imageUrl);
|
||||
@@ -334,4 +339,60 @@ router.delete('/quote/:id', (req, res) => {
|
||||
res.status(204).send();
|
||||
});
|
||||
|
||||
// POST /v2/quote/:id/snapshot-link - create snapshot link
|
||||
router.post('/quote/:id/snapshot-link', (req, res) => {
|
||||
try {
|
||||
const session = getSession(req.params.id);
|
||||
if (!session) {
|
||||
return res.status(404).json({ error: 'Session not found or expired' });
|
||||
}
|
||||
|
||||
const config = buildConfigFromSession(session);
|
||||
const snapshot = createSnapshot(session.id, config);
|
||||
|
||||
const baseUrl = `${req.protocol}://${req.get('host')}`;
|
||||
res.status(201).json({
|
||||
token: snapshot.token,
|
||||
url: `${baseUrl}/v2/snapshot/${snapshot.token}`,
|
||||
sessionId: session.id,
|
||||
createdAt: snapshot.createdAt,
|
||||
expiresAt: snapshot.accessedAt + (48 * 60 * 60)
|
||||
});
|
||||
} catch (error) {
|
||||
console.error('Failed to create snapshot:', error);
|
||||
res.status(500).json({ error: 'Failed to create snapshot' });
|
||||
}
|
||||
});
|
||||
|
||||
// GET /v2/snapshot/:token - retrieve snapshot image
|
||||
router.get('/snapshot/:token', async (req, res) => {
|
||||
try {
|
||||
const snapshot = getSnapshot(req.params.token);
|
||||
if (!snapshot) {
|
||||
return res.status(404).json({ error: 'Snapshot not found or expired' });
|
||||
}
|
||||
|
||||
touchSnapshot(req.params.token);
|
||||
|
||||
const config = JSON.parse(snapshot.configJson);
|
||||
|
||||
let image = getCachedImage(config);
|
||||
let fromCache = true;
|
||||
|
||||
if (!image) {
|
||||
image = await generateQuoteBuffer(config);
|
||||
cacheImage(config, image);
|
||||
fromCache = false;
|
||||
}
|
||||
|
||||
res.setHeader('Content-Type', 'image/png');
|
||||
res.setHeader('X-Cache', fromCache ? 'HIT' : 'MISS');
|
||||
res.setHeader('X-Snapshot-Token', snapshot.token);
|
||||
res.send(image);
|
||||
} catch (error) {
|
||||
console.error('Failed to retrieve snapshot:', error);
|
||||
res.status(500).json({ error: 'Failed to retrieve snapshot' });
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = router;
|
||||
|
||||
Reference in New Issue
Block a user