From 45a204fe45bba22d0c5cfbf777220cdf9f30d604 Mon Sep 17 00:00:00 2001 From: Alexander Trofimov Date: Thu, 29 Mar 2018 17:50:26 +0300 Subject: [PATCH 01/39] [changelog] Add changelog Create CHANGELOG.md for hotfix/v5.1.1 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..503e6a20 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,4 @@ +# Change log +## 5.1.1 +### Back-end +* From 2750d4f6938ba705615b98e1079f7eeadda886ba Mon Sep 17 00:00:00 2001 From: Alexander Trofimov Date: Thu, 29 Mar 2018 18:23:07 +0300 Subject: [PATCH 02/39] [changelog] Add to develop Add changelog to develop --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 503e6a20..fa4168df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ # Change log -## 5.1.1 +## develop ### Back-end * From ee7794597e4534e969e63395a942446b5af9b916 Mon Sep 17 00:00:00 2001 From: Alexey Golubev Date: Fri, 13 Apr 2018 17:10:05 +0300 Subject: [PATCH 03/39] Fix x2t crash after icu version update --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a0626854..4bd575f3 100644 --- a/Makefile +++ b/Makefile @@ -48,8 +48,8 @@ FILE_CONVERTER_FILES += ../core/Common/3dParty/v8/v8/out.gn/$(TARGET)/icudtl.dat endif ifeq ($(PLATFORM),win) -FILE_CONVERTER_FILES += ../core/Common/3dParty/icu/$(TARGET)/build/icudt55$(SHARED_EXT) -FILE_CONVERTER_FILES += ../core/Common/3dParty/icu/$(TARGET)/build/icuuc55$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/Common/3dParty/icu/$(TARGET)/build/icudt*$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/Common/3dParty/icu/$(TARGET)/build/icuuc*$(SHARED_EXT) FILE_CONVERTER_FILES += ../core/Common/3dParty/v8/v8/out.gn/$(TARGET)/release/icudtl.dat endif From de7d8c8cae5bcf5b8b5e26d07f9fda15781f8de0 Mon Sep 17 00:00:00 2001 From: "Alexander.Trofimov" Date: Fri, 13 Apr 2018 17:31:37 +0300 Subject: [PATCH 04/39] [build] Fix run server Fix icudt and icuuc versions --- update-core.bat | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/update-core.bat b/update-core.bat index 22129953..743999ba 100644 --- a/update-core.bat +++ b/update-core.bat @@ -16,8 +16,8 @@ powershell -executionpolicy remotesigned -file update-core.ps1 "http://repo-doc- cd /D "%~dp0\FileConverter\bin" || goto ERROR copy "core\Common\3dParty\v8\win_%OS%\release\icudt.dll" "." -copy "core\Common\3dParty\icu\win_%OS%\build\icudt55.dll" "." -copy "core\Common\3dParty\icu\win_%OS%\build\icuuc55.dll" "." +copy "core\Common\3dParty\icu\win_%OS%\build\icudt*.dll" "." +copy "core\Common\3dParty\icu\win_%OS%\build\icuuc*.dll" "." copy "core\build\lib\win_%OS%\doctrenderer.dll" "." copy "core\build\lib\win_%OS%\HtmlRenderer.dll" "." copy "core\build\lib\win_%OS%\DjVuFile.dll" "." From 865e04c85d56c4fe1c9ce1378f790608ac2a943b Mon Sep 17 00:00:00 2001 From: Oleg Korshul Date: Mon, 23 Apr 2018 12:47:05 +0300 Subject: [PATCH 05/39] Add new libraries to copy script --- update-core.bat | 2 ++ 1 file changed, 2 insertions(+) diff --git a/update-core.bat b/update-core.bat index 743999ba..ea6969a8 100644 --- a/update-core.bat +++ b/update-core.bat @@ -18,6 +18,8 @@ cd /D "%~dp0\FileConverter\bin" || goto ERROR copy "core\Common\3dParty\v8\win_%OS%\release\icudt.dll" "." copy "core\Common\3dParty\icu\win_%OS%\build\icudt*.dll" "." copy "core\Common\3dParty\icu\win_%OS%\build\icuuc*.dll" "." +copy "core\build\lib\win_%OS%\kernel.dll" "." +copy "core\build\lib\win_%OS%\graphics.dll" "." copy "core\build\lib\win_%OS%\doctrenderer.dll" "." copy "core\build\lib\win_%OS%\HtmlRenderer.dll" "." copy "core\build\lib\win_%OS%\DjVuFile.dll" "." From 2329d8aede43edc415bef6b9554aade2829b154c Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Tue, 24 Apr 2018 13:18:52 +0300 Subject: [PATCH 06/39] [config] Sync maxDownloadBytes with document-server-integration.Bug #37559 --- Common/config/default.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Common/config/default.json b/Common/config/default.json index cfedb7e2..f7c69dd4 100644 --- a/Common/config/default.json +++ b/Common/config/default.json @@ -185,7 +185,7 @@ }, "FileConverter": { "converter": { - "maxDownloadBytes": 100000000, + "maxDownloadBytes": 104857600, "downloadTimeout": 120, "downloadAttemptMaxCount": 3, "downloadAttemptDelay": 1000, From c33409f3e3b0d9ebca03410c76b76ab63939b13f Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 4 May 2018 19:32:57 +0300 Subject: [PATCH 07/39] [feature] Add savefile request handler --- Common/sources/commondefines.js | 7 +++ DocService/sources/DocsCoServer.js | 21 +++++++-- DocService/sources/canvasservice.js | 66 ++++++++++++++++++++++++++--- DocService/sources/server.js | 1 + 4 files changed, 86 insertions(+), 9 deletions(-) diff --git a/Common/sources/commondefines.js b/Common/sources/commondefines.js index e5649576..caccd0d9 100644 --- a/Common/sources/commondefines.js +++ b/Common/sources/commondefines.js @@ -633,6 +633,7 @@ function OutputSfcData() { this['lastsave'] = undefined; this['notmodified'] = undefined; this['forcesavetype'] = undefined; + this['crypted'] = undefined; } OutputSfcData.prototype.getKey = function() { return this['key']; @@ -706,6 +707,12 @@ OutputSfcData.prototype.getForceSaveType = function() { OutputSfcData.prototype.setForceSaveType = function(v) { this['forcesavetype'] = v; }; +OutputSfcData.prototype.getCrypted = function() { + return this['crypted'] +}; +OutputSfcData.prototype.setCrypted = function(v) { + this['crypted'] = v; +}; function OutputMailMerge(mailMergeSendData) { if (mailMergeSendData) { diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 0ae828d5..dde40d5f 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -1353,6 +1353,16 @@ exports.install = function(server, callbackFunction) { var puckerIndex = yield* getChangesIndex(docId); bHasChanges = puckerIndex > 0; + let needSendStatus = true; + if (conn.crypted) { + let selectRes = yield taskResult.select(docId); + if (selectRes.length > 0) { + var row = selectRes[0]; + if (taskResult.FileStatus.UpdateVersion === row.status) { + needSendStatus = false; + } + } + } // Если у нас нет пользователей, то удаляем все сообщения if (!bHasEditors) { // На всякий случай снимаем lock @@ -1366,13 +1376,15 @@ exports.install = function(server, callbackFunction) { needSaveChanges = forgotten.length > 0; logger.debug('closeDocument hasForgotten %s: docId = %s', needSaveChanges, docId); } - if (needSaveChanges) { + if (needSaveChanges && needSendStatus) { // Send changes to save server yield* _createSaveTimer(docId, tmpUser.idOriginal); - } else { + } else if (needSendStatus) { yield* cleanDocumentOnExitNoChanges(docId, tmpUser.idOriginal); + } else { + yield* cleanDocumentOnExit(docId); } - } else { + } else if (needSendStatus) { yield* sendStatusDocument(docId, c_oAscChangeBase.No, new commonDefines.OutputAction(commonDefines.c_oAscUserAction.Out, tmpUser.idOriginal)); } @@ -1859,6 +1871,7 @@ exports.install = function(server, callbackFunction) { } } } + data.crypted = decoded.crypted; //issuer for secret if (decoded.iss) { data.iss = decoded.iss; @@ -1899,6 +1912,7 @@ exports.install = function(server, callbackFunction) { //no standart edit.ds_view = conn.user.view; edit.ds_isCloseCoAuthoring = conn.isCloseCoAuthoring; + edit.crypted = conn.crypted; var options = {algorithm: cfgTokenSessionAlgorithm, expiresIn: cfgTokenSessionExpires / 1000}; var secret = utils.getSecretByElem(cfgSecretSession); @@ -1964,6 +1978,7 @@ exports.install = function(server, callbackFunction) { if (data.sessionTimeIdle >= 0) { conn.sessionTimeLastAction = new Date().getTime() - data.sessionTimeIdle; } + conn.crypted = data.crypted; const c_LR = constants.LICENSE_RESULT; conn.licenseType = c_LR.Success; diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index 56ddbc00..6c56a8de 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -614,7 +614,7 @@ function checkAuthorizationLength(authorization, data){ } return res; } -function* commandSfcCallback(cmd, isSfcm) { +function* commandSfcCallback(cmd, isSfcm, isCrypted) { var docId = cmd.getDocId(); logger.debug('Start commandSfcCallback: docId = %s', docId); var saveKey = cmd.getSaveKey(); @@ -640,8 +640,12 @@ function* commandSfcCallback(cmd, isSfcm) { } let updateMask = new taskResult.TaskResultData(); updateMask.key = docId; - updateMask.status = taskResult.FileStatus.SaveVersion; - updateMask.statusInfo = cmd.getData(); + if (!isCrypted) { + updateMask.status = taskResult.FileStatus.SaveVersion; + updateMask.statusInfo = cmd.getData(); + } else { + updateMask.status = taskResult.FileStatus.Ok; + } let updateIfTask = new taskResult.TaskResultData(); updateIfTask.status = taskResult.FileStatus.UpdateVersion; updateIfTask.statusInfo = Math.floor(Date.now() / 60000);//minutes @@ -650,6 +654,7 @@ function* commandSfcCallback(cmd, isSfcm) { logger.debug('Callback commandSfcCallback: docId = %s callback = %s', docId, getRes.server.href); var outputSfc = new commonDefines.OutputSfcData(); outputSfc.setKey(docId); + outputSfc.setCrypted(isCrypted); var users = []; let isOpenFromForgotten = false; //setUserId - set from changes in convert @@ -682,7 +687,7 @@ function* commandSfcCallback(cmd, isSfcm) { isSendHistory = !isOpenFromForgotten; logger.debug('commandSfcCallback forgotten no empty: docId = %s isSendHistory = %s', docId, isSendHistory); } - if (isSendHistory) { + if (isSendHistory && !isCrypted) { //don't send history info because changes isn't from file in storage var data = yield storage.getObject(savePathHistory); outputSfc.setChangeHistory(JSON.parse(data.toString('utf-8'))); @@ -729,7 +734,7 @@ function* commandSfcCallback(cmd, isSfcm) { //if anybody in document stop save var hasEditors = yield* docsCoServer.hasEditors(docId); logger.debug('hasEditors commandSfcCallback: docId = %s hasEditors = %d', docId, hasEditors); - if (!hasEditors) { + if (!hasEditors || isCrypted) { let lastSave = yield* docsCoServer.getLastSave(docId); let notModified = yield* docsCoServer.getLastForceSave(docId, lastSave); var lastSaveDate = lastSave ? new Date(lastSave.time) : new Date(); @@ -803,6 +808,7 @@ function* commandSfcCallback(cmd, isSfcm) { yield utils.promiseRedis(redisClient, redisClient.srem, keyRedis, docId); } logger.debug('End commandSfcCallback: docId = %s', docId); + return !isError; } function* commandSendMMCallback(cmd) { var docId = cmd.getDocId(); @@ -875,7 +881,9 @@ exports.openDocument = function(conn, cmd, opt_upsertRes, opt_bIsRestore) { outputData = new OutputData(cmd.getCommand()); switch (cmd.getCommand()) { case 'open': - yield* commandOpen(conn, cmd, outputData, opt_upsertRes, opt_bIsRestore); + if (!conn.crypted) { + yield* commandOpen(conn, cmd, outputData, opt_upsertRes, opt_bIsRestore); + } break; case 'reopen': yield* commandReopen(cmd); @@ -983,6 +991,52 @@ exports.downloadAs = function(req, res) { } }); }; +exports.saveFile = function(req, res) { + return co(function*() { + let docId = 'null'; + try { + let startDate = null; + if (clientStatsD) { + startDate = new Date(); + } + + let strCmd = req.query['cmd']; + let cmd = new commonDefines.InputCommand(JSON.parse(strCmd)); + docId = cmd.getDocId(); + logger.debug('Start saveFile: docId = %s %s', docId); + + if (cfgTokenEnableBrowser) { + let isValidJwt = false; + let checkJwtRes = docsCoServer.checkJwt(docId, cmd.getJwt(), commonDefines.c_oAscSecretType.Session); + if (checkJwtRes.decoded) { + let doc = checkJwtRes.decoded.document; + isValidJwt = true; + docId = doc.key; + cmd.setDocId(doc.key); + } else { + logger.warn('Error saveFile jwt: docId = %s\r\n%s', docId, checkJwtRes.description); + } + if (!isValidJwt) { + res.sendStatus(400); + return; + } + } + cmd.setStatusInfo(constants.NO_ERROR); + yield* addRandomKeyTaskCmd(cmd); + yield storage.putObject(cmd.getSaveKey() + '/' + cmd.getOutputPath(), req.body, req.body.length); + let sfcRes = yield* commandSfcCallback(cmd, false, true); + res.sendStatus(sfcRes ? 200 : 400); + logger.debug('End saveFile: docId = %s %s', docId, sfcRes); + if (clientStatsD) { + clientStatsD.timing('coauth.saveFile', new Date() - startDate); + } + } + catch (e) { + logger.error('Error saveFile: docId = %s\r\n%s', docId, e.stack); + res.sendStatus(400); + } + }); +}; exports.saveFromChanges = function(docId, statusInfo, optFormat, opt_userId, opt_queue) { return co(function* () { try { diff --git a/DocService/sources/server.js b/DocService/sources/server.js index 0f5c6857..f776533e 100644 --- a/DocService/sources/server.js +++ b/DocService/sources/server.js @@ -218,6 +218,7 @@ if (cluster.isMaster) { app.post('/upload/:docid/:userid/:index', rawFileParser, fileUploaderService.uploadImageFile); app.post('/downloadas/:docid', rawFileParser, canvasService.downloadAs); + app.post('/savefile/:docid', rawFileParser, canvasService.saveFile); app.get('/healthcheck', utils.checkClientIp, docsCoServer.healthCheck); app.get('/baseurl', (req, res) => { From 0e5c5d139038c9c9b6bced033dec4870b2feec63 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Mon, 7 May 2018 20:12:31 +0300 Subject: [PATCH 08/39] [feature] Rename crypted->encrypted, transfer replyStr to saveUrl handler --- Common/sources/commondefines.js | 10 +++---- Common/sources/utils.js | 12 ++++++--- DocService/sources/DocsCoServer.js | 11 +++++--- DocService/sources/canvasservice.js | 42 +++++++++++++++++------------ 4 files changed, 45 insertions(+), 30 deletions(-) diff --git a/Common/sources/commondefines.js b/Common/sources/commondefines.js index caccd0d9..0b7a5b84 100644 --- a/Common/sources/commondefines.js +++ b/Common/sources/commondefines.js @@ -633,7 +633,7 @@ function OutputSfcData() { this['lastsave'] = undefined; this['notmodified'] = undefined; this['forcesavetype'] = undefined; - this['crypted'] = undefined; + this['encrypted'] = undefined; } OutputSfcData.prototype.getKey = function() { return this['key']; @@ -707,11 +707,11 @@ OutputSfcData.prototype.getForceSaveType = function() { OutputSfcData.prototype.setForceSaveType = function(v) { this['forcesavetype'] = v; }; -OutputSfcData.prototype.getCrypted = function() { - return this['crypted'] +OutputSfcData.prototype.getEncrypted = function() { + return this['encrypted'] }; -OutputSfcData.prototype.setCrypted = function(v) { - this['crypted'] = v; +OutputSfcData.prototype.setEncrypted = function(v) { + this['encrypted'] = v; }; function OutputMailMerge(mailMergeSendData) { diff --git a/Common/sources/utils.js b/Common/sources/utils.js index e9fa0123..70af7814 100644 --- a/Common/sources/utils.js +++ b/Common/sources/utils.js @@ -402,6 +402,12 @@ function fillXmlResponse(val) { return xml; } +function fillResponseSimple(res, str, contentType) { + let body = new Buffer(str, 'utf-8'); + res.setHeader('Content-Type', contentType + '; charset=UTF-8'); + res.setHeader('Content-Length', body.length); + res.send(body); +} function _fillResponse(res, output, isJSON) { let data; let contentType; @@ -412,10 +418,7 @@ function _fillResponse(res, output, isJSON) { data = fillXmlResponse(output); contentType = 'text/xml'; } - let body = new Buffer(data, 'utf-8'); - res.setHeader('Content-Type', contentType + '; charset=UTF-8'); - res.setHeader('Content-Length', body.length); - res.send(body); + fillResponseSimple(res, data, contentType); } function fillResponse(req, res, uri, error, isJSON) { @@ -439,6 +442,7 @@ function fillResponse(req, res, uri, error, isJSON) { _fillResponse(res, output, isJSON); } +exports.fillResponseSimple = fillResponseSimple; exports.fillResponse = fillResponse; function fillResponseBuilder(res, key, urls, end, error) { diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index dde40d5f..511fecff 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -1354,7 +1354,7 @@ exports.install = function(server, callbackFunction) { bHasChanges = puckerIndex > 0; let needSendStatus = true; - if (conn.crypted) { + if (conn.encrypted) { let selectRes = yield taskResult.select(docId); if (selectRes.length > 0) { var row = selectRes[0]; @@ -1833,6 +1833,9 @@ exports.install = function(server, callbackFunction) { openCmd.url = doc.url; } } + if (null != doc.ds_encrypted) { + data.encrypted = doc.ds_encrypted; + } } if (decoded.editorConfig) { var edit = decoded.editorConfig; @@ -1871,7 +1874,7 @@ exports.install = function(server, callbackFunction) { } } } - data.crypted = decoded.crypted; + //issuer for secret if (decoded.iss) { data.iss = decoded.iss; @@ -1901,6 +1904,7 @@ exports.install = function(server, callbackFunction) { var doc = payload.document; doc.key = conn.docId; doc.permissions = conn.permissions; + doc.ds_encrypted = conn.encrypted; var edit = payload.editorConfig; //todo //edit.callbackUrl = callbackUrl; @@ -1912,7 +1916,6 @@ exports.install = function(server, callbackFunction) { //no standart edit.ds_view = conn.user.view; edit.ds_isCloseCoAuthoring = conn.isCloseCoAuthoring; - edit.crypted = conn.crypted; var options = {algorithm: cfgTokenSessionAlgorithm, expiresIn: cfgTokenSessionExpires / 1000}; var secret = utils.getSecretByElem(cfgSecretSession); @@ -1978,7 +1981,7 @@ exports.install = function(server, callbackFunction) { if (data.sessionTimeIdle >= 0) { conn.sessionTimeLastAction = new Date().getTime() - data.sessionTimeIdle; } - conn.crypted = data.crypted; + conn.encrypted = data.encrypted; const c_LR = constants.LICENSE_RESULT; conn.licenseType = c_LR.Success; diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index 6c56a8de..244bb87a 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -614,7 +614,7 @@ function checkAuthorizationLength(authorization, data){ } return res; } -function* commandSfcCallback(cmd, isSfcm, isCrypted) { +function* commandSfcCallback(cmd, isSfcm, isEncrypted) { var docId = cmd.getDocId(); logger.debug('Start commandSfcCallback: docId = %s', docId); var saveKey = cmd.getSaveKey(); @@ -629,6 +629,7 @@ function* commandSfcCallback(cmd, isSfcm, isCrypted) { var forceSaveType = forceSave ? forceSave.getType() : commonDefines.c_oAscForceSaveTypes.Command; var isSfcmSuccess = false; let storeForgotten = false; + let replyStr; var statusOk; var statusErr; if (isSfcm) { @@ -640,7 +641,7 @@ function* commandSfcCallback(cmd, isSfcm, isCrypted) { } let updateMask = new taskResult.TaskResultData(); updateMask.key = docId; - if (!isCrypted) { + if (!isEncrypted) { updateMask.status = taskResult.FileStatus.SaveVersion; updateMask.statusInfo = cmd.getData(); } else { @@ -654,7 +655,7 @@ function* commandSfcCallback(cmd, isSfcm, isCrypted) { logger.debug('Callback commandSfcCallback: docId = %s callback = %s', docId, getRes.server.href); var outputSfc = new commonDefines.OutputSfcData(); outputSfc.setKey(docId); - outputSfc.setCrypted(isCrypted); + outputSfc.setEncrypted(isEncrypted); var users = []; let isOpenFromForgotten = false; //setUserId - set from changes in convert @@ -687,7 +688,7 @@ function* commandSfcCallback(cmd, isSfcm, isCrypted) { isSendHistory = !isOpenFromForgotten; logger.debug('commandSfcCallback forgotten no empty: docId = %s isSendHistory = %s', docId, isSendHistory); } - if (isSendHistory && !isCrypted) { + if (isSendHistory && !isEncrypted) { //don't send history info because changes isn't from file in storage var data = yield storage.getObject(savePathHistory); outputSfc.setChangeHistory(JSON.parse(data.toString('utf-8'))); @@ -723,7 +724,7 @@ function* commandSfcCallback(cmd, isSfcm, isCrypted) { outputSfc.setLastSave(new Date(forceSave.getTime()).toISOString()); } try { - let replyStr = yield* docsCoServer.sendServerRequest(docId, uri, outputSfc, checkAuthorizationLength); + replyStr = yield* docsCoServer.sendServerRequest(docId, uri, outputSfc, checkAuthorizationLength); let replyData = docsCoServer.parseReplyData(docId, replyStr); isSfcmSuccess = replyData && commonDefines.c_oAscServerCommandErrors.NoError == replyData.error; } catch (err) { @@ -732,9 +733,9 @@ function* commandSfcCallback(cmd, isSfcm, isCrypted) { } } else { //if anybody in document stop save - var hasEditors = yield* docsCoServer.hasEditors(docId); - logger.debug('hasEditors commandSfcCallback: docId = %s hasEditors = %d', docId, hasEditors); - if (!hasEditors || isCrypted) { + let hvals = yield docsCoServer.getAllPresencePromise(docId); + logger.debug('commandSfcCallback presence: docId = %s count = %d', docId, hvals.length); + if (0 === hvals.length || (isEncrypted && 1 === hvals.length)) { let lastSave = yield* docsCoServer.getLastSave(docId); let notModified = yield* docsCoServer.getLastForceSave(docId, lastSave); var lastSaveDate = lastSave ? new Date(lastSave.time) : new Date(); @@ -744,11 +745,9 @@ function* commandSfcCallback(cmd, isSfcm, isCrypted) { if (updateIfRes.affectedRows > 0) { updateMask.status = updateIfTask.status; updateMask.statusInfo = updateIfTask.statusInfo; - var replyStr = null; try { replyStr = yield* docsCoServer.sendServerRequest(docId, uri, outputSfc, checkAuthorizationLength); } catch (err) { - replyStr = null; logger.error('sendServerRequest error: docId = %s;url = %s;data = %j\r\n%s', docId, uri, outputSfc, err.stack); } var requestRes = false; @@ -808,7 +807,7 @@ function* commandSfcCallback(cmd, isSfcm, isCrypted) { yield utils.promiseRedis(redisClient, redisClient.srem, keyRedis, docId); } logger.debug('End commandSfcCallback: docId = %s', docId); - return !isError; + return replyStr; } function* commandSendMMCallback(cmd) { var docId = cmd.getDocId(); @@ -1010,9 +1009,14 @@ exports.saveFile = function(req, res) { let checkJwtRes = docsCoServer.checkJwt(docId, cmd.getJwt(), commonDefines.c_oAscSecretType.Session); if (checkJwtRes.decoded) { let doc = checkJwtRes.decoded.document; - isValidJwt = true; - docId = doc.key; - cmd.setDocId(doc.key); + var edit = checkJwtRes.decoded.editorConfig; + if (doc.ds_encrypted && !edit.ds_view && !edit.ds_isCloseCoAuthoring) { + isValidJwt = true; + docId = doc.key; + cmd.setDocId(doc.key); + } else { + logger.warn('Error saveFile jwt: docId = %s\r\n%s', docId, 'access deny'); + } } else { logger.warn('Error saveFile jwt: docId = %s\r\n%s', docId, checkJwtRes.description); } @@ -1024,9 +1028,13 @@ exports.saveFile = function(req, res) { cmd.setStatusInfo(constants.NO_ERROR); yield* addRandomKeyTaskCmd(cmd); yield storage.putObject(cmd.getSaveKey() + '/' + cmd.getOutputPath(), req.body, req.body.length); - let sfcRes = yield* commandSfcCallback(cmd, false, true); - res.sendStatus(sfcRes ? 200 : 400); - logger.debug('End saveFile: docId = %s %s', docId, sfcRes); + let replyStr = yield* commandSfcCallback(cmd, false, true); + if (replyStr) { + utils.fillResponseSimple(res, replyStr, 'application/json'); + } else { + res.sendStatus(400); + } + logger.debug('End saveFile: docId = %s %s', docId, replyStr); if (clientStatsD) { clientStatsD.timing('coauth.saveFile', new Date() - startDate); } From 0e99442ef37f2dee3a5b1d291ce19852c93d66c2 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Mon, 7 May 2018 20:22:51 +0300 Subject: [PATCH 09/39] [feature] Rename crypted->encrypted --- DocService/sources/canvasservice.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index 244bb87a..af01fd6c 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -880,7 +880,7 @@ exports.openDocument = function(conn, cmd, opt_upsertRes, opt_bIsRestore) { outputData = new OutputData(cmd.getCommand()); switch (cmd.getCommand()) { case 'open': - if (!conn.crypted) { + if (!conn.encrypted) { yield* commandOpen(conn, cmd, outputData, opt_upsertRes, opt_bIsRestore); } break; From dd19151dbee55e5596fe944a5ef852f1bfb2af8a Mon Sep 17 00:00:00 2001 From: Alexander Yuzhin Date: Wed, 23 May 2018 18:00:30 +0300 Subject: [PATCH 10/39] Fixed run on macOS --- .gitignore | 1 + run-mac.command | 45 ++++++++++++++++++++++++++++----------------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 92fdb344..21ffd39a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ FileConverter/bin/*.S FileConverter/bin/font_selection.bin FileConverter/bin/HtmlFileInternal FileConverter/bin/core.zip +FileConverter/bin/core.tar.gz FileConverter/bin/core DocService/npm-debug.log build diff --git a/run-mac.command b/run-mac.command index 48db55ad..888ac802 100755 --- a/run-mac.command +++ b/run-mac.command @@ -32,35 +32,46 @@ RunCommand() { CreateDir "$BASEDIR/App_Data" CreateDir "$BASEDIR/FileConverter/bin" +CreateDir "$BASEDIR/FileConverter/bin/core" CreateDir "$BASEDIR/FileConverter/bin/HtmlFileInternal" cd "$BASEDIR/FileConverter/bin" -cp -v "../../../core/build/bin/mac_64/icudtl_dat.S" "." -cp -v "../../../core/build/bin/mac_64/x2t" "." -cp -v "../../../core/build/bin/icu/mac_64/libicudata.55.1.dylib" "." -cp -v "../../../core/build/bin/icu/mac_64/libicuuc.55.1.dylib" "." -cp -v "../../../core/build/lib/mac_64/libDjVuFile.dylib" "." -cp -v "../../../core/build/lib/mac_64/libHtmlFile.dylib" "." -cp -v "../../../core/build/lib/mac_64/libHtmlRenderer.dylib" "." -cp -v "../../../core/build/lib/mac_64/libPdfReader.dylib" "." -cp -v "../../../core/build/lib/mac_64/libPdfWriter.dylib" "." -cp -v "../../../core/build/lib/mac_64/libUnicodeConverter.dylib" "." -cp -v "../../../core/build/lib/mac_64/libXpsFile.dylib" "." -cp -v "../../../core/build/lib/mac_64/libascdocumentscore.dylib" "." -cp -v "../../../core/build/lib/mac_64/libdoctrenderer.dylib" "." +wget -N http://repo-doc-onlyoffice-com.s3.amazonaws.com/mac/core/origin/develop/latest/x64/core.tar.gz +gunzip -c core.tar.gz | tar xopf - -C core + +cp -v "core/build/bin/mac_64/icudtl_dat.S" "." +cp -v "core/build/bin/mac_64/x2t" "." +cp -v "core/Common/3dParty/icu/mac_64/build/libicudata.60.dylib" "." +cp -v "core/Common/3dParty/icu/mac_64/build/libicuuc.60.dylib" "." +cp -v "core/Common/3dParty/icu/mac_64/build/libicudata.60.2.dylib" "." +cp -v "core/Common/3dParty/icu/mac_64/build/libicuuc.60.2.dylib" "." +cp -v "core/build/lib/mac_64/libDjVuFile.dylib" "." +cp -v "core/build/lib/mac_64/libHtmlFile.dylib" "." +cp -v "core/build/lib/mac_64/libHtmlRenderer.dylib" "." +cp -v "core/build/lib/mac_64/libPdfReader.dylib" "." +cp -v "core/build/lib/mac_64/libPdfWriter.dylib" "." +cp -v "core/build/lib/mac_64/libUnicodeConverter.dylib" "." +cp -v "core/build/lib/mac_64/libXpsFile.dylib" "." +cp -v "core/build/lib/mac_64/libascdocumentscore.dylib" "." +cp -v "core/build/lib/mac_64/libdoctrenderer.dylib" "." +cp -v "core/build/lib/mac_64/libkernel.dylib" "." -ln -sifv libicuuc.55.1.dylib libicuuc.55.dylib -ln -sifv libicudata.55.1.dylib libicudata.55.dylib chmod -v +x x2t SEARCH='..\/..\/OfficeWeb' REPLACE='..\/..\/..\/sdkjs' sed "s/$SEARCH/$REPLACE/g" "../../../core/build/lib/DoctRenderer.config" > "DoctRenderer.config" +echo "----------------------------------------" +echo "Font generation " +echo "----------------------------------------" + echo $BASEDIR -chmod -v +x $BASEDIR/../core/build/bin/AllFontsGen/mac_64 -bash -cv "$BASEDIR/../core/build/bin/AllFontsGen/mac_64 '' '$BASEDIR/../sdkjs/Common/AllFonts.js' '$BASEDIR/../sdkjs/Common/Images' '$BASEDIR/FileConverter/bin/font_selection.bin'" +cd "$BASEDIR/FileConverter/bin/core/build/bin" +CreateDir "$BASEDIR/../fonts" +chmod -v +x $BASEDIR/FileConverter/bin/core/build/bin/AllFontsGen/mac_64 +bash -cv "$BASEDIR/FileConverter/bin/core/build/bin/AllFontsGen/mac_64 '' '$BASEDIR/../sdkjs/Common/AllFonts.js' '$BASEDIR/../sdkjs/Common/Images' '$BASEDIR/FileConverter/bin/font_selection.bin' '$BASEDIR/../fonts'" echo "----------------------------------------" From e1134f3362a3638c0662bae95f499b414094fcf1 Mon Sep 17 00:00:00 2001 From: "Alexander.Trofimov" Date: Tue, 5 Jun 2018 15:12:04 +0300 Subject: [PATCH 11/39] [chat] Add useridoriginal Add useridoriginal to all messages --- DocService/sources/DocsCoServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 6c22af69..8538043c 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -2247,7 +2247,7 @@ exports.install = function(server, callbackFunction) { function* onMessage(conn, data) { var docId = conn.docId; var userId = conn.user.id; - var msg = {docid: docId, message: data.message, time: Date.now(), user: userId, username: conn.user.username}; + var msg = {docid: docId, message: data.message, time: Date.now(), user: userId, useridoriginal: conn.user.idOriginal, username: conn.user.username}; var msgStr = JSON.stringify(msg); var multi = redisClient.multi([ ['rpush', redisKeyMessage + docId, msgStr], From 345d3a7ddcbc2a2713c4c8242cfb5afb9865d499 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Thu, 21 Jun 2018 19:47:47 +0300 Subject: [PATCH 12/39] [lock] Use userId instead of sessionId in locks --- DocService/sources/DocsCoServer.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 6c22af69..8aebcfb0 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -1395,7 +1395,7 @@ exports.install = function(server, callbackFunction) { //Давайдосвиданья! //Release locks - userLocks = yield* getUserLocks(docId, conn.sessionId); + userLocks = yield* getUserLocks(docId, conn.user.id); if (0 < userLocks.length) { //todo на close себе ничего не шлем //sendReleaseLock(conn, userLocks); @@ -1485,13 +1485,13 @@ exports.install = function(server, callbackFunction) { yield utils.promiseRedis(multi, multi.exec); } } - function* getUserLocks(docId, sessionId) { + function* getUserLocks(docId, userId) { var userLocks = [], i; var toCache = []; var docLock = yield* getAllLocks(docId); for (i = 0; i < docLock.length; ++i) { var elem = docLock[i]; - if (elem.sessionId === sessionId) { + if (elem.user === userId) { userLocks.push(elem); } else { toCache.push(JSON.stringify(elem)); @@ -1557,7 +1557,7 @@ exports.install = function(server, callbackFunction) { //Release locks if (isSave && conn) { if (releaseLocks) { - const userLocks = yield* getUserLocks(docId, conn.sessionId); + const userLocks = yield* getUserLocks(docId, userId); if (0 < userLocks.length) { sendReleaseLock(conn, userLocks); yield* publish({ @@ -2303,7 +2303,7 @@ exports.install = function(server, callbackFunction) { var toCache = []; for (i = 0; i < arrayBlocks.length; ++i) { var block = arrayBlocks[i]; - var elem = {time: Date.now(), user: userId, block: block, sessionId: conn.sessionId}; + var elem = {time: Date.now(), user: userId, block: block}; documentLocks[block] = elem; toCache.push(JSON.stringify(elem)); } @@ -2328,7 +2328,7 @@ exports.install = function(server, callbackFunction) { var toCache = []; for (i = 0; i < arrayBlocks.length; ++i) { var block = arrayBlocks[i]; - var elem = {time: Date.now(), user: userId, block: block, sessionId: conn.sessionId}; + var elem = {time: Date.now(), user: userId, block: block}; documentLocks.push(elem); toCache.push(JSON.stringify(elem)); } @@ -2353,7 +2353,7 @@ exports.install = function(server, callbackFunction) { var toCache = []; for (i = 0; i < arrayBlocks.length; ++i) { var block = arrayBlocks[i]; - var elem = {time: Date.now(), user: userId, block: block, sessionId: conn.sessionId}; + var elem = {time: Date.now(), user: userId, block: block}; documentLocks.push(elem); toCache.push(JSON.stringify(elem)); } @@ -2443,7 +2443,7 @@ exports.install = function(server, callbackFunction) { let userLocks = []; if (data.releaseLocks) { //Release locks - userLocks = yield* getUserLocks(docId, conn.sessionId); + userLocks = yield* getUserLocks(docId, userId); } // Для данного пользователя снимаем Lock с документа, если пришел флаг unlock const checkEndAuthLockRes = yield* checkEndAuthLock(data.unlock, false, docId, userId); From e92f2fea2cb440005a46c69f3390e01d2134fe84 Mon Sep 17 00:00:00 2001 From: Pavel Lobashov Date: Fri, 13 Jul 2018 14:35:32 +0300 Subject: [PATCH 13/39] Add onlyoffice user by `useradd` `useradd` exist on any linux system but `adduser` not exists on arch linux at least --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8e9a2224..c0da7a9c 100644 --- a/Makefile +++ b/Makefile @@ -145,7 +145,8 @@ clean: rm -rf $(CORE_FONTS) $(OUTPUT) $(GRUNT_FILES) install: - sudo adduser --quiet --home /var/www/onlyoffice --system --group onlyoffice + sudo mkdir -pv /var/www/onlyoffice + if ! sudo id -u onlyoffice > /dev/null 2>&1; then sudo useradd -m -d /var/www/onlyoffice -r -U onlyoffice; fi sudo mkdir -p /var/www/onlyoffice/documentserver sudo mkdir -p /var/www/onlyoffice/documentserver/fonts From 1fbc5a23f567a3d10d36d56e1ba083932262a3d7 Mon Sep 17 00:00:00 2001 From: Pavel Lobashov Date: Fri, 13 Jul 2018 16:33:43 +0300 Subject: [PATCH 14/39] Remove all sudo calls, since command is `sudo make install` --- Makefile | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index c0da7a9c..aedc87bf 100644 --- a/Makefile +++ b/Makefile @@ -145,21 +145,21 @@ clean: rm -rf $(CORE_FONTS) $(OUTPUT) $(GRUNT_FILES) install: - sudo mkdir -pv /var/www/onlyoffice - if ! sudo id -u onlyoffice > /dev/null 2>&1; then sudo useradd -m -d /var/www/onlyoffice -r -U onlyoffice; fi + mkdir -pv /var/www/onlyoffice + if ! id -u onlyoffice > /dev/null 2>&1; then useradd -m -d /var/www/onlyoffice -r -U onlyoffice; fi - sudo mkdir -p /var/www/onlyoffice/documentserver - sudo mkdir -p /var/www/onlyoffice/documentserver/fonts - sudo mkdir -p /var/log/onlyoffice/documentserver - sudo mkdir -p /var/lib/onlyoffice/documentserver/App_Data + mkdir -p /var/www/onlyoffice/documentserver + mkdir -p /var/www/onlyoffice/documentserver/fonts + mkdir -p /var/log/onlyoffice/documentserver + mkdir -p /var/lib/onlyoffice/documentserver/App_Data - sudo cp -fr -t /var/www/onlyoffice/documentserver build/* ../web-apps/deploy/* - sudo mkdir -p /etc/onlyoffice/documentserver - sudo mv /var/www/onlyoffice/documentserver/server/Common/config/* /etc/onlyoffice/documentserver + cp -fr -t /var/www/onlyoffice/documentserver build/* ../web-apps/deploy/* + mkdir -p /etc/onlyoffice/documentserver + mv /var/www/onlyoffice/documentserver/server/Common/config/* /etc/onlyoffice/documentserver - sudo chown onlyoffice:onlyoffice -R /var/www/onlyoffice - sudo chown onlyoffice:onlyoffice -R /var/log/onlyoffice - sudo chown onlyoffice:onlyoffice -R /var/lib/onlyoffice + chown onlyoffice:onlyoffice -R /var/www/onlyoffice + chown onlyoffice:onlyoffice -R /var/log/onlyoffice + chown onlyoffice:onlyoffice -R /var/lib/onlyoffice # Make symlinks for shared libs find \ @@ -178,12 +178,12 @@ install: --use-system="true" uninstall: - sudo userdel onlyoffice + userdel onlyoffice # Unlink installed shared libs find /lib -type l | while IFS= read -r lnk; do if (readlink "$$lnk" | grep -q '^${DOCUMENT_ROOT}/server/FileConverter/bin/'); then rm "$$lnk"; fi; done - sudo rm -rf /var/www/onlyoffice/documentserver - sudo rm -rf /var/log/onlyoffice/documentserver - sudo rm -rf /var/lib/onlyoffice/documentserver - sudo rm -rf /etc/onlyoffice/documentserver + rm -rf /var/www/onlyoffice/documentserver + rm -rf /var/log/onlyoffice/documentserver + rm -rf /var/lib/onlyoffice/documentserver + rm -rf /etc/onlyoffice/documentserver From 06fc4fda4b5fc6d4266b526059c120b6d3a231c9 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Tue, 17 Jul 2018 17:02:20 +0300 Subject: [PATCH 15/39] [feature] Add faked file type for PDFA --- Common/sources/constants.js | 1 + Common/sources/formatchecker.js | 1 + FileConverter/sources/converter.js | 8 +++++++- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Common/sources/constants.js b/Common/sources/constants.js index 0f781045..779bf789 100644 --- a/Common/sources/constants.js +++ b/Common/sources/constants.js @@ -120,6 +120,7 @@ exports.AVS_OFFICESTUDIO_FILE_OTHER_OLD_PRESENTATION = exports.AVS_OFFICESTUDIO_ exports.AVS_OFFICESTUDIO_FILE_OTHER_OLD_DRAWING = exports.AVS_OFFICESTUDIO_FILE_OTHER + 0x0006; exports.AVS_OFFICESTUDIO_FILE_OTHER_TEAMLAB_INNER = exports.AVS_OFFICESTUDIO_FILE_OTHER + 0x0007; exports.AVS_OFFICESTUDIO_FILE_OTHER_JSON = exports.AVS_OFFICESTUDIO_FILE_OTHER + 0x0008; // Для mail-merge +exports.AVS_OFFICESTUDIO_FILE_OTHER_PDFA = exports.AVS_OFFICESTUDIO_FILE_OTHER + 0x0101; exports.AVS_OFFICESTUDIO_FILE_TEAMLAB = 0x1000; exports.AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY = exports.AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0001; exports.AVS_OFFICESTUDIO_FILE_TEAMLAB_XLSY = exports.AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0002; diff --git a/Common/sources/formatchecker.js b/Common/sources/formatchecker.js index a6c28a4d..77bc776c 100644 --- a/Common/sources/formatchecker.js +++ b/Common/sources/formatchecker.js @@ -333,6 +333,7 @@ exports.getStringFromFormat = function(format) { return 'csv'; case constants.AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF: + case constants.AVS_OFFICESTUDIO_FILE_OTHER_PDFA: return 'pdf'; case constants.AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_SWF: return 'swf'; diff --git a/FileConverter/sources/converter.js b/FileConverter/sources/converter.js index 16a765fc..f4b90da2 100644 --- a/FileConverter/sources/converter.js +++ b/FileConverter/sources/converter.js @@ -89,7 +89,12 @@ function TaskQueueDataConvert(task) { this.key = cmd.savekey ? cmd.savekey : cmd.id; this.fileFrom = null; this.fileTo = null; - this.formatTo = cmd.outputformat; + if(constants.AVS_OFFICESTUDIO_FILE_OTHER_PDFA !== cmd.outputformat){ + this.formatTo = cmd.outputformat; + } else { + this.formatTo = constants.AVS_OFFICESTUDIO_FILE_CROSSPLATFORM_PDF; + this.isPDFA = true; + } this.csvTxtEncoding = cmd.getCodepage(); this.csvDelimiter = cmd.getDelimiter(); this.csvDelimiterChar = cmd.getDelimiterChar(); @@ -119,6 +124,7 @@ TaskQueueDataConvert.prototype = { xml += this.serializeXmlProp('m_sFileFrom', this.fileFrom); xml += this.serializeXmlProp('m_sFileTo', this.fileTo); xml += this.serializeXmlProp('m_nFormatTo', this.formatTo); + xml += this.serializeXmlProp('m_bIsPDFA', this.isPDFA); xml += this.serializeXmlProp('m_nCsvTxtEncoding', this.csvTxtEncoding); xml += this.serializeXmlProp('m_nCsvDelimiter', this.csvDelimiter); xml += this.serializeXmlProp('m_nCsvDelimiterChar', this.csvDelimiterChar); From a5493a893875c5405d06f52e0f2db4f7fdab7ca4 Mon Sep 17 00:00:00 2001 From: "Alexander.Trofimov" Date: Tue, 24 Jul 2018 18:48:50 +0300 Subject: [PATCH 16/39] [rights] Fix fillForms mode --- DocService/sources/DocsCoServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 519ff2fc..b47c0500 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -1804,7 +1804,7 @@ exports.install = function(server, callbackFunction) { if (permissions && mode) { //as in web-apps/apps/documenteditor/main/app/controller/Main.js return ((permissions.edit !== false || permissions.review === true) && mode !== 'view') || - permissions.comment === true; + permissions.comment === true || permissions.fillForms === true; } else { return def; } From 8c2435d25d7210caed0fa267081449f3469670dd Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Tue, 7 Aug 2018 15:13:18 +0300 Subject: [PATCH 17/39] [bug] Fix healthcheck service in case of disconnected redis or rabbitmq --- Common/sources/rabbitMQCore.js | 8 ++++++-- Common/sources/taskqueueRabbitMQ.js | 2 +- DocService/sources/DocsCoServer.js | 10 +++++++--- DocService/sources/pubsubRabbitMQ.js | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/Common/sources/rabbitMQCore.js b/Common/sources/rabbitMQCore.js index 9c6f2786..eb995229 100644 --- a/Common/sources/rabbitMQCore.js +++ b/Common/sources/rabbitMQCore.js @@ -40,13 +40,17 @@ var cfgRabbitSocketOptions = config.get('rabbitmq.socketOptions'); var RECONNECT_TIMEOUT = 1000; -function connetPromise(closeCallback) { +function connetPromise(reconnectOnConnectionError, closeCallback) { return new Promise(function(resolve, reject) { function startConnect() { amqp.connect(cfgRabbitUrl, cfgRabbitSocketOptions, function(err, conn) { if (null != err) { logger.error('[AMQP] %s', err.stack); - setTimeout(startConnect, RECONNECT_TIMEOUT); + if (reconnectOnConnectionError) { + setTimeout(startConnect, RECONNECT_TIMEOUT); + } else { + reject(err); + } } else { conn.on('error', function(err) { logger.error('[AMQP] conn error', err.stack); diff --git a/Common/sources/taskqueueRabbitMQ.js b/Common/sources/taskqueueRabbitMQ.js index c86bf02b..52b4fb96 100644 --- a/Common/sources/taskqueueRabbitMQ.js +++ b/Common/sources/taskqueueRabbitMQ.js @@ -50,7 +50,7 @@ function init(taskqueue, isAddTask, isAddResponse, isAddTaskReceive, isAddRespon return co(function* () { var e = null; try { - var conn = yield rabbitMQCore.connetPromise(function() { + var conn = yield rabbitMQCore.connetPromise(true, function() { clear(taskqueue); if (!taskqueue.isClose) { init(taskqueue, isAddTask, isAddResponse, isAddTaskReceive, isAddResponseReceive, null); diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index b47c0500..0c7b9165 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -3061,10 +3061,14 @@ exports.healthCheck = function(req, res) { //database promises.push(sqlBase.healthCheck()); //redis - promises.push(utils.promiseRedis(redisClient, redisClient.ping)); - yield Promise.all(promises); + if (redisClient.connected) { + promises.push(utils.promiseRedis(redisClient, redisClient.ping)); + yield Promise.all(promises); + } else { + throw new Error('redis disconnected'); + } //rabbitMQ - let conn = yield rabbitMQCore.connetPromise(function() {}); + let conn = yield rabbitMQCore.connetPromise(false, function() {}); yield rabbitMQCore.closePromise(conn); //storage const clusterId = cluster.isWorker ? cluster.worker.id : ''; diff --git a/DocService/sources/pubsubRabbitMQ.js b/DocService/sources/pubsubRabbitMQ.js index b2bb7523..236c7b47 100644 --- a/DocService/sources/pubsubRabbitMQ.js +++ b/DocService/sources/pubsubRabbitMQ.js @@ -43,7 +43,7 @@ function init(pubsub, callback) { return co(function* () { var e = null; try { - var conn = yield rabbitMQCore.connetPromise(function() { + var conn = yield rabbitMQCore.connetPromise(true, function() { clear(pubsub); if (!pubsub.isClose) { init(pubsub, null); From f54e260792695c75199035b4ce10ecc35fe0a7f6 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 17 Aug 2018 18:44:03 +0300 Subject: [PATCH 18/39] [config] Add spawnOptions for x2t --- Common/config/default.json | 1 + FileConverter/sources/converter.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Common/config/default.json b/Common/config/default.json index 5b539314..2ab55e74 100644 --- a/Common/config/default.json +++ b/Common/config/default.json @@ -198,6 +198,7 @@ "docbuilderPath": "null", "docbuilderAllFontsPath": "null", "args": "", + "spawnOptions": {}, "errorfiles": "", "streamWriterBufferSize": 8388608, "maxRedeliveredCount": 2, diff --git a/FileConverter/sources/converter.js b/FileConverter/sources/converter.js index 54c9c71a..bd667b9c 100644 --- a/FileConverter/sources/converter.js +++ b/FileConverter/sources/converter.js @@ -61,6 +61,10 @@ var cfgX2tPath = configConverter.get('x2tPath'); var cfgDocbuilderPath = configConverter.get('docbuilderPath'); var cfgDocbuilderAllFontsPath = configConverter.get('docbuilderAllFontsPath'); var cfgArgs = configConverter.get('args'); +var cfgSpawnOptions = configConverter.get('spawnOptions'); +if (cfgSpawnOptions.env) { + Object.assign(cfgSpawnOptions.env, process.env); +} var cfgErrorFiles = configConverter.get('errorfiles'); var cfgInputLimits = configConverter.get('inputLimits'); const cfgStreamWriterBufferSize = configConverter.get('streamWriterBufferSize'); @@ -647,7 +651,7 @@ function* ExecuteTask(task) { } let timeoutId; try { - let spawnAsyncPromise = spawnAsync(processPath, childArgs); + let spawnAsyncPromise = spawnAsync(processPath, childArgs, cfgSpawnOptions); childRes = spawnAsyncPromise.child; let waitMS = task.getVisibilityTimeout() * 1000 - (new Date().getTime() - getTaskTime.getTime()); timeoutId = setTimeout(function() { From 97cf8b96f0ee31d7f5bad155eb72d0a57c0bbff5 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 17 Aug 2018 19:08:12 +0300 Subject: [PATCH 19/39] [bug] For bug 36960 Fill response Content-Type. --- DocService/sources/DocsCoServer.js | 1 + DocService/sources/canvasservice.js | 1 + DocService/sources/fileuploaderservice.js | 2 ++ 3 files changed, 4 insertions(+) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 0c7b9165..06324a8b 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -3088,6 +3088,7 @@ exports.healthCheck = function(req, res) { } catch (err) { logger.error('healthCheck error\r\n%s', err.stack); } finally { + res.setHeader('Content-Type', 'text/plain'); res.send(output.toString()); } }); diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index c2d2b742..b76c65d7 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -1016,6 +1016,7 @@ exports.downloadAs = function(req, res) { break; } var strRes = JSON.stringify(outputData); + res.setHeader('Content-Type', 'application/json'); res.send(strRes); logger.debug('End downloadAs: docId = %s %s', docId, strRes); if(clientStatsD) { diff --git a/DocService/sources/fileuploaderservice.js b/DocService/sources/fileuploaderservice.js index f6178bee..c4abebba 100644 --- a/DocService/sources/fileuploaderservice.js +++ b/DocService/sources/fileuploaderservice.js @@ -174,6 +174,7 @@ exports.uploadImageFileOld = function(req, res) { output += '", "*"); }'; //res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Content-Type', 'text/html'); res.send(output); logger.debug('End uploadImageFileOld: docId = %s %s', docId, output); } @@ -246,6 +247,7 @@ exports.uploadImageFile = function(req, res) { } finally { try { if (!isError) { + res.setHeader('Content-Type', 'application/json'); res.send(JSON.stringify(output)); } else { res.sendStatus(400); From 7ccb4606322e5ce420c404a400cd54574954c232 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Mon, 20 Aug 2018 13:16:38 +0300 Subject: [PATCH 20/39] [feature] Use title param in ConvertService.ashx --- DocService/sources/converterservice.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/DocService/sources/converterservice.js b/DocService/sources/converterservice.js index c3d5167f..2a70bd2e 100644 --- a/DocService/sources/converterservice.js +++ b/DocService/sources/converterservice.js @@ -32,6 +32,7 @@ 'use strict'; +const path = require('path'); var config = require('config'); var co = require('co'); var taskResult = require('./taskresult'); @@ -59,7 +60,8 @@ function* getConvertStatus(cmd, selectRes, baseUrl, opt_fileTo) { case taskResult.FileStatus.Ok: status.end = true; if (opt_fileTo) { - status.url = yield storage.getSignedUrl(baseUrl, docId + '/' + opt_fileTo, commonDefines.c_oAscUrlTypes.Temporary); + status.url = yield storage.getSignedUrl(baseUrl, docId + '/' + opt_fileTo, + commonDefines.c_oAscUrlTypes.Temporary, cmd.getTitle()); } break; case taskResult.FileStatus.Err: @@ -193,6 +195,7 @@ function convertRequest(req, res, isJson) { cmd.setEmbeddedFonts(false);//params.embeddedfonts']; cmd.setFormat(params.filetype); var outputtype = params.outputtype || ''; + let outputExt = outputtype; docId = 'conv_' + params.key + '_' + outputtype; cmd.setDocId(docId); var fileTo = constants.OUTPUT_NAME + '.' + outputtype; @@ -227,9 +230,12 @@ function convertRequest(req, res, isJson) { cmd.setThumbnail(thumbnailData); cmd.setOutputFormat(constants.AVS_OFFICESTUDIO_FILE_IMAGE); if (false == thumbnailData.getFirst()) { - cmd.setTitle(constants.OUTPUT_NAME + '.zip'); + outputExt = 'zip'; } } + if (params.title) { + cmd.setTitle(path.basename(params.title, path.extname(params.title)) + '.' + outputExt); + } var async = (typeof params.async === 'string') ? 'true' == params.async : params.async; if (constants.AVS_OFFICESTUDIO_FILE_UNKNOWN !== cmd.getOutputFormat()) { From 51e8f5aa5a2a488ceee44a8f074c2e0bf805d82c Mon Sep 17 00:00:00 2001 From: Alexey Golubev Date: Fri, 24 Aug 2018 18:58:33 +0300 Subject: [PATCH 21/39] Use forked statsd --- Metrics/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Metrics/package.json b/Metrics/package.json index ce676b7a..ec80f8f6 100644 --- a/Metrics/package.json +++ b/Metrics/package.json @@ -4,6 +4,6 @@ "homepage": "http://www.onlyoffice.com", "private": true, "dependencies": { - "statsd": "^0.8.0" + "statsd": "https://github.com/ONLYOFFICE/statsd/archive/v0.8.1.tar.gz" } } From 348fb95cf814066aec4ee39f9b25601abbf24c24 Mon Sep 17 00:00:00 2001 From: Alexey Golubev Date: Mon, 27 Aug 2018 19:19:23 +0300 Subject: [PATCH 22/39] Copy set of shared libraries --- Makefile | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index aedc87bf..5f420bea 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ else ifeq ($(UNAME_S),Linux) PLATFORM := linux SHARED_EXT := .so* + LIB_PREFIX := lib endif UNAME_M := $(shell uname -m) ifeq ($(UNAME_M),x86_64) @@ -39,7 +40,16 @@ endif TARGET := $(PLATFORM)_$(ARCHITECTURE) FILE_CONVERTER = $(OUTPUT)/FileConverter/bin -FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/*$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)DjVuFile$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)docrenderer$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)graphics$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)HtmlFileFile$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)HtmlRenderer$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)kernel$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)PdfReader$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)PdfWriter$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)UnicodeConverter$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)XpsFile$(SHARED_EXT) ifeq ($(PLATFORM),linux) FILE_CONVERTER_FILES += ../core/Common/3dParty/icu/$(TARGET)/build/libicudata$(SHARED_EXT) From 97bc7aaf38128db6bad109b9d32b9ffde93be51d Mon Sep 17 00:00:00 2001 From: Alexey Golubev Date: Tue, 28 Aug 2018 12:20:35 +0300 Subject: [PATCH 23/39] fix misprint --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5f420bea..a33eb83c 100644 --- a/Makefile +++ b/Makefile @@ -41,9 +41,9 @@ TARGET := $(PLATFORM)_$(ARCHITECTURE) FILE_CONVERTER = $(OUTPUT)/FileConverter/bin FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)DjVuFile$(SHARED_EXT) -FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)docrenderer$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)doctrenderer$(SHARED_EXT) FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)graphics$(SHARED_EXT) -FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)HtmlFileFile$(SHARED_EXT) +FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)HtmlFile$(SHARED_EXT) FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)HtmlRenderer$(SHARED_EXT) FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)kernel$(SHARED_EXT) FILE_CONVERTER_FILES += ../core/build/lib/$(TARGET)/$(LIB_PREFIX)PdfReader$(SHARED_EXT) From b53a4d24a3a721967569e26f3e2878d7be95c6be Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 31 Aug 2018 17:24:13 +0300 Subject: [PATCH 24/39] [jwt] Do not reduce authorization header in case of inBody option --- DocService/sources/DocsCoServer.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 06324a8b..d5ee794e 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -619,13 +619,12 @@ function* sendServerRequest(docId, uri, dataObject, opt_checkAuthorization) { let auth; if (cfgTokenEnableRequestOutbox) { auth = utils.fillJwtForRequest(dataObject); - if (opt_checkAuthorization && !opt_checkAuthorization(auth, dataObject)) { - auth = utils.fillJwtForRequest(dataObject); - logger.warn('authorization reduced to: docId = %s; length=%d', docId, auth.length); - } if (cfgTokenOutboxInBody) { dataObject = {token: auth}; auth = undefined; + } else if (opt_checkAuthorization && !opt_checkAuthorization(auth, dataObject)) { + auth = utils.fillJwtForRequest(dataObject); + logger.warn('authorization reduced to: docId = %s; length=%d', docId, auth.length); } } let res = yield utils.postRequestPromise(uri, JSON.stringify(dataObject), cfgCallbackRequestTimeout * 1000, auth); From e0bede2b69291dc749917efbc286f303fa381210 Mon Sep 17 00:00:00 2001 From: "Alexander.Trofimov" Date: Thu, 6 Sep 2018 15:31:09 +0300 Subject: [PATCH 25/39] [license] Branding Branding now int. Check string and boolean for old versions --- Common/sources/license.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Common/sources/license.js b/Common/sources/license.js index 33836ac5..e872cffa 100644 --- a/Common/sources/license.js +++ b/Common/sources/license.js @@ -91,7 +91,7 @@ exports.readLicense = function*() { } res.light = (true === oLicense['light'] || 'true' === oLicense['light']); // Someone who likes to put json string instead of bool - res.branding = (true === oLicense['branding'] || 'true' === oLicense['branding']); // Someone who likes to put json string instead of bool + res.branding = getBranding(oLicense['branding']); if (oLicense.hasOwnProperty('connections')) { res.connections = oLicense['connections'] >> 0; } @@ -143,6 +143,10 @@ function getLicenseMode(mode) { const c_LM = constants.LICENSE_MODE; return 'developer' === mode ? c_LM.Developer : ('trial' === mode ? c_LM.Trial : c_LM.None); } +function getBranding(mode) { + // Someone who likes to put json string instead of bool + return ((typeof mode === 'string') ? 'true' === mode : (mode || 0)) - 0; +} function* _getFileState() { const val = yield utils.promiseRedis(redisClient, redisClient.hget, redisKeyLicense, redisKeyLicense); From ca99b37f5ba98775f6b864f9c5155e2a4320f329 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 7 Sep 2018 14:26:47 +0300 Subject: [PATCH 26/39] [log] Add reSave to mark repeated changes saving --- DocService/sources/DocsCoServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index d5ee794e..fc01b180 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -2382,7 +2382,7 @@ exports.install = function(server, callbackFunction) { // Для Excel необходимо делать пересчет lock-ов при добавлении/удалении строк/столбцов function* saveChanges(conn, data) { const docId = conn.docId, userId = conn.user.id; - logger.info("Start saveChanges docid: %s", docId); + logger.info("Start saveChanges docid: %s; reSave: %s", docId, data.reSave); let puckerIndex = yield* getChangesIndex(docId); From 33808e5a2f639b4d6c78adf665e9418fd114d6b7 Mon Sep 17 00:00:00 2001 From: "Alexander.Trofimov" Date: Mon, 10 Sep 2018 17:10:24 +0300 Subject: [PATCH 27/39] [license] plugins Use new key 'plugins' instead of 'branding' (revert to boolean) --- Common/sources/license.js | 10 ++++------ DocService/sources/DocsCoServer.js | 5 +++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Common/sources/license.js b/Common/sources/license.js index e872cffa..0ccea3e1 100644 --- a/Common/sources/license.js +++ b/Common/sources/license.js @@ -64,7 +64,8 @@ exports.readLicense = function*() { connections: constants.LICENSE_CONNECTIONS, usersCount: 0, usersExpire: constants.LICENSE_EXPIRE_USERS_ONE_DAY, - hasLicense: false + hasLicense: false, + plugins: false }; let checkFile = false; try { @@ -91,7 +92,8 @@ exports.readLicense = function*() { } res.light = (true === oLicense['light'] || 'true' === oLicense['light']); // Someone who likes to put json string instead of bool - res.branding = getBranding(oLicense['branding']); + res.branding = (true === oLicense['branding'] || 'true' === oLicense['branding']); // Someone who likes to put json string instead of bool + res.plugins = true === oLicense['plugins']; if (oLicense.hasOwnProperty('connections')) { res.connections = oLicense['connections'] >> 0; } @@ -143,10 +145,6 @@ function getLicenseMode(mode) { const c_LM = constants.LICENSE_MODE; return 'developer' === mode ? c_LM.Developer : ('trial' === mode ? c_LM.Trial : c_LM.None); } -function getBranding(mode) { - // Someone who likes to put json string instead of bool - return ((typeof mode === 'string') ? 'true' === mode : (mode || 0)) - 0; -} function* _getFileState() { const val = yield utils.promiseRedis(redisClient, redisClient.hget, redisKeyLicense, redisKeyLicense); diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index fc01b180..5e01400a 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -173,7 +173,7 @@ let connections = []; // Активные соединения let lockDocumentsTimerId = {};//to drop connection that can't unlockDocument let pubsub; let queue; -let licenseInfo = {type: constants.LICENSE_RESULT.Error, light: false, branding: false}; +let licenseInfo = {type: constants.LICENSE_RESULT.Error, light: false, branding: false, plugins: false}; let shutdownFlag = false; const MIN_SAVE_EXPIRATION = 60000; @@ -2687,7 +2687,8 @@ exports.install = function(server, callbackFunction) { rights: rights, buildVersion: commonDefines.buildVersion, buildNumber: commonDefines.buildNumber, - branding: licenseInfo.branding + branding: licenseInfo.branding, + plugins: licenseInfo.plugins } }); } catch (err) { From 7cb15aa0acfff330cb194d8ca45a04654564a4a0 Mon Sep 17 00:00:00 2001 From: Alexey Golubev Date: Mon, 10 Sep 2018 19:35:52 +0300 Subject: [PATCH 28/39] Fix installation bug --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a33eb83c..01e8af9c 100644 --- a/Makefile +++ b/Makefile @@ -163,7 +163,7 @@ install: mkdir -p /var/log/onlyoffice/documentserver mkdir -p /var/lib/onlyoffice/documentserver/App_Data - cp -fr -t /var/www/onlyoffice/documentserver build/* ../web-apps/deploy/* + cp -fr -t /var/www/onlyoffice/documentserver build/* ../web-apps-pro/deploy/* mkdir -p /etc/onlyoffice/documentserver mv /var/www/onlyoffice/documentserver/server/Common/config/* /etc/onlyoffice/documentserver From 453dac9613a9db195ce6a06ac480bdca95ba5676 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Wed, 12 Sep 2018 19:38:07 +0300 Subject: [PATCH 29/39] [feature] Add info/json handler for license --- Common/sources/constants.js | 1 + DocService/sources/DocsCoServer.js | 86 ++++++++++++++++++++++++++++++ DocService/sources/server.js | 1 + 3 files changed, 88 insertions(+) diff --git a/Common/sources/constants.js b/Common/sources/constants.js index c8f0e8fa..ab802950 100644 --- a/Common/sources/constants.js +++ b/Common/sources/constants.js @@ -206,6 +206,7 @@ exports.REDIS_KEY_SHUTDOWN = 'shutdown'; exports.REDIS_KEY_COLLECT_LOST = 'collectlost'; exports.REDIS_KEY_LICENSE = 'license'; exports.REDIS_KEY_LICENSE_T = 'licenseT'; +exports.REDIS_KEY_EDITOR_CONNECTIONS = 'editorconnections'; exports.SHUTDOWN_CODE = 4001; exports.SHUTDOWN_REASON = 'server shutdown'; diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 5e01400a..53519204 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -159,6 +159,7 @@ const redisKeyForceSaveTimer = cfgRedisPrefix + constants.REDIS_KEY_FORCE_SAVE_T const redisKeyForceSaveTimerLock = cfgRedisPrefix + constants.REDIS_KEY_FORCE_SAVE_TIMER_LOCK; const redisKeySaved = cfgRedisPrefix + constants.REDIS_KEY_SAVED; const redisKeyPresenceUniqueUsers = cfgRedisPrefix + constants.REDIS_KEY_PRESENCE_UNIQUE_USERS; +const redisKeyEditorConnections = cfgRedisPrefix + constants.REDIS_KEY_EDITOR_CONNECTIONS; const EditorTypes = { document : 0, @@ -181,6 +182,10 @@ const FORCE_SAVE_EXPIRATION = Math.min(Math.max(cfgForceSaveInterval, MIN_SAVE_E cfgQueueRetentionPeriod * 1000); const HEALTH_CHECK_KEY_MAX = 10000; +const PRECISION = [{name: 'hour', val: ms('1h')}, {name: 'day', val: ms('1d')}, {name: 'week', val: ms('1w')}, + {name: 'month', val: ms('31d')}, +]; + function getIsShutdown() { return shutdownFlag; } @@ -2952,6 +2957,19 @@ exports.install = function(server, callbackFunction) { } }); } + + function* collectStats(countEdit, countView) { + let now = Date.now(); + var multi = redisClient.multi( + [ + ['lpop', redisKeyEditorConnections], + ['rpush', redisKeyEditorConnections, JSON.stringify({time: now, edit: countEdit, view: countView})] + ]); + let multiRes = yield utils.promiseRedis(multi, multi.exec); + if (multiRes.length > 1 && JSON.parse(multiRes[0]).time > now - PRECISION[PRECISION.length - 1].val) { + yield utils.promiseRedis(redisClient, redisClient.lpush, redisKeyEditorConnections, multiRes[0]); + } + } function expireDoc() { var cronJob = this; return co(function* () { @@ -3006,6 +3024,7 @@ exports.install = function(server, callbackFunction) { idSet.forEach(function(value1, value2, set) { commands.push(['zadd', redisKeyDocuments, expireAt, value1]); }); + yield* collectStats(countEdit, countView); if (commands.length > 0) { var multi = redisClient.multi(commands); yield utils.promiseRedis(multi, multi.exec); @@ -3093,6 +3112,73 @@ exports.healthCheck = function(req, res) { } }); }; +exports.licenseInfo = function(req, res) { + return co(function*() { + let isError = false; + let output = {connectionsStat: {}}; + Object.assign(output, licenseInfo); + try { + logger.debug('licenseInfo start'); + var precisionSum = {}; + for (let i = 0; i < PRECISION.length; ++i) { + precisionSum[PRECISION[i].name] = { + edit: {min: Number.MAX_VALUE, sum: 0, count: 0, max: 0}, + view: {min: Number.MAX_VALUE, sum: 0, count: 0, max: 0} + }; + output.connectionsStat[PRECISION[i].name] = { + edit: {min: 0, avr: 0, max: 0}, + view: {min: 0, avr: 0, max: 0} + }; + } + var redisRes = yield utils.promiseRedis(redisClient, redisClient.lrange, redisKeyEditorConnections, 0, -1); + const now = Date.now(); + var precisionIndex = 0; + for (let i = redisRes.length - 1; i >= 1; i -= 2) { + for (let j = precisionIndex; j < PRECISION.length; ++j) { + let elem = JSON.parse(redisRes[i]); + if (now - elem.time < PRECISION[j].val) { + let precision = precisionSum[PRECISION[j].name]; + precision.edit.min = Math.min(precision.edit.min, elem.edit); + precision.edit.max = Math.max(precision.edit.max, elem.edit); + precision.edit.sum += elem.edit; + precision.edit.count++; + precision.view.min = Math.min(precision.view.min, elem.view); + precision.view.max = Math.max(precision.view.max, elem.view); + precision.view.sum += elem.view; + precision.view.count++; + } else { + precisionIndex = j + 1; + } + } + } + for (let i in precisionSum) { + let precision = precisionSum[i]; + let precisionOut = output.connectionsStat[i]; + if (precision.edit.count > 0) { + precisionOut.edit.avr = Math.round(precision.edit.sum / precision.edit.count); + precisionOut.edit.min = precision.edit.min; + precisionOut.edit.max = precision.edit.max; + } + if (precision.view.count > 0) { + precisionOut.view.avr = Math.round(precision.view.sum / precision.view.count); + precisionOut.view.min = precision.view.min; + precisionOut.view.max = precision.view.max; + } + } + logger.debug('licenseInfo end'); + } catch (err) { + isError = true; + logger.error('licenseInfo error\r\n%s', err.stack); + } finally { + if (!isError) { + res.setHeader('Content-Type', 'application/json'); + res.send(JSON.stringify(output)); + } else { + res.sendStatus(400); + } + } + }); +}; // Команда с сервера (в частности teamlab) exports.commandFromServer = function (req, res) { return co(function* () { diff --git a/DocService/sources/server.js b/DocService/sources/server.js index f776533e..ca845b27 100644 --- a/DocService/sources/server.js +++ b/DocService/sources/server.js @@ -234,6 +234,7 @@ if (cluster.isMaster) { } converterService.builder(req, res); }); + app.get('/info/info.json', utils.checkClientIp, docsCoServer.licenseInfo); const sendUserPlugins = (res, data) => { res.setHeader('Content-Type', 'application/json'); From c595814c6f6633355ec18bad286571824fef0c3c Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Thu, 13 Sep 2018 16:55:30 +0300 Subject: [PATCH 30/39] [feature] Add info page --- Common/config/production-linux.json | 4 + Common/config/production-windows.json | 4 + Makefile | 10 +- info/index.html | 232 ++++++++++++++++++++++++++ 4 files changed, 249 insertions(+), 1 deletion(-) create mode 100644 info/index.html diff --git a/Common/config/production-linux.json b/Common/config/production-linux.json index 2f4a42f1..fcfaccb6 100644 --- a/Common/config/production-linux.json +++ b/Common/config/production-linux.json @@ -27,6 +27,10 @@ "path": "/var/www/onlyoffice/documentserver/server/welcome", "options": {"maxAge": "7d"} }, + "/info": { + "path": "/var/www/onlyoffice/documentserver/server/info", + "options": {"maxAge": "7d"} + }, "/sdkjs-plugins": { "path": "/var/www/onlyoffice/documentserver/sdkjs-plugins", "options": {"maxAge": "7d"} diff --git a/Common/config/production-windows.json b/Common/config/production-windows.json index 77cfde6f..296d9ac3 100644 --- a/Common/config/production-windows.json +++ b/Common/config/production-windows.json @@ -30,6 +30,10 @@ "/welcome": { "path": "../../welcome", "options": {"maxAge": "7d"} + }, + "/info": { + "path": "../../info", + "options": {"maxAge": "7d"} } } }, diff --git a/Makefile b/Makefile index 01e8af9c..6bf3e7d2 100644 --- a/Makefile +++ b/Makefile @@ -93,6 +93,10 @@ WELCOME_DIR = welcome WELCOME_FILES = $(WELCOME_DIR)/** WELCOME = $(OUTPUT)/$(WELCOME_DIR)/ +INFO_DIR = info +INFO_FILES = $(INFO_DIR)/** +INFO = $(OUTPUT)/$(INFO_DIR)/ + CORE_FONTS_DIR = core-fonts CORE_FONTS_FILES = ../$(CORE_FONTS_DIR)/** CORE_FONTS = $(OUTPUT)/../$(CORE_FONTS_DIR)/ @@ -100,7 +104,7 @@ CORE_FONTS = $(OUTPUT)/../$(CORE_FONTS_DIR)/ .PHONY: all clean install uninstall build-date htmlfileinternal docbuilder .NOTPARALLEL: -all: $(FILE_CONVERTER) $(SPELLCHECKER_DICTIONARIES) $(TOOLS) $(SCHEMA) $(CORE_FONTS) $(LICENSE) $(WELCOME) build-date +all: $(FILE_CONVERTER) $(SPELLCHECKER_DICTIONARIES) $(TOOLS) $(SCHEMA) $(CORE_FONTS) $(LICENSE) $(WELCOME) $(INFO) build-date ext: htmlfileinternal docbuilder @@ -147,6 +151,10 @@ $(WELCOME): mkdir -p $(WELCOME) && \ cp -r -t $(WELCOME) $(WELCOME_FILES) +$(INFO): + mkdir -p $(INFO) && \ + cp -r -t $(INFO) $(INFO_FILES) + $(CORE_FONTS): mkdir -p $(CORE_FONTS) && \ cp -r -t $(CORE_FONTS) $(CORE_FONTS_FILES) diff --git a/info/index.html b/info/index.html new file mode 100644 index 00000000..26ef0c47 --- /dev/null +++ b/info/index.html @@ -0,0 +1,232 @@ + + + + ONLYOFFICE™ + + + + + + + +
+
+
Please, wait...
+ + +
+ + + From f8ad659e89e0941d8dafd59d83de812ea9f95464 Mon Sep 17 00:00:00 2001 From: "Alexander.Trofimov" Date: Thu, 13 Sep 2018 18:29:32 +0300 Subject: [PATCH 31/39] [license] Add info --- DocService/sources/DocsCoServer.js | 4 ++-- info/index.html | 18 ++++++++++-------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 53519204..cfd56c19 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -3115,8 +3115,8 @@ exports.healthCheck = function(req, res) { exports.licenseInfo = function(req, res) { return co(function*() { let isError = false; - let output = {connectionsStat: {}}; - Object.assign(output, licenseInfo); + let output = {connectionsStat: {}, licenseInfo: {}}; + Object.assign(output.licenseInfo, licenseInfo); try { logger.debug('licenseInfo start'); var precisionSum = {}; diff --git a/info/index.html b/info/index.html index 26ef0c47..379b7ba6 100644 --- a/info/index.html +++ b/info/index.html @@ -117,7 +117,7 @@ Limit to concurent connections: - 100 + 100
@@ -183,18 +183,21 @@ } return xmlhttp; }; - function fillInfo(info) { - return 3; + function fillInfo(licenseInfo) { + var elem = document.getElementById('license-limit'); + var limit = licenseInfo.usersCount || licenseInfo.connections; + elem.innerText = limit; + return limit; } - function fillConnections(info, connectionsLimit) { + function fillConnections(info, limit) { for (var precision in info.connectionsStat) { for (var agregate in info.connectionsStat[precision].edit) { var value = info.connectionsStat[precision].edit[agregate]; var elem = document.getElementById('cell-' + precision + '-' + agregate); elem.innerText = value; - if (value >= connectionsLimit) { + if (value >= limit) { elem.classList.add("critical"); - } else if (value >= connectionsLimit * 0.7) { + } else if (value >= limit * 0.7) { elem.classList.add("warning"); } } @@ -214,8 +217,7 @@ if (xhrObj.status == 200) { document.getElementById('doc-server-ok').classList.remove("hidden"); var info = JSON.parse(xhrObj.responseText); - var connectionsLimit = fillInfo(info); - fillConnections(info, connectionsLimit); + fillConnections(info, fillInfo(info.licenseInfo)); } else { document.getElementById('doc-server-err').classList.remove("hidden"); } From 44bff7172cba3bdc5a118c891165a766059b172a Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 14 Sep 2018 13:47:28 +0300 Subject: [PATCH 32/39] [bug] Change '1w' -> '7d' --- DocService/sources/DocsCoServer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index cfd56c19..12259398 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -182,7 +182,7 @@ const FORCE_SAVE_EXPIRATION = Math.min(Math.max(cfgForceSaveInterval, MIN_SAVE_E cfgQueueRetentionPeriod * 1000); const HEALTH_CHECK_KEY_MAX = 10000; -const PRECISION = [{name: 'hour', val: ms('1h')}, {name: 'day', val: ms('1d')}, {name: 'week', val: ms('1w')}, +const PRECISION = [{name: 'hour', val: ms('1h')}, {name: 'day', val: ms('1d')}, {name: 'week', val: ms('7d')}, {name: 'month', val: ms('31d')}, ]; From 03b24fc7bcb36f747a67c29cb5b0d32c44692e53 Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 14 Sep 2018 15:41:36 +0300 Subject: [PATCH 33/39] [bug] Improve average calculation at server start --- DocService/sources/DocsCoServer.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 12259398..748da04c 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -3122,7 +3122,7 @@ exports.licenseInfo = function(req, res) { var precisionSum = {}; for (let i = 0; i < PRECISION.length; ++i) { precisionSum[PRECISION[i].name] = { - edit: {min: Number.MAX_VALUE, sum: 0, count: 0, max: 0}, + edit: {min: Number.MAX_VALUE, sum: 0, count: 0, max: 0, time: null, period: PRECISION[i].val}, view: {min: Number.MAX_VALUE, sum: 0, count: 0, max: 0} }; output.connectionsStat[PRECISION[i].name] = { @@ -3142,6 +3142,7 @@ exports.licenseInfo = function(req, res) { precision.edit.max = Math.max(precision.edit.max, elem.edit); precision.edit.sum += elem.edit; precision.edit.count++; + precision.edit.time = elem.time; precision.view.min = Math.min(precision.view.min, elem.view); precision.view.max = Math.max(precision.view.max, elem.view); precision.view.sum += elem.view; @@ -3154,13 +3155,15 @@ exports.licenseInfo = function(req, res) { for (let i in precisionSum) { let precision = precisionSum[i]; let precisionOut = output.connectionsStat[i]; + //scale compensates for the lack of points at server start + let scale = (now - precision.edit.time) / precision.edit.period; if (precision.edit.count > 0) { - precisionOut.edit.avr = Math.round(precision.edit.sum / precision.edit.count); + precisionOut.edit.avr = Math.round((precision.edit.sum / precision.edit.count) * scale); precisionOut.edit.min = precision.edit.min; precisionOut.edit.max = precision.edit.max; } if (precision.view.count > 0) { - precisionOut.view.avr = Math.round(precision.view.sum / precision.view.count); + precisionOut.view.avr = Math.round((precision.view.sum / precision.view.count) * scale); precisionOut.view.min = precision.view.min; precisionOut.view.max = precision.view.max; } From aa79ef801849da4143efc06a60bd15944504ca1d Mon Sep 17 00:00:00 2001 From: "Alexander.Trofimov" Date: Fri, 14 Sep 2018 16:59:23 +0300 Subject: [PATCH 34/39] [info] Add params Add buildDate and endDate to license info --- Common/sources/license.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Common/sources/license.js b/Common/sources/license.js index 0ccea3e1..d30fab11 100644 --- a/Common/sources/license.js +++ b/Common/sources/license.js @@ -65,7 +65,9 @@ exports.readLicense = function*() { usersCount: 0, usersExpire: constants.LICENSE_EXPIRE_USERS_ONE_DAY, hasLicense: false, - plugins: false + plugins: false, + buildDate: oBuildDate, + endDate: null }; let checkFile = false; try { @@ -80,6 +82,7 @@ exports.readLicense = function*() { const publicKey = '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDRhGF7X4A0ZVlEg594WmODVVUI\niiPQs04aLmvfg8SborHss5gQXu0aIdUT6nb5rTh5hD2yfpF2WIW6M8z0WxRhwicg\nXwi80H1aLPf6lEPPLvN29EhQNjBpkFkAJUbS8uuhJEeKw0cE49g80eBBF4BCqSL6\nPFQbP9/rByxdxEoAIQIDAQAB\n-----END PUBLIC KEY-----\n'; if (verify.verify(publicKey, sign, 'hex')) { const endDate = new Date(oLicense['end_date']); + res.endDate = endDate; const isTrial = (true === oLicense['trial'] || 'true' === oLicense['trial']); // Someone who likes to put json string instead of bool res.mode = isTrial ? c_LM.Trial : getLicenseMode(oLicense['mode']); const checkDate = c_LM.Trial === res.mode ? new Date() : oBuildDate; From a1e1a2639aab6f383def75307e36ece82c7b0a5c Mon Sep 17 00:00:00 2001 From: "Alexander.Trofimov" Date: Fri, 14 Sep 2018 17:25:04 +0300 Subject: [PATCH 35/39] [info] Add server info Add buildVersion and buildNumber to info --- DocService/sources/DocsCoServer.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 748da04c..5a6c9723 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -3115,7 +3115,11 @@ exports.healthCheck = function(req, res) { exports.licenseInfo = function(req, res) { return co(function*() { let isError = false; - let output = {connectionsStat: {}, licenseInfo: {}}; + let output = { + connectionsStat: {}, licenseInfo: {}, serverInfo: { + buildVersion: commonDefines.buildVersion, buildNumber: commonDefines.buildNumber, + } + }; Object.assign(output.licenseInfo, licenseInfo); try { logger.debug('licenseInfo start'); From ad85c25616911a5f8dfde7566901eab389eb5069 Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Mon, 17 Sep 2018 13:46:17 +0300 Subject: [PATCH 36/39] Fill license and server info --- info/img/favicon.ico | Bin 0 -> 1150 bytes info/img/icon-cross.png | Bin 0 -> 1080 bytes info/img/logo.png | Bin 0 -> 3615 bytes info/index.html | 104 +++++++++++++++++++++++++++------------- 4 files changed, 72 insertions(+), 32 deletions(-) create mode 100644 info/img/favicon.ico create mode 100644 info/img/icon-cross.png create mode 100644 info/img/logo.png diff --git a/info/img/favicon.ico b/info/img/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fc55efad2c5bb765724fd5ee712907e5dec70503 GIT binary patch literal 1150 zcmb7oTR2T+nCWLvuKb5N%P&`*X(Z^lV0n6`@GNd`##_A^XnB!QEx_usBezE zN)vf1A_WR1DJ7<>BBEyh^Yna-RM}?FugB*vK-g1zDBEd0whm24@P6_Xjg~OXT`|~G z4*ydgx__d%8x$XzDpYMN=S7Nqq>(cTh|8FvD!I>9@JC z!H2?nAM&3Es;~Jy&I}-&x`J zJIY~*^3bbu$<;Sg{A72kXkmA<0C!LtXUTq}vv)jalo)w#szie6B7G?$scw)o zpfyoZFMbjAiYHI%L8I|2(SrsfiJEv3^`Oy%iAq8Y(Tj-@xM(!~0diFX8ZQcHVuVTp zr4b5fpg?`z_T6T)w6rswrOTWALh0_zK2PUk=bc?wcXzkY5CPBt_JJ*616TuA@$o4T z0Y5=6cn`Y3NTC<@6j0U=&VUnOH*hU-t{3<~9XP<>B|s180M9{GMTA?S%v$gO`~nX_ zeGc*2!o_8&jsegLs_isDt#u9bgR7?Qp(9p;OQ4Uhu|l_jP2eNA56XmnQO4JxYi-kI z;1HmZzEdn+>;NCY;X)0Z2d_YdSo)yWc*z=+3^al#phOfeN?1dqtbv0(D>x-uSyNsH zwu1H||MHnyqMfxZYJjG%PMc?%LdHa=b&9nbxD2)n=LTuJlFb0!1#b!G$4&Dc+ic*v zL%U9aWgG|uL~U(t`v2kKVVUBkthvQ)G9VSRv$N^XB!mR1il3gIR%yVKMi-(h z?~*M&K0YqO;jpv`t9YtoY-~)$0OcUnWMIGIdOq3gGA1&Km+U&$e4>F2>@8$U$k&8s z@kZ2pIENL5nxLqusY#olFa|cwG{!NF;wkFLz(yT4Winw*k2Z-Pp1O^>JK1334-MiU zI%c9=Q>AraYZ?#VsRepJk%S)g@bYix-=H}Ah_6`yHkYLkf`GC;e;2|LBxWP&um zGY0V|m1IOl{9-1ms;X2Bkme!dKJY@ew8!I-7H>8|WsLB8y($Jel1oy4z(MKRfJ|0K z>m16;;_6~EogF(fhN`@@-;xw1}+r2CFWQ|TecH&Wn@pmks^%= znl6vB2BB(z;*Cf>kY38!=?m{yz0P%FzBw@sY;Yf%DIk;7&wzU( z_0XH<;wg>7|ANP0Gv8%r@-3*cEAd;TUNs2u-yX$$!g$$(>R2yQuNs79D{*Oh-G;J~ y2JW}?B++=?rpz=Tjn{3yaTeI6V?*J;00RKvN<-G*4?iye0000bRc+POLCtj5esSO1`+k3X{r2yiv-e(SJghjN5ueWp&`U@7|jg$H!qB}-Zz7RfWKX+!Dhh! zh(e=W0oEi64qyZ_(822J=>Z@Rke;Ct1fr)6(AU+|2kWvfh>o5i%m@P0hXVc?Kvp!0 ze*nx4Vf#-k*3Jxwr&7rHtE3>mBk(%nDOFGm#W|91@y z{ntC3>W2HT-v5(0+#{Nd1H0kENf8t*t8f9z`=Q7%YYGlSB~d&`q>x`(bj6dXq;Ncm z46t^G0Mt9YpZ8VZHjLiO})46Wb@ z0}~q?D_dPdJ$-9y#4jv@gpCNr5vjkh{{O`q{}#L7454IJWCV^vh{XBZQb?hIzYh%~ z{9cREZ~6Yg`u|=F$LeJ}J6bsfO4c(SJJp@4Lpy2{?!4^i)y zmS^uj^@)5PZ_v>?aQ~C(`j^u6qpzZCU5sm6dHV>@tw+rYHzf= zf?mPMCZMd&z0N9*Hw)^GBKFkbj+R&ZFNM0+KJQr^S(p);Wv7=eeJ^2)7wLxDR$J_t z|EX31!b!!ylJ@SCbc{z#?Iv)#;@S!}zW8Gq08m8du%-QW;n1k$NKzy6KJ9?r!Ghsj zJB{QFw2%zEkp5mF=I|8#ky=_tZMx_1s?h0Dya$-?`9Q?g%c8j*@zk96fld9e=JPWx zjQXjB&Fw3WOAex&LRxv}5Om|!6dQ)Lr`S#IPr{{9d@{@Wsj4_n6%@`cPOlxOU32jD z^Tgn!MiaG5yh_i>N#%SgDJjR>Y&m8NuhR-%)=WcSoct1L+9^$eexKv`Z`?+YBf0*{ zq)qu*Qgm9|CZlb!*J9o-wv9+slvh9cCJ9O5DF7YMdRU6ALFOhO)N6nDW!mQ`2tr9t z5ZK@#3yB5t_Zf@2tGhtbq}cAr<~U9zLJTzO>;u`KU#K;gtGZ|M(9p3Z(rJ9;t5CmD zE%sWQ6|+rTRc0ynvJL7TQ$=DmymxG?QWbSdWZX_^{dF!!an=5UR*j$~z`n_1@80*M@P}8iJfVFg3jobpAoR9D1V^mXydwe$_?|lgOv5AAVF>u zN*$r^x5DhkH3_EtSs#V%dk-1bA9E>iHB%We#$j7QvsbF36PReJr^=AWD=M{@ywAxm zUSF57^O98vAG3d65xz7IZbu3qMrUk3^Ph9}Jp}N!DqbjYA~4{fNW5XOO2KuhTv%m+ z>h@R)fp8*2W5!0yOW(+$Ut(b+y+~3Y4!S*_*y4ZJU;a57C{TOSO-*Ij10vhXm_?K& z=OsS{Fw>zo>Fjse71{di6pHtNjkj^jg>qtk>?13QXvs+S`C??4+bo^urVRmB1kB0e zpV{fJhy>VA#1`_`Ja6`r7i@jMk#oc4OI9_kI3TUh9hH3U^458U{8gbj za7cN2^arU+_=ZgPVgH$db37<5XqnX4ZRf=YXAqt3>%xZ_ThZUoPIDLRefef;Ti!Ht zp;-6IC^Nkm{qq?#!!uwuxiL7bG*209*f8!KAoj9?F@17}SUQTA%|{~9Po~9H_lBFL z@)KxHlr1Fne%MiXNj{=+w5zTK9FkjIaFvJg#=bITxf$Q2Yj!0->Cy3$n-L-cX1+~b zL8L>wgZv-sxjnpUPxfUFrglI3z`v-Qq<`f0=L3T82LF&89QA#KkFz#u@vCn=p@zx2 z(bq$|M)QwAbzkW8%(y6yIeo+h@JEZJG5hz6@B}ap{Q9xrRjcdMccS5?>PRsGut?iAOUVPzX^2+LS&|GRJylA2O{5@`M zQt>C5!9Qs&pQpbD-7eJUsn!u2Xd^hl`?$tn5L1&=T<$;SQeJ#pn2>jiZfV_$^i4jV znr34%Ad)R5df`=gvs&q?L>_a?aM$7{G`&Dw%E3Nkw}>2au*moea3PUX_?=3vr}dld z%Q+ekUgr3wldU_p)z(knjPzsNKf6>l&(*sA9{O?l+DPS#WdNeT{u!dioK|{u#xO*B z>q~W9j;ZpfpGL-$OQX^Q_=@^5ks}%7Ae5ovsD|C3&UvLPI+gskV^QA>JJ91%g-%za zE(f?`qh0+AT(cqyWxX`44r!lZ#Oy|T0V9+uj5hO2lSCFKA-BYaQAP4e{V{h}r4>X< zi$BL84hS@uL*3)eimr_($u#%F5_vH3a(x#|FjKg-GIMF#4D{AKV1qQ*X|$Tqu840? zS2SZsbHwrSWiTIM)LgwK)p~{r@;3}MLJRI&1;{jkrj%+=>g3W5Z~2uaP8KI!^Ckw^ z&{~gqjK#{d=OI4oBwg@oj7#_3`xGB7KJpse@Rs*5Z#5gc2j^1`#bKh01!qXLdOKc@ zthHed5ZW;BIGX>^O*iTL{r3EtsG0tW6T#dEnMTG~9r zdmISh!t1Tiy2|f{+C23Zl0zu;?+!l(`Rslrj@c_FtY1>(i@oVE$yCYna=xN@d~deq znR|ujOwi)aW?-?gzU2ycO%&3g+wq*QW-dyy*Nz9Tz@r-L&z7gHGo&axhjtFuCNfc1 zOuwMU4s%<`gw47i@-cwY;?sw$7fYlbNe!f4NdSNY$IooND7e@B&TNyf@{-F5i}|wcZ-D>!VyA-eZVLtT)twVJGqpXIqSkae%hVdP?!Tn$_YHr%{+gskU j&G^@2dD~t;)H>N-WT_Qsng&Ge|FR)%oDua_zUTi3Dvm_Q literal 0 HcmV?d00001 diff --git a/info/index.html b/info/index.html index 379b7ba6..3e4a638f 100644 --- a/info/index.html +++ b/info/index.html @@ -4,7 +4,7 @@ ONLYOFFICE™ - + -
+
+ ONLYOFFICE +
Please, wait...
@@ -183,11 +201,33 @@ } return xmlhttp; }; - function fillInfo(licenseInfo) { - var elem = document.getElementById('license-limit'); - var limit = licenseInfo.usersCount || licenseInfo.connections; - elem.innerText = limit; - return limit; + function fillInfo(licenseInfo, serverInfo) { + var elem = document.getElementById('build-type'); + elem.innerText = (licenseInfo.packageType == 0) ? 'Opensource' : ((licenseInfo.packageType == 1) ? 'Integration' : 'Developer'); + + elem = document.getElementById('build-date'); + var builddate = new Date(licenseInfo.buildDate); + elem.innerText = builddate.toLocaleDateString(); + + elem = document.getElementById('build-version'); + elem.innerText = serverInfo.buildVersion + '.' + serverInfo.buildNumber; + + elem = document.getElementById('limit-type'); + elem.innerText = (licenseInfo.usersCount>0) ? 'Concurrent users limit:' : 'Concurrent connections limit:'; + + elem = document.getElementById('lic-limit'); + elem.innerText = (licenseInfo.usersCount || licenseInfo.connections); + + elem = document.getElementById('lic-valid-type'); + elem.innerText = (licenseInfo.mode == 1) ? 'Valid:' : 'Updates available:'; + + var licdate = new Date(licenseInfo.endDate); + elem = document.getElementById('lic-valid'); + elem.innerText = licdate.toLocaleDateString(); + if (Date.now() > licdate) + elem.classList.add('critical'); + + return (licenseInfo.usersCount>0) ? 1000000 : licenseInfo.connections; } function fillConnections(info, limit) { for (var precision in info.connectionsStat) { @@ -217,7 +257,7 @@ if (xhrObj.status == 200) { document.getElementById('doc-server-ok').classList.remove("hidden"); var info = JSON.parse(xhrObj.responseText); - fillConnections(info, fillInfo(info.licenseInfo)); + fillConnections(info, fillInfo(info.licenseInfo, info.serverInfo)); } else { document.getElementById('doc-server-err').classList.remove("hidden"); } From 506fa592ef992072095d0a8031c375839e753950 Mon Sep 17 00:00:00 2001 From: Julia Radzhabova Date: Mon, 17 Sep 2018 13:56:07 +0300 Subject: [PATCH 37/39] Fix translations --- info/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/info/index.html b/info/index.html index 3e4a638f..54380863 100644 --- a/info/index.html +++ b/info/index.html @@ -203,7 +203,7 @@ }; function fillInfo(licenseInfo, serverInfo) { var elem = document.getElementById('build-type'); - elem.innerText = (licenseInfo.packageType == 0) ? 'Opensource' : ((licenseInfo.packageType == 1) ? 'Integration' : 'Developer'); + elem.innerText = (licenseInfo.packageType == 0) ? 'Open source' : ((licenseInfo.packageType == 1) ? 'Integration' : 'Developer'); elem = document.getElementById('build-date'); var builddate = new Date(licenseInfo.buildDate); From 5980d03d56292ed654b54dcaf8284232b74df1ad Mon Sep 17 00:00:00 2001 From: Sergey Konovalov Date: Fri, 14 Sep 2018 14:59:58 +0300 Subject: [PATCH 38/39] [bug] Forbid svg image pasting --- Common/config/default.json | 3 +-- DocService/sources/canvasservice.js | 15 ++++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Common/config/default.json b/Common/config/default.json index 2ab55e74..b7b2bfb9 100644 --- a/Common/config/default.json +++ b/Common/config/default.json @@ -78,8 +78,7 @@ "utils_common_fontdir": "null", "utils_fonts_search_patterns": "*.ttf;*.ttc;*.otf", "resource_expires": 31536000, - "limits_image_types_upload": "jpg;png;gif;bmp", - "limits_image_types_copy": "jpg;png;gif;bmp;svg" + "limits_image_types_upload": "jpg;png;gif;bmp" }, "sql": { "type": "postgres", diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index b76c65d7..7ec2d689 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -53,7 +53,6 @@ var pubsubRedis = require('./pubsubRedis'); var cfgTypesUpload = config_utils.get('limits_image_types_upload'); -var cfgTypesCopy = config_utils.get('limits_image_types_copy'); var cfgImageSize = config_server.get('limits_image_size'); var cfgImageDownloadTimeout = config_server.get('limits_image_download_timeout'); var cfgRedisPrefix = config.get('services.CoAuthoring.redis.prefix'); @@ -475,20 +474,14 @@ function isDisplayedImage(strName) { return res; } function* commandImgurls(conn, cmd, outputData) { - var supportedFormats; + var supportedFormats = cfgTypesUpload || 'jpg'; var urls; var docId = cmd.getDocId(); var errorCode = constants.NO_ERROR; var outputUrls = []; var isImgUrl = 'imgurl' == cmd.getCommand(); if (!conn.user.view && !conn.isCloseCoAuthoring) { - if (isImgUrl) { - urls = [cmd.getData()]; - supportedFormats = cfgTypesUpload || 'jpg'; - } else { - urls = cmd.getData(); - supportedFormats = cfgTypesCopy || 'jpg'; - } + urls = isImgUrl ? [cmd.getData()] : cmd.getData(); //todo Promise.all() var displayedImageMap = {};//to make one imageIndex for ole object urls var imageCount = 0; @@ -524,6 +517,10 @@ function* commandImgurls(conn, cmd, outputData) { formatStr = formatChecker.getStringFromFormat(format); if (formatStr && -1 !== supportedFormats.indexOf(formatStr)) { isAllow = true; + } else if (!isImgUrl && 'svg' === formatStr && isDisplayedImage(pathModule.basename(urlParsed.pathname)) > 0) { + //paste case + //todo refactoring + isAllow = true; } } if (!isAllow && urlParsed) { From 2a0102753fb30d72d4d5ce359488af8020482693 Mon Sep 17 00:00:00 2001 From: Alexey Golubev Date: Wed, 26 Sep 2018 12:41:08 +0300 Subject: [PATCH 39/39] Fix install opensource --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6bf3e7d2..87982bc3 100644 --- a/Makefile +++ b/Makefile @@ -171,7 +171,7 @@ install: mkdir -p /var/log/onlyoffice/documentserver mkdir -p /var/lib/onlyoffice/documentserver/App_Data - cp -fr -t /var/www/onlyoffice/documentserver build/* ../web-apps-pro/deploy/* + cp -fr -t /var/www/onlyoffice/documentserver build/* ../web-apps/deploy/* mkdir -p /etc/onlyoffice/documentserver mv /var/www/onlyoffice/documentserver/server/Common/config/* /etc/onlyoffice/documentserver