Skip to content

Commit

Permalink
[bug] Fix bug with LastModifiedTime changing after putFile(nextcloud)
Browse files Browse the repository at this point in the history
  • Loading branch information
konovalovsergey committed Jun 5, 2024
1 parent 6d3d2f9 commit 9787325
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 39 deletions.
18 changes: 6 additions & 12 deletions DocService/sources/canvasservice.js
Original file line number Diff line number Diff line change
Expand Up @@ -1234,19 +1234,13 @@ function* processWopiPutFile(ctx, docId, wopiParams, savePathDoc, userLastChange
let streamObj = yield storage.createReadStream(ctx, savePathDoc);
let postRes = yield wopiClient.putFile(ctx, wopiParams, null, streamObj.readStream, metadata.ContentLength, userLastChangeId, isModifiedByUser, isAutosave, isExitSave);
if (postRes) {
if (postRes.body) {
try {
let body = JSON.parse(postRes.body);
//collabora nexcloud connector
if (body.LastModifiedTime) {
let lastModifiedTimeInfo = wopiClient.getWopiModifiedMarker(wopiParams, body.LastModifiedTime);
yield commandOpenStartPromise(ctx, docId, undefined, lastModifiedTimeInfo);
}
} catch (e) {
ctx.logger.debug('processWopiPutFile error: %s', e.stack);
}
}
res = '{"error": 0}';
let body = wopiClient.parsePutFileResponse(ctx, postRes);
//collabora nexcloud connector
if (body?.LastModifiedTime) {
let lastModifiedTimeInfo = wopiClient.getWopiModifiedMarker(wopiParams, body.LastModifiedTime);
yield commandOpenStartPromise(ctx, docId, undefined, lastModifiedTimeInfo);
}
}
return res;
}
Expand Down
85 changes: 58 additions & 27 deletions DocService/sources/wopiClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -447,14 +447,66 @@ function checkAndInvalidateCache(ctx, docId, fileInfo) {
return res;
});
}
function parsePutFileResponse(ctx, postRes) {
let body = null
if (postRes.body) {
try {
//collabora nexcloud connector
body = JSON.parse(postRes.body);
} catch (e) {
ctx.logger.debug('wopi PutFile body parse error: %s', e.stack);
}
}
return body;
}
async function checkAndReplaceEmptyFile(ctx, fileInfo, wopiSrc, access_token, access_token_ttl, lang, ui, fileType) {
// TODO: throw error if format not supported?
if (fileInfo.Size === 0 && fileType.length !== 0) {
const tenNewFileTemplate = ctx.getCfg('services.CoAuthoring.server.newFileTemplate', cfgNewFileTemplate);

//Create new files using Office for the web
const wopiParams = getWopiParams(undefined, fileInfo, wopiSrc, access_token, access_token_ttl);

if (templatesFolderLocalesCache === null) {
const dirContent = await readdir(`${tenNewFileTemplate}/`, {withFileTypes: true});
templatesFolderLocalesCache = dirContent.filter(dirObject => dirObject.isDirectory())
.map(dirObject => dirObject.name);
}

const localePrefix = lang || ui || 'en';
let locale = constants.TEMPLATES_FOLDER_LOCALE_COLLISON_MAP[localePrefix] ??
templatesFolderLocalesCache.find(locale => locale.startsWith(localePrefix));
if (locale === undefined) {
locale = constants.TEMPLATES_DEFAULT_LOCALE;
}

const filePath = `${tenNewFileTemplate}/${locale}/new.${fileType}`;
if (!templateFilesSizeCache[filePath]) {
templateFilesSizeCache[filePath] = await lstat(filePath);
}

const templateFileInfo = templateFilesSizeCache[filePath];
const templateFileStream = createReadStream(filePath);
let postRes = await putFile(ctx, wopiParams, undefined, templateFileStream, templateFileInfo.size, fileInfo.UserId, false, false, false);
if (postRes) {
//update Size
fileInfo.Size = templateFileInfo.size;
let body = parsePutFileResponse(ctx, postRes);
//collabora nexcloud connector
if (body?.LastModifiedTime) {
//update LastModifiedTime
fileInfo.LastModifiedTime = body.LastModifiedTime;
}
}
}
}
function getEditorHtml(req, res) {
return co(function*() {
let params = {key: undefined, fileInfo: {}, userAuth: {}, queryParams: req.query, token: undefined, documentType: undefined};
let ctx = new operationContext.Context();
try {
ctx.initFromRequest(req);
yield ctx.initTenantCache();
const tenNewFileTemplate = ctx.getCfg('services.CoAuthoring.server.newFileTemplate', cfgNewFileTemplate);
const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser);
const tenTokenOutboxAlgorithm = ctx.getCfg('services.CoAuthoring.token.outbox.algorithm', cfgTokenOutboxAlgorithm);
const tenTokenOutboxExpires = ctx.getCfg('services.CoAuthoring.token.outbox.expires', cfgTokenOutboxExpires);
Expand Down Expand Up @@ -483,6 +535,10 @@ function getEditorHtml(req, res) {
params.fileInfo = {};
return;
}
const fileType = getFileTypeByInfo(fileInfo);
if (!shutdownFlag) {
yield checkAndReplaceEmptyFile(ctx, fileInfo, wopiSrc, access_token, access_token_ttl, lang, ui, fileType);
}

if (!fileInfo.UserCanWrite) {
mode = 'view';
Expand Down Expand Up @@ -518,38 +574,12 @@ function getEditorHtml(req, res) {
}
if (!shutdownFlag) {
//save common info
const fileType = getFileTypeByInfo(fileInfo);
if (undefined === lockId) {
lockId = crypto.randomBytes(16).toString('base64');
let commonInfo = JSON.stringify({lockId: lockId, fileInfo: fileInfo});
yield canvasService.commandOpenStartPromise(ctx, docId, utils.getBaseUrlByRequest(ctx, req), commonInfo, fileType);
}

// TODO: throw error if format not supported?
if (fileInfo.Size === 0 && fileType.length !== 0) {
const wopiParams = getWopiParams(undefined, fileInfo, wopiSrc, access_token, access_token_ttl);

if (templatesFolderLocalesCache === null) {
const dirContent = yield readdir(`${tenNewFileTemplate}/`, { withFileTypes: true });
templatesFolderLocalesCache = dirContent.filter(dirObject => dirObject.isDirectory()).map(dirObject => dirObject.name);
}

const localePrefix = lang || ui || 'en';
let locale = constants.TEMPLATES_FOLDER_LOCALE_COLLISON_MAP[localePrefix] ?? templatesFolderLocalesCache.find(locale => locale.startsWith(localePrefix));
if (locale === undefined) {
locale = constants.TEMPLATES_DEFAULT_LOCALE;
}

const filePath = `${tenNewFileTemplate}/${locale}/new.${fileType}`;
if (!templateFilesSizeCache[filePath]) {
templateFilesSizeCache[filePath] = yield lstat(filePath);
}

const templateFileInfo = templateFilesSizeCache[filePath];
const templateFileStream = createReadStream(filePath);
yield putFile(ctx, wopiParams, undefined, templateFileStream, templateFileInfo.size, fileInfo.UserId, false, false, false);
}

//Lock
if ('view' !== mode) {
let lockRes = yield lock(ctx, 'LOCK', lockId, fileInfo, userAuth);
Expand Down Expand Up @@ -1030,6 +1060,7 @@ exports.parseWopiCallback = parseWopiCallback;
exports.getEditorHtml = getEditorHtml;
exports.getConverterHtml = getConverterHtml;
exports.putFile = putFile;
exports.parsePutFileResponse = parsePutFileResponse;
exports.putRelativeFile = putRelativeFile;
exports.renameFile = renameFile;
exports.lock = lock;
Expand Down

0 comments on commit 9787325

Please sign in to comment.