diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index 7d45100a..855e5707 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -600,13 +600,10 @@ function sendReleaseLock(ctx, conn, userLocks) { } function modifyConnectionForPassword(ctx, conn, isEnterCorrectPassword) { return co(function*() { - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); if (isEnterCorrectPassword) { conn.isEnterCorrectPassword = true; - if (tenTokenEnableBrowser) { - let sessionToken = yield fillJwtByConnection(ctx, conn); - sendDataRefreshToken(ctx, conn, sessionToken); - } + let sessionToken = yield fillJwtByConnection(ctx, conn); + sendDataRefreshToken(ctx, conn, sessionToken); } }); } @@ -1100,7 +1097,7 @@ async function saveRelativeFromChanges(ctx, conn, responseKey, data) { let docId = data.docId; let token = data.token; let forceSaveRes; - if (tenTokenEnableBrowser) { + if (tenTokenEnableBrowser || token) { docId = null; let checkJwtRes = await checkJwt(ctx, token, commonDefines.c_oAscSecretType.Browser); if (checkJwtRes.decoded) { @@ -1685,9 +1682,9 @@ exports.install = function(server, callbackFunction) { const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); let handshake = socket.handshake; - if (tenTokenEnableBrowser) { + const token = handshake?.auth?.session || handshake?.auth?.token; + if (tenTokenEnableBrowser || token) { let secretType = !!(handshake?.auth?.session) ? commonDefines.c_oAscSecretType.Session : commonDefines.c_oAscSecretType.Browser; - let token = handshake?.auth?.session || handshake?.auth?.token; checkJwtRes = yield checkJwt(ctx, token, secretType); if (!checkJwtRes.decoded) { res = new Error("not authorized"); @@ -1879,7 +1876,6 @@ exports.install = function(server, callbackFunction) { * @param reason - the reason of the disconnection (either client or server-side) */ function* closeDocument(ctx, conn, reason) { - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); const tenForgottenFiles = ctx.getCfg('services.CoAuthoring.server.forgottenfiles', cfgForgottenFiles); ctx.logger.info("Connection closed or timed out: reason = %s", reason); @@ -1916,10 +1912,8 @@ exports.install = function(server, callbackFunction) { modifyConnectionEditorToView(ctx, conn); conn.isCloseCoAuthoring = true; yield addPresence(ctx, conn, true); - if (tenTokenEnableBrowser) { - let sessionToken = yield fillJwtByConnection(ctx, conn); - sendDataRefreshToken(ctx, conn, sessionToken); - } + let sessionToken = yield fillJwtByConnection(ctx, conn); + sendDataRefreshToken(ctx, conn, sessionToken); } } @@ -2135,8 +2129,6 @@ exports.install = function(server, callbackFunction) { } function* sendFileErrorAuth(ctx, conn, sessionId, errorId, code, opt_notWarn) { - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); - conn.sessionId = sessionId;//restore old //Kill previous connections connections = _.reject(connections, function(el) { @@ -2150,10 +2142,8 @@ exports.install = function(server, callbackFunction) { // We put it in an array, because we need to send data to open/save the document connections.push(conn); yield addPresence(ctx, conn, true); - if (tenTokenEnableBrowser) { - let sessionToken = yield fillJwtByConnection(ctx, conn); - sendDataRefreshToken(ctx, conn, sessionToken); - } + let sessionToken = yield fillJwtByConnection(ctx, conn); + sendDataRefreshToken(ctx, conn, sessionToken); sendFileError(ctx, conn, errorId, code, opt_notWarn); } } @@ -2554,9 +2544,10 @@ exports.install = function(server, callbackFunction) { let [licenseInfo] = yield tenantManager.getTenantLicense(ctx); let isDecoded = false; //check jwt - if (tenTokenEnableBrowser) { + const token = data.jwtSession || data.jwtOpen; + if (tenTokenEnableBrowser || token) { let secretType = !!data.jwtSession ? commonDefines.c_oAscSecretType.Session : commonDefines.c_oAscSecretType.Browser; - const checkJwtRes = yield checkJwt(ctx, data.jwtSession || data.jwtOpen, secretType); + const checkJwtRes = yield checkJwt(ctx, token, secretType); if (checkJwtRes.decoded) { isDecoded = true; let decoded = checkJwtRes.decoded; @@ -3086,7 +3077,6 @@ exports.install = function(server, callbackFunction) { } while (connections.length > 0 && changes && tenMaxRequestChanges === changes.length); } function* sendAuthInfo(ctx, conn, bIsRestore, participantsMap, opt_hasForgotten, opt_openedAt) { - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); const tenImageSize = ctx.getCfg('services.CoAuthoring.server.limits_image_size', cfgImageSize); const tenTypesUpload = ctx.getCfg('services.CoAuthoring.utils.limits_image_types_upload', cfgTypesUpload); @@ -3102,7 +3092,7 @@ exports.install = function(server, callbackFunction) { let allMessages = yield editorData.getMessages(ctx, docId); allMessages = allMessages.length > 0 ? allMessages : undefined;//todo client side let sessionToken; - if (tenTokenEnableBrowser && !bIsRestore) { + if (!bIsRestore) { sessionToken = yield fillJwtByConnection(ctx, conn); } let tenEditor = getEditorConfig(ctx); @@ -3621,7 +3611,6 @@ exports.install = function(server, callbackFunction) { ctx.initFromPubSub(data); yield ctx.initTenantCache(); ctx.logger.debug('pubsub message start:%s', msg); - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); var participants; var participant; @@ -3795,10 +3784,8 @@ exports.install = function(server, callbackFunction) { ctx.logger.debug('changeConnectionInfo: userId = %s', data.useridoriginal); participant.user.username = cmd.getUserName(); yield addPresence(ctx, participant, false); - if (tenTokenEnableBrowser) { - let sessionToken = yield fillJwtByConnection(ctx, participant); - sendDataRefreshToken(ctx, participant, sessionToken); - } + let sessionToken = yield fillJwtByConnection(ctx, participant); + sendDataRefreshToken(ctx, participant, sessionToken); } } if (hasChanges) { diff --git a/DocService/sources/ai/aiProxyHandler.js b/DocService/sources/ai/aiProxyHandler.js index f6da8c84..e9b88534 100644 --- a/DocService/sources/ai/aiProxyHandler.js +++ b/DocService/sources/ai/aiProxyHandler.js @@ -162,7 +162,6 @@ async function proxyRequest(req, res) { try { ctx.logger.info('Start proxyRequest'); await ctx.initTenantCache(); - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); const tenAiApiTimeout = ctx.getCfg('aiSettings.timeout', cfgAiApiTimeout); const tenAiApi = ctx.getCfg('aiSettings', cfgAiSettings); const tenAiApiProxy = ctx.getCfg('aiSettings.proxy', cfgAiApiProxy); @@ -176,26 +175,24 @@ async function proxyRequest(req, res) { let userId = ''; let userName = ''; let userCustomerId = ''; - if (tenTokenEnableBrowser) { - let checkJwtRes = await docsCoServer.checkJwtHeader(ctx, req, 'Authorization', 'Bearer ', commonDefines.c_oAscSecretType.Session); - if (!checkJwtRes || checkJwtRes.err) { - ctx.logger.error('proxyRequest: checkJwtHeader error: %s', checkJwtRes?.err); - res.status(403).json({ - "error": { - "message": "proxyRequest: checkJwtHeader error", - "code": "403" - } - }); - return; - } else { - docId = checkJwtRes?.decoded?.document?.key; - userId = checkJwtRes?.decoded?.editorConfig?.user?.id; - userName = checkJwtRes?.decoded?.editorConfig?.user?.name; - userCustomerId = checkJwtRes?.decoded?.editorConfig?.user?.customerId; - - ctx.setDocId(docId); - ctx.setUserId(userId); - } + let checkJwtRes = await docsCoServer.checkJwtHeader(ctx, req, 'Authorization', 'Bearer ', commonDefines.c_oAscSecretType.Session); + if (!checkJwtRes || checkJwtRes.err) { + ctx.logger.error('proxyRequest: checkJwtHeader error: %s', checkJwtRes?.err); + res.status(403).json({ + "error": { + "message": "proxyRequest: checkJwtHeader error", + "code": "403" + } + }); + return; + } else { + docId = checkJwtRes?.decoded?.document?.key; + userId = checkJwtRes?.decoded?.editorConfig?.user?.id; + userName = checkJwtRes?.decoded?.editorConfig?.user?.name; + userCustomerId = checkJwtRes?.decoded?.editorConfig?.user?.customerId; + + ctx.setDocId(docId); + ctx.setUserId(userId); } if (!tenAiApi?.providers) { diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index 6f41f479..71c57e7f 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -695,7 +695,7 @@ function* commandImgurls(ctx, conn, cmd, outputData) { let authorizations = []; let isInJwtToken = false; let token = cmd.getTokenDownload(); - if (tenTokenEnableBrowser && token) { + if (tenTokenEnableBrowser && token) {// allow requests without token let checkJwtRes = yield docsCoServer.checkJwt(ctx, token, commonDefines.c_oAscSecretType.Browser); if (checkJwtRes.decoded) { //todo multiple url case @@ -1447,7 +1447,7 @@ exports.downloadAs = function(req, res) { ctx.logger.debug('Start downloadAs: %s', strCmd); const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); - if (tenTokenEnableBrowser) { + if (tenTokenEnableBrowser || cmd.getTokenDownload() || cmd.getTokenSession()) { var isValidJwt = false; if (cmd.getTokenDownload()) { let checkJwtRes = yield docsCoServer.checkJwt(ctx, cmd.getTokenDownload(), commonDefines.c_oAscSecretType.Browser); @@ -1535,28 +1535,25 @@ exports.saveFile = function(req, res) { docId = cmd.getDocId(); ctx.setDocId(docId); ctx.logger.debug('Start saveFile'); - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); - if (tenTokenEnableBrowser) { - let isValidJwt = false; - let checkJwtRes = yield docsCoServer.checkJwt(ctx, cmd.getTokenSession(), commonDefines.c_oAscSecretType.Session); - if (checkJwtRes.decoded) { - let doc = checkJwtRes.decoded.document; - 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 { - ctx.logger.warn('Error saveFile jwt: %s', 'access deny'); - } + let isValidJwt = false; + let checkJwtRes = yield docsCoServer.checkJwt(ctx, cmd.getTokenSession(), commonDefines.c_oAscSecretType.Session); + if (checkJwtRes.decoded) { + let doc = checkJwtRes.decoded.document; + 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 { - ctx.logger.warn('Error saveFile jwt: %s', checkJwtRes.description); - } - if (!isValidJwt) { - res.sendStatus(403); - return; + ctx.logger.warn('Error saveFile jwt: %s', 'access deny'); } + } else { + ctx.logger.warn('Error saveFile jwt: %s', checkJwtRes.description); + } + if (!isValidJwt) { + res.sendStatus(403); + return; } ctx.setDocId(docId); cmd.setStatusInfo(constants.NO_ERROR); @@ -1582,16 +1579,12 @@ exports.saveFile = function(req, res) { }; function getPrintFileUrl(ctx, docId, baseUrl, filename) { return co(function*() { - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); const tenTokenSessionAlgorithm = ctx.getCfg('services.CoAuthoring.token.session.algorithm', cfgTokenSessionAlgorithm); const tenTokenSessionExpires = ms(ctx.getCfg('services.CoAuthoring.token.session.expires', cfgTokenSessionExpires)); baseUrl = utils.checkBaseUrl(ctx, baseUrl); - let token = ''; - if (tenTokenEnableBrowser) { - let payload = {document: {key: docId}}; - token = yield docsCoServer.signToken(ctx, payload, tenTokenSessionAlgorithm, tenTokenSessionExpires / 1000, commonDefines.c_oAscSecretType.Session); - } + let payload = {document: {key: docId}}; + let token = yield docsCoServer.signToken(ctx, payload, tenTokenSessionAlgorithm, tenTokenSessionExpires / 1000, commonDefines.c_oAscSecretType.Session); //while save printed file Chrome's extension seems to rely on the resource name set in the URI https://stackoverflow.com/a/53593453 //replace '/' with %2f before encodeURIComponent becase nginx determine %2f as '/' and get wrong system path let userFriendlyName = encodeURIComponent(filename.replace(/\//g, "%2f")); @@ -1626,22 +1619,19 @@ exports.printFile = function(req, res) { docId = req.params.docid; ctx.setDocId(docId); ctx.logger.info('Start printFile'); - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); - if (tenTokenEnableBrowser) { - let checkJwtRes = yield docsCoServer.checkJwt(ctx, token, commonDefines.c_oAscSecretType.Session); - if (checkJwtRes.decoded) { - let docIdBase = checkJwtRes.decoded.document.key; - if (!docId.startsWith(docIdBase)) { - ctx.logger.warn('Error printFile jwt: description = %s', 'access deny'); - res.sendStatus(403); - return; - } - } else { - ctx.logger.warn('Error printFile jwt: description = %s', checkJwtRes.description); + let checkJwtRes = yield docsCoServer.checkJwt(ctx, token, commonDefines.c_oAscSecretType.Session); + if (checkJwtRes.decoded) { + let docIdBase = checkJwtRes.decoded.document.key; + if (!docId.startsWith(docIdBase)) { + ctx.logger.warn('Error printFile jwt: description = %s', 'access deny'); res.sendStatus(403); return; } + } else { + ctx.logger.warn('Error printFile jwt: description = %s', checkJwtRes.description); + res.sendStatus(403); + return; } ctx.setDocId(docId); let streamObj = yield storage.createReadStream(ctx, `${docId}/${constants.OUTPUT_NAME}.pdf`); diff --git a/DocService/sources/converterservice.js b/DocService/sources/converterservice.js index a1ca7f10..21fa2f17 100644 --- a/DocService/sources/converterservice.js +++ b/DocService/sources/converterservice.js @@ -685,7 +685,7 @@ function getConverterHtmlHandler(req, res) { return; } let token = req.query['token']; - if (tenTokenEnableBrowser) { + if (tenTokenEnableBrowser || token) { let checkJwtRes = yield docsCoServer.checkJwt(ctx, token, commonDefines.c_oAscSecretType.Browser); if (checkJwtRes.decoded) { docId = checkJwtRes.decoded.docId; diff --git a/DocService/sources/fileuploaderservice.js b/DocService/sources/fileuploaderservice.js index 71cc11bb..f613842e 100644 --- a/DocService/sources/fileuploaderservice.js +++ b/DocService/sources/fileuploaderservice.js @@ -50,10 +50,6 @@ const cfgTokenEnableBrowser = config.get('services.CoAuthoring.token.enable.brow const PATTERN_ENCRYPTED = 'ENCRYPTED;'; -function* checkJwtUpload(ctx, errorName, token){ - let checkJwtRes = yield docsCoServer.checkJwt(ctx, token, commonDefines.c_oAscSecretType.Session); - return checkJwtUploadTransformRes(ctx, errorName, checkJwtRes); -} function checkJwtUploadTransformRes(ctx, errorName, checkJwtRes){ var res = {err: true, docId: null, userid: null, encrypted: null}; if (checkJwtRes.decoded) { @@ -90,23 +86,20 @@ exports.uploadImageFile = function(req, res) { ctx.logger.debug('Start uploadImageFile'); const tenImageSize = ctx.getCfg('services.CoAuthoring.server.limits_image_size', cfgImageSize); const tenTypesUpload = ctx.getCfg('services.CoAuthoring.utils.limits_image_types_upload', cfgTypesUpload); - const tenTokenEnableBrowser = ctx.getCfg('services.CoAuthoring.token.enable.browser', cfgTokenEnableBrowser); - if (tenTokenEnableBrowser) { - let checkJwtRes = yield docsCoServer.checkJwtHeader(ctx, req, 'Authorization', 'Bearer ', commonDefines.c_oAscSecretType.Session); - if (!checkJwtRes) { - //todo remove compatibility with previous versions - checkJwtRes = yield docsCoServer.checkJwt(ctx, req.query['token'], commonDefines.c_oAscSecretType.Session); - } - let transformedRes = checkJwtUploadTransformRes(ctx, 'uploadImageFile', checkJwtRes); - if (!transformedRes.err) { - docId = transformedRes.docId || docId; - encrypted = transformedRes.encrypted; - ctx.setDocId(docId); - ctx.setUserId(transformedRes.userid); - } else { - httpStatus = 403; - } + let checkJwtRes = yield docsCoServer.checkJwtHeader(ctx, req, 'Authorization', 'Bearer ', commonDefines.c_oAscSecretType.Session); + if (!checkJwtRes) { + //todo remove compatibility with previous versions + checkJwtRes = yield docsCoServer.checkJwt(ctx, req.query['token'], commonDefines.c_oAscSecretType.Session); + } + let transformedRes = checkJwtUploadTransformRes(ctx, 'uploadImageFile', checkJwtRes); + if (!transformedRes.err) { + docId = transformedRes.docId || docId; + encrypted = transformedRes.encrypted; + ctx.setDocId(docId); + ctx.setUserId(transformedRes.userid); + } else { + httpStatus = 403; } if (200 === httpStatus && docId && req.body && Buffer.isBuffer(req.body)) { diff --git a/DocService/sources/wopiClient.js b/DocService/sources/wopiClient.js index ff091bfb..4da0d510 100644 --- a/DocService/sources/wopiClient.js +++ b/DocService/sources/wopiClient.js @@ -594,7 +594,6 @@ function getEditorHtml(req, res) { try { ctx.initFromRequest(req); yield ctx.initTenantCache(); - 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); const tenWopiFileInfoBlockList = ctx.getCfg('wopi.fileInfoBlockList', cfgWopiFileInfoBlockList); @@ -662,11 +661,9 @@ function getEditorHtml(req, res) { delete params.fileInfo[item]; }); - if (tenTokenEnableBrowser) { - let options = {algorithm: tenTokenOutboxAlgorithm, expiresIn: tenTokenOutboxExpires}; - let secret = yield tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Browser); - params.token = jwt.sign(params, secret, options); - } + let options = {algorithm: tenTokenOutboxAlgorithm, expiresIn: tenTokenOutboxExpires}; + let secret = yield tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Browser); + params.token = jwt.sign(params, secret, options); } catch (err) { ctx.logger.error('wopiEditor error: %s', err.stack); params.fileInfo = {}; @@ -689,7 +686,6 @@ function getConverterHtml(req, res) { try { ctx.initFromRequest(req); yield ctx.initTenantCache(); - 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); const tenWopiHost = ctx.getCfg('wopi.host', cfgWopiHost); @@ -723,14 +719,12 @@ function getConverterHtml(req, res) { params.statusHandler = `${baseUrl}/hosting/wopi/convert-and-edit-handler`; params.statusHandler += `?${constants.SHARD_KEY_WOPI_NAME}=${encodeURIComponent(wopiSrc)}&access_token=${encodeURIComponent(access_token)}`; params.statusHandler += `&targetext=${encodeURIComponent(targetext)}&docId=${encodeURIComponent(docId)}`; - if (tenTokenEnableBrowser) { - let tokenData = {docId: docId}; - let options = {algorithm: tenTokenOutboxAlgorithm, expiresIn: tenTokenOutboxExpires}; - let secret = yield tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Browser); - let token = jwt.sign(tokenData, secret, options); + let tokenData = {docId: docId}; + let options = {algorithm: tenTokenOutboxAlgorithm, expiresIn: tenTokenOutboxExpires}; + let secret = yield tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Browser); + let token = jwt.sign(tokenData, secret, options); - params.statusHandler += `&token=${encodeURIComponent(token)}`; - } + params.statusHandler += `&token=${encodeURIComponent(token)}`; } } catch (err) { ctx.logger.error('convert-and-edit error:%s', err.stack); @@ -894,7 +888,6 @@ async function refreshFile(ctx, wopiParams, baseUrl) { if (!userAuth) { return; } - 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); @@ -906,11 +899,9 @@ async function refreshFile(ctx, wopiParams, baseUrl) { if (!prepareResult) { return; } - if (tenTokenEnableBrowser) { - let options = {algorithm: tenTokenOutboxAlgorithm, expiresIn: tenTokenOutboxExpires}; - let secret = await tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Browser); - res.token = jwt.sign(res, secret, options); - } + let options = {algorithm: tenTokenOutboxAlgorithm, expiresIn: tenTokenOutboxExpires}; + let secret = await tenantManager.getTenantSecret(ctx, commonDefines.c_oAscSecretType.Browser); + res.token = jwt.sign(res, secret, options); } catch (err) { res = undefined; ctx.logger.error('wopi error RefreshFile:%s', err.stack);