diff --git a/Common/sources/constants.js b/Common/sources/constants.js index 3299ca82c..ffaabaf78 100644 --- a/Common/sources/constants.js +++ b/Common/sources/constants.js @@ -50,7 +50,8 @@ exports.VIEWER_ONLY = /^(?:(pdf|djvu|xps|oxps))$/; exports.DEFAULT_DOC_ID = 'docId'; exports.DEFAULT_USER_ID = 'userId'; exports.ALLOWED_PROTO = /^https?$/i; -exports.SHARED_KEY_NAME = 'WOPISrc'; +exports.SHARD_KEY_WOPI_NAME = 'WOPISrc'; +exports.SHARD_KEY_API_NAME = 'shardkey'; exports.RIGHTS = { None : 0, diff --git a/Common/sources/operationContext.js b/Common/sources/operationContext.js index 0eeb11a5f..b9f9aaca7 100644 --- a/Common/sources/operationContext.js +++ b/Common/sources/operationContext.js @@ -41,11 +41,12 @@ function Context(){ this.logger = logger.getLogger('nodeJS'); this.initDefault(); } -Context.prototype.init = function(tenant, docId, userId, opt_shardKey) { +Context.prototype.init = function(tenant, docId, userId, opt_shardKey, opt_WopiSrc) { this.setTenant(tenant); this.setDocId(docId); this.setUserId(userId); this.setShardKey(opt_shardKey); + this.setWopiSrc(opt_WopiSrc); this.config = null; this.secret = null; @@ -65,21 +66,23 @@ Context.prototype.initFromConnection = function(conn) { } } let userId = conn.user?.id; - let shardKey = utils.getShardByConnection(this, conn); - this.init(tenant, docId || this.docId, userId || this.userId, shardKey); + let shardKey = utils.getShardKeyByConnection(this, conn); + let wopiSrc = utils.getWopiSrcByConnection(this, conn); + this.init(tenant, docId || this.docId, userId || this.userId, shardKey, wopiSrc); }; Context.prototype.initFromRequest = function(req) { let tenant = tenantManager.getTenantByRequest(this, req); let shardKey = utils.getShardKeyByRequest(this, req); - this.init(tenant, this.docId, this.userId, shardKey); + let wopiSrc = utils.getWopiSrcByRequest(this, req); + this.init(tenant, this.docId, this.userId, shardKey, wopiSrc); }; Context.prototype.initFromTaskQueueData = function(task) { let ctx = task.getCtx(); - this.init(ctx.tenant, ctx.docId, ctx.userId, ctx.shardKey); + this.init(ctx.tenant, ctx.docId, ctx.userId, ctx.shardKey, ctx.wopiSrc); }; Context.prototype.initFromPubSub = function(data) { let ctx = data.ctx; - this.init(ctx.tenant, ctx.docId, ctx.userId, ctx.shardKey); + this.init(ctx.tenant, ctx.docId, ctx.userId, ctx.shardKey, ctx.wopiSrc); }; Context.prototype.initTenantCache = async function() { this.config = await tenantManager.getTenantConfig(this); @@ -101,12 +104,16 @@ Context.prototype.setUserId = function(userId) { Context.prototype.setShardKey = function(shardKey) { this.shardKey = shardKey; }; +Context.prototype.setWopiSrc = function(wopiSrc) { + this.wopiSrc = wopiSrc; +}; Context.prototype.toJSON = function() { return { tenant: this.tenant, docId: this.docId, userId: this.userId, - shardKey: this.shardKey + shardKey: this.shardKey, + wopiSrc: this.wopiSrc } }; Context.prototype.getCfg = function(property, defaultValue) { diff --git a/Common/sources/storage-fs.js b/Common/sources/storage-fs.js index 1b9670e0c..b8e404a2d 100644 --- a/Common/sources/storage-fs.js +++ b/Common/sources/storage-fs.js @@ -142,7 +142,10 @@ async function getSignedUrl(ctx, storageCfg, baseUrl, strPath, urlType, optFilen url += '?md5=' + encodeURIComponent(md5); url += '&expires=' + encodeURIComponent(expires); if (ctx.shardKey) { - url += `&${constants.SHARED_KEY_NAME}=${encodeURIComponent(ctx.shardKey)}`; + url += `&${constants.SHARD_KEY_API_NAME}=${encodeURIComponent(ctx.shardKey)}`; + } + if (ctx.wopiSrc) { + url += `&${constants.SHARD_KEY_WOPI_NAME}=${encodeURIComponent(ctx.wopiSrc)}`; } url += '&filename=' + userFriendlyName; return url; diff --git a/Common/sources/utils.js b/Common/sources/utils.js index 5410cd9d4..52ed83cb3 100644 --- a/Common/sources/utils.js +++ b/Common/sources/utils.js @@ -787,14 +787,22 @@ function getDomainByRequest(ctx, req) { } exports.getDomainByConnection = getDomainByConnection; exports.getDomainByRequest = getDomainByRequest; -function getShardByConnection(ctx, conn) { - return conn?.handshake?.query?.[constants.SHARED_KEY_NAME]; +function getShardKeyByConnection(ctx, conn) { + return conn?.handshake?.query?.[constants.SHARD_KEY_API_NAME]; +} +function getWopiSrcByConnection(ctx, conn) { + return conn?.handshake?.query?.[constants.SHARD_KEY_WOPI_NAME]; } function getShardKeyByRequest(ctx, req) { - return req.query[constants.SHARED_KEY_NAME]; + return req.query?.[constants.SHARD_KEY_API_NAME]; +} +function getWopiSrcByRequest(ctx, req) { + return req.query?.[constants.SHARD_KEY_WOPI_NAME]; } -exports.getShardByConnection = getShardByConnection; +exports.getShardKeyByConnection = getShardKeyByConnection; +exports.getWopiSrcByConnection = getWopiSrcByConnection; exports.getShardKeyByRequest = getShardKeyByRequest; +exports.getWopiSrcByRequest = getWopiSrcByRequest; function stream2Buffer(stream) { return new Promise(function(resolve, reject) { if (!stream.readable) { diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index fcd235d39..316547ae8 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -2522,7 +2522,7 @@ exports.install = function(server, callbackFunction) { upsertRes = yield canvasService.commandOpenStartPromise(ctx, docId, utils.getBaseUrlByConnection(ctx, conn), data.documentCallbackUrl, format); curIndexUser = upsertRes.insertId; //todo update additional in commandOpenStartPromise - if ((upsertRes.isInsert || (wopiParams && 2 === curIndexUser)) && (undefined !== data.timezoneOffset || ctx.shardKey)) { + if ((upsertRes.isInsert || (wopiParams && 2 === curIndexUser)) && (undefined !== data.timezoneOffset || ctx.shardKey || ctx.wopiSrc)) { //todo insert in commandOpenStartPromise. insert here for database compatibility if (false === canvasService.hasAdditionalCol) { let selectRes = yield taskResult.select(ctx, docId); @@ -2539,6 +2539,9 @@ exports.install = function(server, callbackFunction) { if (ctx.shardKey) { task.additional += sqlBase.DocumentAdditional.prototype.setShardKey(ctx.shardKey); } + if (ctx.wopiSrc) { + task.additional += sqlBase.DocumentAdditional.prototype.setWopiSrc(ctx.wopiSrc); + } yield taskResult.update(ctx, task); } else { ctx.logger.warn('auth unknown column "additional"'); diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index bd1ce232f..dff01cd98 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -628,6 +628,7 @@ let commandSfctByCmd = co.wrap(function*(ctx, cmd, opt_priority, opt_expiration, } if (opt_initShardKey) { ctx.setShardKey(sqlBase.DocumentAdditional.prototype.getShardKey(row.additional)); + ctx.setWopiSrc(sqlBase.DocumentAdditional.prototype.getWopiSrc(row.additional)); } yield* addRandomKeyTaskCmd(ctx, cmd); addPasswordToCmd(ctx, cmd, row.password); @@ -1525,7 +1526,10 @@ function getPrintFileUrl(ctx, docId, baseUrl, filename) { let userFriendlyName = encodeURIComponent(filename.replace(/\//g, "%2f")); let res = `${baseUrl}/printfile/${encodeURIComponent(docId)}/${userFriendlyName}?token=${encodeURIComponent(token)}`; if (ctx.shardKey) { - res += `&${constants.SHARED_KEY_NAME}=${encodeURIComponent(ctx.shardKey)}`; + res += `&${constants.SHARD_KEY_API_NAME}=${encodeURIComponent(ctx.shardKey)}`; + } + if (ctx.wopiSrc) { + res += `&${constants.SHARD_KEY_WOPI_NAME}=${encodeURIComponent(ctx.wopiSrc)}`; } res += `&filename=${userFriendlyName}`; return res; @@ -1727,6 +1731,7 @@ exports.saveFromChanges = function(ctx, docId, statusInfo, optFormat, opt_userId } if (opt_initShardKey) { ctx.setShardKey(sqlBase.DocumentAdditional.prototype.getShardKey(row.additional)); + ctx.setWopiSrc(sqlBase.DocumentAdditional.prototype.getWopiSrc(row.additional)); } var cmd = new commonDefines.InputCommand(); cmd.setCommand('sfc'); diff --git a/DocService/sources/databaseConnectors/connectorUtilities.js b/DocService/sources/databaseConnectors/connectorUtilities.js index b7a988c4c..a1b5c1a7c 100644 --- a/DocService/sources/databaseConnectors/connectorUtilities.js +++ b/DocService/sources/databaseConnectors/connectorUtilities.js @@ -168,6 +168,23 @@ DocumentAdditional.prototype.getShardKey = function(str) { return res; }; +DocumentAdditional.prototype.setWopiSrc = function(wopiSrc) { + let additional = new DocumentAdditional(); + additional.data.push({wopiSrc}); + return additional.toSQLInsert(); +}; +DocumentAdditional.prototype.getWopiSrc = function(str) { + let res; + let val = new DocumentAdditional(); + val.fromString(str); + val.data.forEach((elem) => { + if (elem.wopiSrc) { + res = elem.wopiSrc; + } + }); + return res; +}; + module.exports = { UserCallback, DocumentPassword, diff --git a/DocService/sources/gc.js b/DocService/sources/gc.js index 6fbaf357f..6c734a2f1 100644 --- a/DocService/sources/gc.js +++ b/DocService/sources/gc.js @@ -78,7 +78,8 @@ var checkFileExpire = function(expireSeconds) { let tenant = expired[i].tenant; let docId = expired[i].id; let shardKey = sqlBase.DocumentAdditional.prototype.getShardKey(expired[i].additional); - ctx.init(tenant, docId, ctx.userId, shardKey); + let wopiSrc = sqlBase.DocumentAdditional.prototype.getWopiSrc(expired[i].additional); + ctx.init(tenant, docId, ctx.userId, shardKey, wopiSrc); yield ctx.initTenantCache(); //todo tenant //check that no one is in the document