UNPKG

@fontoxml/fontoxml-development-tools

Version:

Development tools for Fonto.

110 lines (95 loc) 2.87 kB
import asyncRouteWithLockCleanupHandler from '../asyncRouteWithLockCleanupHandler.js'; /** @typedef {import('../../src/getAppConfig.js').DevCmsConfig} DevCmsConfig */ function sendJson(res, status, body) { res .status(status) .set('content-type', 'application/json; charset=utf-8') .json(body); } /** * @param {DevCmsConfig} config */ export default function configureDocumentPutRouteHandler(config) { return asyncRouteWithLockCleanupHandler(async (acquireLock, req, res) => { const documentId = req.body.documentId; if (documentId && documentId.indexOf('..') !== -1) { res.status(403).end(); return; } const context = req.body.context; const documentContext = req.body.documentContext || {}; const metadata = req.body.metadata; const currentSession = req.getFontoSession(context.editSessionToken); const fileLock = await acquireLock(documentId); const contentAndLatestRevisionId = await req.cms.getFileAndLatestRevisionId( documentId, currentSession.editSessionToken, fileLock, ); if (!contentAndLatestRevisionId) { fileLock.release(); res.status(404).end(); return; } const documentLoadLock = { ...config.documentLoadLock, ...config.documentLoadLockOverrides[documentId], }; const currentState = { lock: { isLockAcquired: documentContext.isLockAcquired !== undefined ? documentLoadLock.isLockAvailable && documentContext.isLockAcquired : documentLoadLock.isLockAcquired, isLockAvailable: documentLoadLock.isLockAvailable, reason: !documentLoadLock.isLockAvailable ? documentLoadLock.lockReason : undefined, }, revisionId: contentAndLatestRevisionId.revisionId, }; if (!currentState.lock.isLockAvailable) { // Not available has to mean not acquired, so 412 is the correct response. // Sending 403 here would cause the document to be considered inaccessible // instead of merely having an unavailable lock. fileLock.release(); sendJson(res, 412, currentState); return; } if ( req.body.revisionId && req.body.revisionId !== currentState.revisionId ) { fileLock.release(); sendJson(res, 412, currentState); return; } if (!currentState.lock.isLockAcquired) { fileLock.release(); sendJson(res, 412, currentState); return; } const newContent = req.body.content; let updatedRevisionId; try { updatedRevisionId = await req.cms.updateFile( documentId, newContent, currentSession.user, currentSession.editSessionToken, fileLock, ); } catch (_error) { fileLock.release(); sendJson(res, 400, currentState); return; } documentContext.isLockAcquired = currentState.lock.isLockAcquired; documentContext.documentMetadata = metadata; fileLock.release(); sendJson(res, 200, { revisionId: updatedRevisionId, documentContext, }); }); }