Files
server/DocService/sources/taskresult.js
2023-02-26 15:31:59 +03:00

346 lines
12 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
'use strict';
const crypto = require('crypto');
var sqlBase = require('./baseConnector');
var utils = require('./../../Common/sources/utils');
var constants = require('./../../Common/sources/constants');
var commonDefines = require('./../../Common/sources/commondefines');
var tenantManager = require('./../../Common/sources/tenantManager');
var config = require('config');
const cfgTableResult = config.get('services.CoAuthoring.sql.tableResult');
const cfgTableChanges = config.get('services.CoAuthoring.sql.tableChanges');
let addSqlParam = sqlBase.baseConnector.addSqlParameter;
let concatParams = sqlBase.baseConnector.concatParams;
var RANDOM_KEY_MAX = 10000;
function TaskResultData() {
this.tenant = null;
this.key = null;
this.status = null;
this.statusInfo = null;
this.lastOpenDate = null;
this.creationDate = null;
this.userIndex = null;
this.changeId = null;
this.callback = null;
this.baseurl = null;
this.password = null;
this.additional = null;
this.innerPasswordChange = null;//not a DB field
}
TaskResultData.prototype.completeDefaults = function() {
if (!this.tenant) {
this.tenant = tenantManager.getDefautTenant();
}
if (!this.key) {
this.key = '';
}
if (!this.status) {
this.status = commonDefines.FileStatus.None;
}
if (!this.statusInfo) {
this.statusInfo = constants.NO_ERROR;
}
if (!this.lastOpenDate) {
this.lastOpenDate = new Date();
}
if (!this.creationDate) {
this.creationDate = new Date();
}
if (!this.userIndex) {
this.userIndex = 1;
}
if (!this.changeId) {
this.changeId = 0;
}
if (!this.callback) {
this.callback = '';
}
if (!this.baseurl) {
this.baseurl = '';
}
};
function upsert(ctx, task, opt_updateUserIndex) {
return sqlBase.baseConnector.upsert(ctx, task, opt_updateUserIndex);
}
function select(ctx, docId) {
return new Promise(function(resolve, reject) {
let values = [];
let p1 = addSqlParam(ctx.tenant, values);
let p2 = addSqlParam(docId, values);
let sqlCommand = `SELECT * FROM ${cfgTableResult} WHERE tenant=${p1} AND id=${p2};`;
sqlBase.baseConnector.sqlQuery(ctx, sqlCommand, function(error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
}, undefined, undefined, values);
});
}
function toUpdateArray(task, updateTime, isMask, values, setPassword) {
var res = [];
if (null != task.status) {
let sqlParam = addSqlParam(task.status, values);
res.push(`status=${sqlParam}`);
}
if (null != task.statusInfo) {
let sqlParam = addSqlParam(task.statusInfo, values);
res.push(`status_info=${sqlParam}` );
}
if (updateTime) {
let sqlParam = addSqlParam(new Date(), values);
res.push(`last_open_date=${sqlParam}`);
}
if (null != task.indexUser) {
let sqlParam = addSqlParam(task.indexUser, values);
res.push(`user_index=${sqlParam}`);
}
if (null != task.changeId) {
let sqlParam = addSqlParam(task.changeId, values);
res.push(`change_id=${sqlParam}`);
}
if (null != task.callback && !isMask) {
var userCallback = new sqlBase.UserCallback();
userCallback.fromValues(task.indexUser, task.callback);
let sqlParam = addSqlParam(userCallback.toSQLInsert(), values);
res.push(`callback=${concatParams('callback', sqlParam)}`);
}
if (null != task.baseurl) {
let sqlParam = addSqlParam(task.baseurl, values);
res.push(`baseurl=${sqlParam}`);
}
if (setPassword) {
let sqlParam = addSqlParam(task.password, values);
res.push(`password=${sqlParam}`);
} else if (null != task.password || setPassword) {
var documentPassword = new sqlBase.DocumentPassword();
documentPassword.fromValues(task.password, task.innerPasswordChange);
let sqlParam = addSqlParam(documentPassword.toSQLInsert(), values);
res.push(`password=${concatParams('password', sqlParam)}`);
}
if (null != task.additional) {
let sqlParam = addSqlParam(task.additional, values);
res.push(`additional=${concatParams('additional', sqlParam)}`);
}
return res;
}
function update(ctx, task, setPassword) {
return new Promise(function(resolve, reject) {
let values = [];
let updateElems = toUpdateArray(task, true, false, values, setPassword);
let sqlSet = updateElems.join(', ');
let p1 = addSqlParam(task.tenant, values);
let p2 = addSqlParam(task.key, values);
let sqlCommand = `UPDATE ${cfgTableResult} SET ${sqlSet} WHERE tenant=${p1} AND id=${p2};`;
sqlBase.baseConnector.sqlQuery(ctx, sqlCommand, function(error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
}, undefined, undefined, values);
});
}
function updateIf(ctx, task, mask) {
return new Promise(function(resolve, reject) {
let values = [];
let commandArg = toUpdateArray(task, true, false, values, false);
let commandArgMask = toUpdateArray(mask, false, true, values, false);
commandArgMask.push('tenant=' + addSqlParam(mask.tenant, values));
commandArgMask.push('id=' + addSqlParam(mask.key, values));
let sqlSet = commandArg.join(', ');
let sqlWhere = commandArgMask.join(' AND ');
let sqlCommand = `UPDATE ${cfgTableResult} SET ${sqlSet} WHERE ${sqlWhere};`;
sqlBase.baseConnector.sqlQuery(ctx, sqlCommand, function(error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
}, undefined, undefined, values);
});
}
function restoreInitialPassword(ctx, docId) {
return select(ctx, docId).then(function(selectRes) {
if (selectRes.length > 0) {
var row = selectRes[0];
let docPassword = sqlBase.DocumentPassword.prototype.getDocPassword(ctx, row.password);
var updateTask = new TaskResultData();
updateTask.tenant = ctx.tenant;
updateTask.key = docId;
if (docPassword.initial) {
var documentPassword = new sqlBase.DocumentPassword();
documentPassword.fromValues(docPassword.initial);
updateTask.password = documentPassword.toSQLInsert();
return update(ctx, updateTask, true);
} else if (docPassword.current) {
updateTask.password = null;
return update(ctx, updateTask, true);
}
}
});
}
function addRandomKey(ctx, task, opt_prefix, opt_size) {
return new Promise(function(resolve, reject) {
task.tenant = ctx.tenant;
if (undefined !== opt_prefix && undefined !== opt_size) {
task.key = opt_prefix + crypto.randomBytes(opt_size).toString("hex");
} else {
task.key = task.key + '_' + Math.round(Math.random() * RANDOM_KEY_MAX);
}
task.completeDefaults();
let values = [];
let p0 = addSqlParam(task.tenant, values);
let p1 = addSqlParam(task.key, values);
let p2 = addSqlParam(task.status, values);
let p3 = addSqlParam(task.statusInfo, values);
let p4 = addSqlParam(new Date(), values);
let p5 = addSqlParam(task.userIndex, values);
let p6 = addSqlParam(task.changeId, values);
let p7 = addSqlParam(task.callback, values);
let p8 = addSqlParam(task.baseurl, values);
let sqlCommand = `INSERT INTO ${cfgTableResult} (tenant, id, status, status_info, last_open_date, user_index, change_id, callback, baseurl)` +
` VALUES (${p0}, ${p1}, ${p2}, ${p3}, ${p4}, ${p5}, ${p6}, ${p7}, ${p8});`;
sqlBase.baseConnector.sqlQuery(ctx, sqlCommand, function(error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
}, undefined, undefined, values);
});
}
function* addRandomKeyTask(ctx, key, opt_prefix, opt_size) {
var task = new TaskResultData();
task.tenant = ctx.tenant;
task.key = key;
task.status = commonDefines.FileStatus.WaitQueue;
//nTryCount чтобы не зависнуть если реально будут проблемы с DB
var nTryCount = RANDOM_KEY_MAX;
var addRes = null;
while (nTryCount-- > 0) {
try {
addRes = yield addRandomKey(ctx, task, opt_prefix, opt_size);
} catch (e) {
addRes = null;
//key exist, try again
}
if (addRes && addRes.affectedRows > 0) {
break;
}
}
if (addRes && addRes.affectedRows > 0) {
return task;
} else {
throw new Error('addRandomKeyTask Error');
}
}
function remove(ctx, docId) {
return new Promise(function(resolve, reject) {
let values = [];
let p1 = addSqlParam(ctx.tenant, values);
let p2 = addSqlParam(docId, values);
const sqlCommand = `DELETE FROM ${cfgTableResult} WHERE tenant=${p1} AND id=${p2};`;
sqlBase.baseConnector.sqlQuery(ctx, sqlCommand, function(error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
}, undefined, undefined, values);
});
}
function removeIf(ctx, mask) {
return new Promise(function(resolve, reject) {
let values = [];
let commandArgMask = toUpdateArray(mask, false, true, values, false);
commandArgMask.push('tenant=' + addSqlParam(mask.tenant, values));
commandArgMask.push('id=' + addSqlParam(mask.key, values));
let sqlWhere = commandArgMask.join(' AND ');
const sqlCommand = `DELETE FROM ${cfgTableResult} WHERE ${sqlWhere};`;
sqlBase.baseConnector.sqlQuery(ctx, sqlCommand, function(error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
}, undefined, undefined, values);
});
}
function getExpired(ctx, maxCount, expireSeconds) {
return new Promise(function(resolve, reject) {
let values = [];
let expireDate = new Date();
utils.addSeconds(expireDate, -expireSeconds);
let sqlParam1 = addSqlParam(expireDate, values);
let sqlParam2 = addSqlParam(maxCount, values);
let sqlCommand = `SELECT * FROM ${cfgTableResult} WHERE last_open_date <= ${sqlParam1}` +
` AND NOT EXISTS(SELECT tenant, id FROM ${cfgTableChanges} WHERE ${cfgTableChanges}.tenant = ${cfgTableResult}.tenant AND ${cfgTableChanges}.id = ${cfgTableResult}.id LIMIT 1) LIMIT ${sqlParam2};`;
sqlBase.baseConnector.sqlQuery(ctx, sqlCommand, function(error, result) {
if (error) {
reject(error);
} else {
resolve(result);
}
}, undefined, undefined, values);
});
}
exports.TaskResultData = TaskResultData;
exports.upsert = upsert;
exports.select = select;
exports.update = update;
exports.updateIf = updateIf;
exports.restoreInitialPassword = restoreInitialPassword;
exports.addRandomKeyTask = addRandomKeyTask;
exports.remove = remove;
exports.removeIf = removeIf;
exports.getExpired = getExpired;