Merge remote-tracking branch 'remotes/origin/release/v7.0.0' into develop

# Conflicts:
#	Common/package.json
#	Common/sources/license.js
This commit is contained in:
Sergey Konovalov
2021-12-20 18:37:03 +03:00
20 changed files with 502 additions and 155 deletions

View File

@ -30,8 +30,6 @@
"urlExpires": 604800,
"accessKeyId": "AKID",
"secretAccessKey": "SECRET",
"useRequestToGetUrl": false,
"useSignedUrl": false,
"sslEnabled": false,
"s3ForcePathStyle": true,
"externalHost": ""
@ -83,8 +81,8 @@
"favIconUrlCell" : "/web-apps/apps/spreadsheeteditor/main/resources/img/favicon.ico",
"favIconUrlSlide" : "/web-apps/apps/presentationeditor/main/resources/img/favicon.ico",
"fileInfoBlockList" : ["FileUrl"],
"wordView": ["pdf", "djvu", "xps", "doc", "dotx", "dotm", "dot", "fodt", "ott", "rtf", "mht", "html", "htm", "xml", "epub", "fb2"],
"wordEdit": ["docx", "docm", "odt", "txt"],
"wordView": ["pdf", "djvu", "xps", "oxps", "doc", "dotx", "dotm", "dot", "fodt", "ott", "rtf", "mht", "html", "htm", "xml", "epub", "fb2"],
"wordEdit": ["docx", "docm", "docxf", "oform", "odt", "txt"],
"cellView": ["xls", "xltx", "xltm", "xlt", "fods", "ots"],
"cellEdit": ["xlsx", "xlsm", "ods", "csv"],
"slideView": ["ppt", "ppsx", "ppsm", "pps", "potx", "potm", "pot", "fodp", "otp"],
@ -187,7 +185,8 @@
"sessionclosecommand": "2m",
"pemStdTTL": "1h",
"pemCheckPeriod": "10m",
"updateVersionStatus": "5m"
"updateVersionStatus": "5m",
"monthUniqueUsers": "1y"
},
"ipfilter": {
"rules": [{"address": "*", "allowed": true}],

View File

@ -15,10 +15,6 @@
"json-schema-traverse": "^0.3.0"
}
},
"amazon-s3-url-signer": {
"version": "https://github.com/agolybev/amazon-s3-url-signer/archive/v0.0.9.tar.gz",
"integrity": "sha512-wkmsZG000+d711di1U3690g3rE++ettaLZWDrAESgNhklr3wQcYEdEqAnQjgNirM0jjByQ9HTCeV48wFpHHguQ=="
},
"amqplib": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz",

View File

@ -4,7 +4,6 @@
"homepage": "https://www.onlyoffice.com",
"private": true,
"dependencies": {
"amazon-s3-url-signer": "https://github.com/agolybev/amazon-s3-url-signer/archive/v0.0.9.tar.gz",
"amqplib": "^0.8.0",
"aws-sdk": "^2.346.0",
"co": "^4.6.0",

View File

@ -96,7 +96,12 @@ exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOTM = exports.AVS_OFFICESTUDIO_FILE_DOCU
exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT_FLAT = exports.AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x000e;
exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_OTT = exports.AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x000f;
exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT = exports.AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0010;
exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER = exports.AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0011;
exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT = exports.AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0011;
exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER = exports.AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0012;
exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_PACKAGE = exports.AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0014;
exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM = exports.AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0015;
exports.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF = exports.AVS_OFFICESTUDIO_FILE_DOCUMENT + 0x0016;
exports.AVS_OFFICESTUDIO_FILE_PRESENTATION = 0x0080;
exports.AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX = exports.AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0001;
exports.AVS_OFFICESTUDIO_FILE_PRESENTATION_PPT = exports.AVS_OFFICESTUDIO_FILE_PRESENTATION + 0x0002;
@ -180,6 +185,7 @@ exports.CONVERT_DOWNLOAD = -81;
exports.CONVERT_UNKNOWN_FORMAT = -82;
exports.CONVERT_TIMEOUT = -83;
exports.CONVERT_READ_FILE = -84;
exports.CONVERT_DRM_UNSUPPORTED = -85;
exports.CONVERT_CORRUPTED = -86;
exports.CONVERT_LIBREOFFICE = -87;
exports.CONVERT_PARAMS = -88;
@ -224,6 +230,7 @@ exports.REDIS_KEY_PRESENCE_HASH = 'presence:hash:';
exports.REDIS_KEY_PRESENCE_SET = 'presence:set:';
exports.REDIS_KEY_PRESENCE_UNIQUE_USERS = 'presence:unique:users';
exports.REDIS_KEY_PRESENCE_UNIQUE_USERS_HASH = 'presence:unique:users:hash';
exports.REDIS_KEY_PRESENCE_MONTH_UNIQUE_USERS_HASH = 'presence:unique:users:month';
exports.REDIS_KEY_LOCKS = 'locks:';
exports.REDIS_KEY_LOCK_DOCUMENT = 'lockdocument:';
exports.REDIS_KEY_MESSAGE = 'message:';

View File

@ -231,6 +231,10 @@ exports.getFormatFromString = function(ext) {
return constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_ODT_FLAT;
case 'ott':
return constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_OTT;
case 'oform':
return constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM;
case 'docxf':
return constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF;
case 'pptx':
return constants.AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX;
@ -366,8 +370,16 @@ exports.getStringFromFormat = function(format) {
return 'ott';
case constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOC_FLAT:
return 'doc';
case constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_FLAT:
return 'docx';
case constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_HTML_IN_CONTAINER:
return 'doc';
case constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCX_PACKAGE:
return 'xml';
case constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_OFORM:
return 'oform';
case constants.AVS_OFFICESTUDIO_FILE_DOCUMENT_DOCXF:
return 'docxf';
case constants.AVS_OFFICESTUDIO_FILE_PRESENTATION_PPTX:
return 'pptx';

View File

@ -39,6 +39,8 @@ const oBuildDate = new Date(buildDate);
exports.readLicense = function*() {
const c_LR = constants.LICENSE_RESULT;
var now = new Date();
var startDate = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));//first day of current month
return [{
count: 1,
type: c_LR.Success,
@ -53,6 +55,7 @@ exports.readLicense = function*() {
hasLicense: false,
plugins: false,
buildDate: oBuildDate,
startDate: startDate,
endDate: null,
customerId: ""
}, null];

View File

@ -49,8 +49,6 @@ var cfgBucketName = configStorage.get('bucketName');
var cfgStorageFolderName = configStorage.get('storageFolderName');
var cfgAccessKeyId = configStorage.get('accessKeyId');
var cfgSecretAccessKey = configStorage.get('secretAccessKey');
var cfgUseRequestToGetUrl = configStorage.get('useRequestToGetUrl');
var cfgUseSignedUrl = configStorage.get('useSignedUrl');
var cfgSslEnabled = configStorage.get('sslEnabled');
var cfgS3ForcePathStyle = configStorage.get('s3ForcePathStyle');
var configFs = configStorage.get('fs');
@ -224,50 +222,19 @@ exports.deleteObjects = function(strPaths) {
};
exports.getSignedUrl = function(baseUrl, strPath, urlType, optFilename, opt_creationDate) {
return new Promise(function(resolve, reject) {
var expires = (commonDefines.c_oAscUrlTypes.Session === urlType ? cfgExpSessionAbsolute : cfgStorageUrlExpires) || 31536000;
var expires = (commonDefines.c_oAscUrlTypes.Session === urlType ? cfgExpSessionAbsolute / 1000 : cfgStorageUrlExpires) || 31536000;
var userFriendlyName = optFilename ? optFilename.replace(/\//g, "%2f") : path.basename(strPath);
var contentDisposition = utils.getContentDisposition(userFriendlyName, null, null);
if (cfgUseRequestToGetUrl) {
//default Expires 900 seconds
var params = {
Bucket: cfgBucketName, Key: getFilePath(strPath), ResponseContentDisposition: contentDisposition, Expires: expires
};
s3Client.getSignedUrl('getObject', params, function(err, data) {
if (err) {
reject(err);
} else {
resolve(utils.changeOnlyOfficeUrl(data, strPath, optFilename));
}
});
} else {
var host;
if (cfgRegion) {
host = 'https://s3-'+cfgRegion+'.amazonaws.com';
} else if (cfgEndpointParsed &&
(cfgEndpointParsed.hostname == 'localhost' || cfgEndpointParsed.hostname == '127.0.0.1') &&
80 == cfgEndpointParsed.port) {
host = utils.checkBaseUrl(baseUrl) + cfgEndpointParsed.path;
//default Expires 900 seconds
var params = {
Bucket: cfgBucketName, Key: getFilePath(strPath), ResponseContentDisposition: contentDisposition, Expires: expires
};
s3Client.getSignedUrl('getObject', params, function(err, data) {
if (err) {
reject(err);
} else {
host = cfgEndpoint;
resolve(utils.changeOnlyOfficeUrl(data, strPath, optFilename));
}
if (host && host.length > 0 && '/' != host[host.length - 1]) {
host += '/';
}
var newUrl;
if (cfgUseSignedUrl) {
//todo уйти от parse
var hostParsed = url.parse(host);
var protocol = hostParsed.protocol.substring(0, hostParsed.protocol.length - 1);
var signerOptions = {
host: hostParsed.hostname, port: hostParsed.port,
protocol: protocol, useSubdomain: false
};
var awsUrlSigner = s3urlSigner.urlSigner(cfgAccessKeyId, cfgSecretAccessKey, signerOptions);
newUrl = awsUrlSigner.getUrl('GET', getFilePath(strPath), cfgBucketName, expires, contentDisposition);
} else {
newUrl = host + cfgBucketName + '/' + cfgStorageFolderName + '/' + strPath;
}
resolve(utils.changeOnlyOfficeUrl(newUrl, strPath, optFilename));
}
});
});
};

View File

@ -431,6 +431,7 @@ exports.mapAscServerErrorToOldError = function(error) {
break;
case constants.CONVERT_PASSWORD :
case constants.CONVERT_DRM :
case constants.CONVERT_DRM_UNSUPPORTED :
res = -5;
break;
case constants.CONVERT_DOWNLOAD :
@ -930,6 +931,7 @@ exports.convertLicenseInfoToFileParams = function(licenseInfo) {
// whiteLabel = false;
// }
let license = {};
license.start_date = licenseInfo.startDate && licenseInfo.startDate.toJSON();
license.end_date = licenseInfo.endDate && licenseInfo.endDate.toJSON();
license.timelimited = 0 !== (constants.LICENSE_MODE.Limited & licenseInfo.mode);
license.trial = 0 !== (constants.LICENSE_MODE.Trial & licenseInfo.mode);
@ -966,3 +968,44 @@ exports.checkBaseUrl = function(baseUrl) {
exports.resolvePath = function(object, path, defaultValue) {
return path.split('.').reduce((o, p) => o ? o[p] : defaultValue, object);
}
Date.isLeapYear = function (year) {
return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
};
Date.getDaysInMonth = function (year, month) {
return [31, (Date.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
};
Date.prototype.isLeapYear = function () {
return Date.isLeapYear(this.getUTCFullYear());
};
Date.prototype.getDaysInMonth = function () {
return Date.getDaysInMonth(this.getUTCFullYear(), this.getUTCMonth());
};
Date.prototype.addMonths = function (value) {
var n = this.getUTCDate();
this.setUTCDate(1);
this.setUTCMonth(this.getUTCMonth() + value);
this.setUTCDate(Math.min(n, this.getDaysInMonth()));
return this;
};
function getMonthDiff(d1, d2) {
var months;
months = (d2.getUTCFullYear() - d1.getUTCFullYear()) * 12;
months -= d1.getUTCMonth();
months += d2.getUTCMonth();
return months;
}
exports.getLicensePeriod = function(startDate, now) {
startDate = new Date(startDate.getTime());//clone
startDate.addMonths(getMonthDiff(startDate, now));
if (startDate > now) {
startDate.addMonths(-1);
}
startDate.setUTCHours(0,0,0,0);
return startDate.getTime();
};

View File

@ -33,6 +33,11 @@
"resolved": "https://registry.npmjs.org/apicache/-/apicache-1.6.2.tgz",
"integrity": "sha512-3z5e+1E2qwZoqzFVgdx5l9nGhSG0kHv3v2G170vnJSz5uj4mCLVZfRw0o37aWwV8pTPXSkB8OBZz3TIur4H26g=="
},
"append-field": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/append-field/-/append-field-1.0.0.tgz",
"integrity": "sha1-HjRA6RXwsSA9I3SOeO3XubW0PlY="
},
"array-flatten": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
@ -77,11 +82,48 @@
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk="
},
"buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
},
"buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw=="
},
"busboy": {
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
"requires": {
"dicer": "0.2.5",
"readable-stream": "1.1.x"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
}
}
},
"bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@ -92,6 +134,17 @@
"resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
},
"concat-stream": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
"requires": {
"buffer-from": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^2.2.2",
"typedarray": "^0.0.6"
}
},
"config": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/config/-/config-2.0.1.tgz",
@ -166,6 +219,38 @@
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
},
"dicer": {
"version": "0.2.5",
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
"integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
"requires": {
"readable-stream": "1.1.x",
"streamsearch": "0.1.2"
},
"dependencies": {
"isarray": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
},
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.1",
"isarray": "0.0.1",
"string_decoder": "~0.10.x"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
}
}
},
"double-ended-queue": {
"version": "2.1.0-0",
"resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
@ -349,9 +434,9 @@
}
},
"faye-websocket": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
"integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
"integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
"requires": {
"websocket-driver": ">=0.5.1"
}
@ -400,9 +485,9 @@
}
},
"http-parser-js": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz",
"integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w=="
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz",
"integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg=="
},
"iconv-lite": {
"version": "0.4.23",
@ -550,6 +635,14 @@
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"mkdirp": {
"version": "0.5.5",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
"integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
"requires": {
"minimist": "^1.2.5"
}
},
"moment": {
"version": "2.22.2",
"resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz",
@ -568,6 +661,21 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
},
"multer": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/multer/-/multer-1.4.3.tgz",
"integrity": "sha512-np0YLKncuZoTzufbkM6wEKp68EhWJXcU6fq6QqrSwkckd2LlMgd1UqhUJLj6NS/5sZ8dE8LYDWslsltJznnXlg==",
"requires": {
"append-field": "^1.0.0",
"busboy": "^0.2.11",
"concat-stream": "^1.5.2",
"mkdirp": "^0.5.4",
"object-assign": "^4.1.1",
"on-finished": "^2.3.0",
"type-is": "^1.6.4",
"xtend": "^4.0.0"
}
},
"multi-integer-range": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/multi-integer-range/-/multi-integer-range-4.0.7.tgz",
@ -614,6 +722,11 @@
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
},
"object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@ -893,12 +1006,13 @@
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
},
"sockjs": {
"version": "0.3.19",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
"integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
"version": "0.3.21",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz",
"integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==",
"requires": {
"faye-websocket": "^0.10.0",
"uuid": "^3.0.1"
"faye-websocket": "^0.11.3",
"uuid": "^3.4.0",
"websocket-driver": "^0.7.4"
}
},
"split2": {
@ -931,6 +1045,11 @@
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
},
"streamsearch": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@ -953,6 +1072,11 @@
"mime-types": "~2.1.18"
}
},
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
},
"uid-safe": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
@ -990,9 +1114,9 @@
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"vary": {
"version": "1.1.2",
@ -1000,11 +1124,12 @@
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"websocket-driver": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
"integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=",
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
"integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
"requires": {
"http-parser-js": ">=0.4.0",
"http-parser-js": ">=0.5.1",
"safe-buffer": ">=5.1.0",
"websocket-extensions": ">=0.1.1"
}
},

View File

@ -25,13 +25,14 @@
"mime": "^2.3.1",
"mime-db": "^1.49.0",
"ms": "^2.1.1",
"multer": "^1.4.3",
"multi-integer-range": "^4.0.7",
"multiparty": "^4.2.1",
"mysql": "^2.16.0",
"pg": "^8.5.1",
"redis": "^2.8.0",
"retry": "^0.12.0",
"sockjs": "^0.3.19",
"sockjs": "^0.3.21",
"underscore": "^1.13.1",
"utf7": "^1.0.2",
"windows-locale": "^1.0.1"

View File

@ -560,6 +560,8 @@ function* updateEditUsers(userId, anonym) {
const expireAt = (Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1)) / 1000 +
licenseInfo.usersExpire - 1;
yield editorData.addPresenceUniqueUser(userId, expireAt, {anonym: anonym});
let period = utils.getLicensePeriod(licenseInfo.startDate, now);
yield editorData.addPresenceUniqueUsersOfMonth(userId, period, {anonym: anonym, firstOpenDate: now.toISOString()});
}
function* getEditorsCount(docId, opt_hvals) {
var elem, editorsCount = 0;
@ -2092,7 +2094,7 @@ exports.install = function(server, callbackFunction) {
let wopiParams = null;
if (data.documentCallbackUrl) {
wopiParams = wopiClient.parseWopiCallback(docId, data.documentCallbackUrl);
if (wopiParams) {
if (wopiParams && wopiParams.userAuth) {
conn.access_token_ttl = wopiParams.userAuth.access_token_ttl;
}
}
@ -2191,6 +2193,10 @@ exports.install = function(server, callbackFunction) {
cmd.setWopiParams(wopiParams);
if (wopiParams) {
documentCallback = null;
if (!wopiParams.userAuth) {
yield* sendFileErrorAuth(conn, data.sessionId, 'Wopi without userAuth');
return;
}
}
}
if (conn.user.idOriginal.length > constants.USER_ID_MAX_LENGTH) {
@ -3330,8 +3336,10 @@ exports.licenseInfo = function(req, res) {
connectionsStat: {}, licenseInfo: {}, serverInfo: {
buildVersion: commonDefines.buildVersion, buildNumber: commonDefines.buildNumber,
}, quota: {
editorConnectionsCount: 0,
uniqueUserCount: 0,
anonymousUserCount: 0
anonymousUserCount: 0,
byMonth: null
}
};
Object.assign(output.licenseInfo, licenseInfo);
@ -3340,7 +3348,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, time: null, period: PRECISION[i].val},
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] = {
@ -3360,7 +3368,6 @@ 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;
@ -3373,15 +3380,13 @@ 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) * scale);
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) * scale);
precisionOut.view.avr = Math.round(precision.view.sum / precision.view.count);
precisionOut.view.min = precision.view.min;
precisionOut.view.max = precision.view.max;
}
@ -3394,6 +3399,11 @@ exports.licenseInfo = function(req, res) {
output.quota.anonymousUserCount++;
}
});
output.quota.byMonth = yield editorData.getPresenceUniqueUsersOfMonth();
output.quota.byMonth.sort((a, b) => {
return a.date.localeCompare(b.date);
});
output.quota.editorConnectionsCount = yield editorData.getEditorConnectionsCount(connections);
logger.debug('licenseInfo end');
} catch (err) {
isError = true;

View File

@ -368,6 +368,8 @@ function* getUpdateResponse(cmd) {
} else {
updateTask.status = taskResult.FileStatus.Err;
}
} else if (constants.CONVERT_DRM_UNSUPPORTED == statusInfo) {
updateTask.status = taskResult.FileStatus.Err;
} else if (constants.CONVERT_DEAD_LETTER == statusInfo) {
updateTask.status = taskResult.FileStatus.ErrToReload;
} else {
@ -1060,7 +1062,10 @@ function* commandSfcCallback(cmd, isSfcm, isEncrypted) {
updateIfTask.status = recoverTask.status;
updateIfTask.statusInfo = recoverTask.statusInfo;
updateIfRes = yield taskResult.updateIf(updateIfTask, updateMask);
if (!(updateIfRes.affectedRows > 0)) {
if (updateIfRes.affectedRows > 0) {
updateMask.status = updateIfTask.status;
updateMask.statusInfo = updateIfTask.statusInfo;
} else {
logger.debug('commandSfcCallback restore %d status failed: docId = %s', recoverTask.status, docId);
}
}

View File

@ -31,13 +31,18 @@
*/
'use strict';
const config = require('config');
const ms = require('ms');
const utils = require('./../../Common/sources/utils');
const commonDefines = require('./../../Common/sources/commondefines');
const cfgExpMonthUniqueUsers = ms(config.get('services.CoAuthoring.expire.monthUniqueUsers'));
function EditorData() {
this.data = {};
this.forceSaveTimer = {};
this.uniqueUser = {};
this.uniqueUsersOfMonth = {};
this.shutdown = {};
this.stat = [];
}
@ -242,6 +247,29 @@ EditorData.prototype.getPresenceUniqueUser = function(nowUTC) {
}
return Promise.resolve(res);
};
EditorData.prototype.addPresenceUniqueUsersOfMonth = function(userId, period, userInfo) {
if(!this.uniqueUsersOfMonth[period]) {
let expireAt = Date.now() + cfgExpMonthUniqueUsers;
this.uniqueUsersOfMonth[period] = {expireAt: expireAt, data: {}};
}
this.uniqueUsersOfMonth[period].data[userId] = userInfo;
return Promise.resolve();
};
EditorData.prototype.getPresenceUniqueUsersOfMonth = function() {
let res = [];
let nowUTC = Date.now();
for (let periodId in this.uniqueUsersOfMonth) {
if (this.uniqueUsersOfMonth.hasOwnProperty(periodId)) {
if (this.uniqueUsersOfMonth[periodId].expireAt <= nowUTC) {
delete this.uniqueUsersOfMonth[periodId];
} else {
let date = new Date(parseInt(periodId)).toISOString();
res.push({date: date, users: this.uniqueUsersOfMonth[periodId].data});
}
}
}
return Promise.resolve(res);
};
EditorData.prototype.setEditorConnections = function(countEdit, countView, now, precision) {
this.stat.push({time: now, edit: countEdit, view: countView});

View File

@ -45,6 +45,7 @@ const http = require('http');
const urlModule = require('url');
const path = require('path');
const bodyParser = require("body-parser");
const multer = require('multer');
const mime = require('mime');
const apicache = require('apicache');
const docsCoServer = require('./DocsCoServer');
@ -165,6 +166,7 @@ docsCoServer.install(server, () => {
const rawFileParser = bodyParser.raw(
{inflate: true, limit: config.get('server.limits_tempfile_upload'), type: function() {return true;}});
const urleEcodedParser = bodyParser.urlencoded({ extended: false });
let forms = multer();
app.get('/coauthoring/CommandService.ashx', utils.checkClientIp, rawFileParser, docsCoServer.commandFromServer);
app.post('/coauthoring/CommandService.ashx', utils.checkClientIp, rawFileParser,
@ -220,7 +222,7 @@ docsCoServer.install(server, () => {
if (cfgWopiEnable) {
app.get('/hosting/discovery', utils.checkClientIp, wopiClient.discovery);
app.get('/hosting/capabilities', utils.checkClientIp, wopiClient.collaboraCapabilities);
app.post('/hosting/wopi/:documentType/:mode', utils.checkClientIp, urleEcodedParser, utils.lowercaseQueryString, wopiClient.getEditorHtml);
app.post('/hosting/wopi/:documentType/:mode', utils.checkClientIp, urleEcodedParser, forms.none(), utils.lowercaseQueryString, wopiClient.getEditorHtml);
}
app.post('/dummyCallback', utils.checkClientIp, rawFileParser, function(req, res){
@ -295,8 +297,10 @@ docsCoServer.install(server, () => {
logger.debug('themes.json dir:%s', dir);
logger.debug('themes.json themesList:%j', themesList);
for (let j = 0; j < themesList.length; ++j) {
let data = yield utils.readFile(themesList[j], true);
themes.push(JSON.parse(data.toString('utf-8')));
if (themesList[j].endsWith('.json')) {
let data = yield utils.readFile(themesList[j], true);
themes.push(JSON.parse(data.toString('utf-8')));
}
}
break;
}
@ -305,7 +309,7 @@ docsCoServer.install(server, () => {
logger.error('themes.json error:%s', err.stack);
} finally {
if (themes.length > 0) {
res.setHeader('Content-Type', 'text/xml');
res.setHeader('Content-Type', 'application/json');
res.send({"themes": themes});
} else {
res.sendStatus(404);

View File

@ -127,7 +127,10 @@ function discovery(req, res) {
}
for (let j = 0; j < ext.edit.length; ++j) {
output += `<action name="view" ext="${ext.edit[j]}" urlsrc="${urlTemplateView}" />`;
output += `<action name="editnew" ext="${ext.edit[j]}" requires="locks,update" urlsrc="${urlTemplateEdit}" />`;
if ("oform" !== ext.edit[j]) {
//todo config
output += `<action name="editnew" ext="${ext.edit[j]}" requires="locks,update" urlsrc="${urlTemplateEdit}" />`;
}
output += `<action name="edit" ext="${ext.edit[j]}" default="true" requires="locks,update" urlsrc="${urlTemplateEdit}" />`;
}
output +=`</app>`;
@ -222,10 +225,16 @@ function getLastModifiedTimeFromCallbacks(callbacks) {
}
}
}
function isCorrectUserAuth(userAuth) {
return undefined !== userAuth.wopiSrc;
}
function parseWopiCallback(docId, userAuthStr, opt_url) {
let wopiParams = null;
if (isWopiCallback(userAuthStr)) {
let userAuth = JSON.parse(userAuthStr);
if (!isCorrectUserAuth(userAuth)) {
userAuth = null;
}
let commonInfo = null;
let lastModifiedTime = null;
if (opt_url) {
@ -300,8 +309,8 @@ function getEditorHtml(req, res) {
let wopiSrc = req.query['wopisrc'];
let sc = req.query['sc'];
let hostSessionId = req.query['hid'];
let access_token = req.body['access_token'];
let access_token_ttl = parseInt(req.body['access_token_ttl']);
let access_token = req.body['access_token'] || "";
let access_token_ttl = parseInt(req.body['access_token_ttl']) || 0;
let uri = `${encodeURI(wopiSrc)}?access_token=${encodeURIComponent(access_token)}`;
@ -388,6 +397,9 @@ function putFile(wopiParams, data, dataStream, userLastChangeId) {
let postRes = null;
try {
logger.info('wopi PutFile start');
if (!wopiParams.userAuth) {
return postRes;
}
let fileInfo = wopiParams.commonInfo.fileInfo;
let userAuth = wopiParams.userAuth;
let uri = `${userAuth.wopiSrc}/contents?access_token=${userAuth.access_token}`;
@ -427,6 +439,9 @@ function renameFile(wopiParams, name) {
let res;
try {
logger.info('wopi RenameFile start');
if (!wopiParams.userAuth) {
return res;
}
let fileInfo = wopiParams.commonInfo.fileInfo;
let userAuth = wopiParams.userAuth;
let uri = `${userAuth.wopiSrc}?access_token=${userAuth.access_token}`;
@ -495,6 +510,9 @@ function lock(command, lockId, fileInfo, userAuth) {
try {
logger.info('wopi %s start', command);
if (fileInfo && fileInfo.SupportsLocks) {
if (!userAuth) {
return false;
}
let wopiSrc = userAuth.wopiSrc;
let access_token = userAuth.access_token;
let uri = `${wopiSrc}?access_token=${access_token}`;
@ -526,6 +544,9 @@ function unlock(wopiParams) {
logger.info('wopi Unlock start');
let fileInfo = wopiParams.commonInfo.fileInfo;
if (fileInfo && fileInfo.SupportsLocks) {
if (!wopiParams.userAuth) {
return;
}
let wopiSrc = wopiParams.userAuth.wopiSrc;
let lockId = wopiParams.commonInfo.lockId;
let access_token = wopiParams.userAuth.access_token;

View File

@ -85,10 +85,10 @@ var TEMP_PREFIX = 'ASC_CONVERT';
var queue = null;
var clientStatsD = statsDClient.getClient();
var exitCodesReturn = [constants.CONVERT_PARAMS, constants.CONVERT_NEED_PARAMS, constants.CONVERT_CORRUPTED,
constants.CONVERT_DRM, constants.CONVERT_PASSWORD, constants.CONVERT_LIMITS];
var exitCodesMinorError = [constants.CONVERT_NEED_PARAMS, constants.CONVERT_DRM, constants.CONVERT_PASSWORD];
constants.CONVERT_DRM, constants.CONVERT_DRM_UNSUPPORTED, constants.CONVERT_PASSWORD, constants.CONVERT_LIMITS];
var exitCodesMinorError = [constants.CONVERT_NEED_PARAMS, constants.CONVERT_DRM, constants.CONVERT_DRM_UNSUPPORTED, constants.CONVERT_PASSWORD];
var exitCodesUpload = [constants.NO_ERROR, constants.CONVERT_CORRUPTED, constants.CONVERT_NEED_PARAMS,
constants.CONVERT_DRM];
constants.CONVERT_DRM, constants.CONVERT_DRM_UNSUPPORTED];
let inputLimitsXmlCache;
function TaskQueueDataConvert(task) {
@ -697,7 +697,7 @@ function* ExecuteTask(task) {
url = fileInfo.FileUrl;
} else if (fileInfo.TemplateSource) {
url = fileInfo.TemplateSource;
} else {
} else if (userAuth) {
url = `${userAuth.wopiSrc}/contents?access_token=${userAuth.access_token}`;
headers = {'X-WOPI-MaxExpectedSize': cfgDownloadMaxBytes, 'X-WOPI-ItemVersion': fileInfo.Version};
wopiClient.fillStandardHeaders(headers, url, userAuth.access_token);

View File

@ -149,9 +149,9 @@
}
},
"faye-websocket": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
"integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz",
"integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==",
"requires": {
"websocket-driver": ">=0.5.1"
}
@ -192,9 +192,9 @@
}
},
"http-parser-js": {
"version": "0.5.0",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.0.tgz",
"integrity": "sha512-cZdEF7r4gfRIq7ezX9J0T+kQmJNOub71dWbgAXVHDct80TKP4MCETtZQ31xyv38UwgzkWPYF/Xc0ge55dW9Z9w=="
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.3.tgz",
"integrity": "sha512-t7hjvef/5HEK7RWTdUzVUhl8zkEu+LlaE0IYzdMuvbSDipxBRpOn4Uhw8ZyECEa808iVT8XCjzo6xmYt4CiLZg=="
},
"iconv-lite": {
"version": "0.4.23",
@ -256,9 +256,9 @@
}
},
"minimist": {
"version": "1.2.0",
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"ms": {
"version": "2.0.0",
@ -377,12 +377,13 @@
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
},
"sockjs": {
"version": "0.3.19",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
"integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
"version": "0.3.21",
"resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.21.tgz",
"integrity": "sha512-DhbPFGpxjc6Z3I+uX07Id5ZO2XwYsWOrYjaSeieES78cq+JaJvVe5q/m1uvjIQhXinhIeCFRH6JgXe+mvVMyXw==",
"requires": {
"faye-websocket": "^0.10.0",
"uuid": "^3.0.1"
"faye-websocket": "^0.11.3",
"uuid": "^3.4.0",
"websocket-driver": "^0.7.4"
}
},
"statuses": {
@ -410,9 +411,9 @@
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
},
"uuid": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
"integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
},
"vary": {
"version": "1.1.2",
@ -420,18 +421,19 @@
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
},
"websocket-driver": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz",
"integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=",
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz",
"integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==",
"requires": {
"http-parser-js": ">=0.4.0",
"http-parser-js": ">=0.5.1",
"safe-buffer": ">=5.1.0",
"websocket-extensions": ">=0.1.1"
}
},
"websocket-extensions": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
"integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg=="
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="
}
}
}

View File

@ -9,7 +9,7 @@
"config": "^2.0.1",
"express": "^4.16.4",
"nodehun": "git+https://git@github.com/ONLYOFFICE/nodehun.git#2411a56828c7d58214c61781b4a5c63d18adba99",
"sockjs": "^0.3.19"
"sockjs": "^0.3.21"
},
"pkg": {
"assets": [

View File

@ -20,6 +20,8 @@
font-family: 'Open Sans', sans-serif;
font-size: 12px;
color: #333333;
display: flex;
flex-direction: column;
}
header {
@ -27,7 +29,7 @@
height: 44px;
margin: 0 auto;
min-width: 600px;
width: auto;
width: 100%;
padding-top: 4px;
}
@ -74,6 +76,10 @@
padding-right: 24px;
}
.td-last {
padding-bottom: 30px;
}
.main-panel {
margin: 40px auto 16px;
width: 672px;
@ -88,6 +94,11 @@
font-weight: 600;
padding-bottom: 25px;
}
.header2 {
font-size: 16px;
font-weight: 600;
padding-bottom: 25px;
}
#doc-server-wait {
text-align: center;
@ -137,6 +148,7 @@
<header>
<img src="img/logo.png" alt="ONLYOFFICE">
</header>
<div style="overflow: auto;height: 100%;flex-grow: 1;">
<div class="main-panel">
<div class="header0" id="doc-server-wait">Please, wait...</div>
<div class="hidden" id="doc-server-ok">
@ -159,7 +171,7 @@
</tr>
<tr>
<td id="build-version">Version:</td>
<td></td>
<td id="trial"></td>
</tr>
<tr>
<td id="build-date">Release date:</td>
@ -175,18 +187,38 @@
</tr>
<tr>
<td id="cell-use-up" class="td-value" width="150">0</td>
<td id="cell-external" class="td-value" width="150">0</td>
<td id="cell-internal" class="td-value" width="150">0</td>
<td id="cell-external" class="td-value" width="150">0</td>
<td id="cell-left" class="td-value" width="224">0</td>
</tr>
<tr>
<td>Use up</td>
<td>External</td>
<td>Internal</td>
<td>External</td>
<td>Left</td>
</tr>
</table>
<table>
<table id="connection-activity-info" class="hidden">
<tr>
<td colspan="4" class="td-caption">Current connections</td>
</tr>
<tr>
<td class="td-separator" colspan="4"><div class="separator"></div></td>
</tr>
<tr>
<td id="cell-conn-use-up" class="td-value" width="150">0</td>
<td id="cell-conn-left" class="td-value" width="150">0</td>
<td class="td-value" width="150"></td>
<td class="td-value" width="224"></td>
</tr>
<tr>
<td>Use up</td>
<td>Left</td>
<td></td>
<td></td>
</tr>
</table>
<table id="connections-peaks" class="hidden">
<tr>
<td colspan="4" class="td-caption">Peaks</td>
</tr>
@ -206,7 +238,7 @@
<td>Month</td>
</tr>
</table>
<table>
<table id="connections-average" class="hidden">
<tr>
<td colspan="4" class="td-caption">Average</td>
</tr>
@ -226,6 +258,9 @@
<td>Month</td>
</tr>
</table>
<div id="user-statistics-caption" class="header2 hidden">Usage statistics for the reporting period:</div>
<table id="user-statistics" class="hidden">
</table>
</div>
<div class="hidden header0" id="doc-server-err">
<div id="status-err-icon"></div>
@ -235,6 +270,7 @@
</div>
</div>
</div>
</div>
<script>
var _createXMLHTTPObject = function() {
var xmlhttp;
@ -285,10 +321,16 @@
elem.innerText = licdate.toLocaleDateString();
if (Date.now() > licdate)
elem.classList.add('critical');
elem = document.getElementById('trial');
elem.innerText = (licenseInfo.mode & 4) ? 'Trial' : '';
}
if (licenseInfo.usersCount>0) {
var quota = info.quota;
var quota = info.quota;
if (licenseInfo.usersCount>0) { // users limit
elem = document.getElementById('user-activity-info');
elem.classList.remove('hidden');
elem = document.getElementById('user-activity-info-caption');
var days = parseInt(licenseInfo.usersExpire/86400) || 1;
@ -305,15 +347,28 @@
var value = licenseInfo.usersCount - quota.uniqueUserCount;
elem.innerText = value;
elem.classList.add(value > licenseInfo.usersCount * 0.1 ? "normal" : "critical");
} else { // connections limit
elem = document.getElementById('connection-activity-info');
elem.classList.remove('hidden');
elem = document.getElementById('user-activity-info');
elem.classList.remove("hidden");
elem = document.getElementById('cell-conn-use-up');
elem.innerText = (quota.editorConnectionsCount || 0);
elem = document.getElementById('cell-conn-left');
var value = licenseInfo.connections - (quota.editorConnectionsCount || 0);
elem.innerText = value;
elem.classList.add(value > licenseInfo.connections * 0.1 ? "normal" : "critical");
}
return (licenseInfo.usersCount>0) ? 1000000 : licenseInfo.connections;
}
function fillConnections(info, limit) {
function fillConnections(info) {
var licenseInfo = info.licenseInfo;
if (licenseInfo.usersCount>0) return;
var limit = licenseInfo.connections;
document.getElementById('connections-peaks').classList.remove('hidden');
document.getElementById('connections-average').classList.remove('hidden');
for (var precision in info.connectionsStat) {
for (var agregate in info.connectionsStat[precision].edit) {
var value = info.connectionsStat[precision].edit[agregate];
@ -328,6 +383,64 @@
}
}
function fillStatistic(info) {
if (info.licenseInfo.usersCount<1) return;
var byMonth = info.quota.byMonth;
if (byMonth.length<1) return;
document.getElementById('user-statistics-caption').classList.remove('hidden');
var elem = document.getElementById('user-statistics');
elem.classList.remove('hidden');
var arr = [];
byMonth.forEach(function(item){
var date = item.date,
users = item.users,
internal = 0,
external = 0;
if (date && users) {
for (var uid in users) {
if (users.hasOwnProperty(uid)) {
users[uid].anonym ? external++ : internal++;
}
}
arr.push({
startDate: new Date(date),
internal: internal,
external: external
});
if (arr.length>1) {
arr[arr.length-2].endDate = new Date(new Date(date) - 86400000);
}
}
});
for (var i=0; i<arr.length; i++) {
var item = arr[arr.length-i-1];
var tr = document.createElement("tr");
tr.innerHTML = '<td colspan="4" class="td-caption">' + (item.endDate ? item.startDate.toLocaleDateString() + ' - ' + item.endDate.toLocaleDateString(): 'From ' + item.startDate.toLocaleDateString()) + '</td>';
elem.appendChild(tr);
tr = document.createElement("tr");
tr.innerHTML = '<td class="td-separator" colspan="4"><div class="separator"></div></td>';
elem.appendChild(tr);
tr = document.createElement("tr");
tr.innerHTML = '<td class="td-value" width="150">' + item.internal + '</td>' +
'<td class="td-value" width="150">' + item.external + '</td>' +
'<td class="td-value" width="150">' + (item.internal + item.external) + '</td>' +
'<td class="td-value" width="224"></td>';
elem.appendChild(tr);
tr = document.createElement("tr");
tr.innerHTML = '<td class="td-last">Internal</td>' +
'<td class="td-last">External</td>' +
'<td class="td-last">Active</td>' +
'<td class="td-last"></td>';
elem.appendChild(tr);
};
}
(function(){
try {
var xhrObj = _createXMLHTTPObject();
@ -341,7 +454,9 @@
if (xhrObj.status == 200) {
document.getElementById('doc-server-ok').classList.remove("hidden");
var info = JSON.parse(xhrObj.responseText);
fillConnections(info, fillInfo(info));
fillInfo(info);
fillConnections(info);
fillStatistic(info);
} else {
document.getElementById('doc-server-err').classList.remove("hidden");
}

56
npm-shrinkwrap.json generated
View File

@ -70,9 +70,9 @@
"integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c="
},
"async": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/async/-/async-3.2.2.tgz",
"integrity": "sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g=="
},
"atob": {
"version": "2.1.2",
@ -656,9 +656,9 @@
"integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg="
},
"getobject": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
"integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw="
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz",
"integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg=="
},
"glob": {
"version": "7.1.6",
@ -853,17 +853,27 @@
}
},
"grunt-legacy-util": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.0.tgz",
"integrity": "sha512-ZEmYFB44bblwPE2oz3q3ygfF6hseQja9tx8I3UZIwbUik32FMWewA+d1qSFicMFB+8dNXDkh35HcDCWlpRsGlA==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz",
"integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==",
"requires": {
"async": "~1.5.2",
"exit": "~0.1.1",
"getobject": "~0.1.0",
"async": "~3.2.0",
"exit": "~0.1.2",
"getobject": "~1.0.0",
"hooker": "~0.2.3",
"lodash": "~4.17.20",
"lodash": "~4.17.21",
"underscore.string": "~3.3.5",
"which": "~1.3.0"
"which": "~2.0.2"
},
"dependencies": {
"which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
"requires": {
"isexe": "^2.0.0"
}
}
}
},
"grunt-mkdir": {
@ -965,9 +975,9 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.5",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"interpret": {
"version": "1.1.0",
@ -1172,9 +1182,9 @@
}
},
"lodash": {
"version": "4.17.20",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
"version": "4.17.21",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
},
"lodash.camelcase": {
"version": "4.3.0",
@ -1417,9 +1427,9 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-parse": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
},
"path-root": {
"version": "0.1.1",