fix: unique keyHash in download URL path + 2s reload delay for save callback

This commit is contained in:
root
2026-07-16 12:12:31 +00:00
parent 63291169ba
commit fce938b0c2
5 changed files with 38 additions and 10 deletions

View File

@@ -6,6 +6,6 @@
"originalName": "master_cv_template.docx",
"path": "/root/workspace/cv-app/renderer/carbone-templates/433a0593-d3cf-414e-8763-ab5f87cbc75c.docx",
"uploadedAt": "2026-07-16T09:03:29.601Z",
"updatedAt": "2026-07-16T12:06:39.375Z"
"updatedAt": "2026-07-16T12:09:36.709Z"
}
]

View File

@@ -147,11 +147,11 @@ router.get('/:templateId/config', (req, res) => {
const docKey = generateDocKey(templateId, Date.now());
const fileName = template.originalName || template.name + '.docx';
// Add file mtime as cache-buster to the document URL so ONLYOFFICE
// always fetches the latest version from our backend.
// The mtime changes every time the file is saved, so the URL is
// different after each save, forcing ONLYOFFICE to re-download.
const documentUrl = `${BACKEND_PUBLIC_URL}/api/onlyoffice/${templateId}/download?mtime=${fileMtime}&cb=${Date.now()}`;
// Add the doc key to the download URL path so ONLYOFFICE treats
// every edit session as a completely fresh document URL.
// Query params alone aren't enough — ONLYOFFICE may ignore them for caching.
const keyHash = docKey.split('_').pop();
const documentUrl = `${BACKEND_PUBLIC_URL}/api/onlyoffice/${templateId}/download/${keyHash}?mtime=${fileMtime}&cb=${Date.now()}`;
const callbackUrl = `${BACKEND_PUBLIC_URL}/api/onlyoffice/${templateId}/callback`;
const config = {
@@ -223,9 +223,35 @@ router.get('/:templateId/config', (req, res) => {
// ============================================================
// ENDPOINT: GET /api/onlyoffice/:templateId/download
// ONLYOFFICE fetches the .docx file from this URL
// ONLYOFFICE fetches the .docx file from this URL.
// The optional :keyHash path param provides per-session cache-busting.
// ============================================================
router.get('/:templateId/download/:keyHash', (req, res) => {
const templateId = req.params.templateId;
const registry = loadRegistry();
const template = registry.find(t => t.id === templateId);
if (!template) {
return res.status(404).json({ error: 'Template not found' });
}
if (!fs.existsSync(template.path)) {
return res.status(404).json({ error: 'Template file missing' });
}
const fileName = template.originalName || template.name + '.docx';
res.setHeader('Content-Type', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document');
res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`);
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
res.setHeader('Pragma', 'no-cache');
res.setHeader('Expires', '0');
const fileStream = fs.createReadStream(template.path);
fileStream.pipe(res);
});
// Fallback route without keyHash (backward compatibility)
router.get('/:templateId/download', (req, res) => {
const templateId = req.params.templateId;
const registry = loadRegistry();