@fontoxml/fontoxml-development-tools
Version:
Development tools for Fonto.
125 lines (109 loc) • 3.09 kB
JavaScript
/** @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 (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);
req.cms.load(
documentId,
currentSession.editSessionToken,
(error, _content) => {
if (error) {
if (error.status === 404) {
res.status(404).end();
} else {
res.status(500).end();
}
return;
}
req.cms.getLatestRevisionId(
documentId,
currentSession.editSessionToken,
(error, revisionId) => {
if (error) {
res.status(500).send(error);
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,
};
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.
sendJson(res, 412, currentState);
return;
}
if (
req.body.revisionId &&
req.body.revisionId !== currentState.revisionId
) {
sendJson(res, 412, currentState);
return;
}
if (!currentState.lock.isLockAcquired) {
sendJson(res, 412, currentState);
return;
}
const newContent = req.body.content;
req.cms.save(
documentId,
newContent,
currentSession,
(error) => {
documentContext.documentMetadata = metadata;
if (error) {
sendJson(res, 400, currentState);
return;
}
// Retrieve the latest revision id to return to the client.
req.cms.getLatestRevisionId(
documentId,
currentSession.editSessionToken,
(error, revisionId) => {
if (error) {
res.status(500).send(error);
return;
}
sendJson(res, 200, {
revisionId,
documentContext,
});
}
);
}
);
}
);
}
);
};
}