diff --git a/Common/config/default.json b/Common/config/default.json index 59f58a837..93dc6c1e0 100644 --- a/Common/config/default.json +++ b/Common/config/default.json @@ -64,6 +64,16 @@ "ttl" : 300, "cachesize" : 1000 }, + "openpgpjs": { + "config": { + }, + "encrypt": { + "passwords": ["verysecretstring"] + }, + "decrypt": { + "passwords": ["verysecretstring"] + } + }, "services": { "CoAuthoring": { "server": { @@ -77,6 +87,7 @@ "wholeCycle": "2m" }, "callbackRequestTimeout": { + "connectionAndInactivity": "10s", "wholeCycle": "2m" }, "healthcheckfilepath": "../public/healthcheck.docx", @@ -204,7 +215,7 @@ "autostart": [] }, "editor":{ - "spellcheckerUrl": "/spellchecker", + "spellcheckerUrl": "", "reconnection":{ "attempts": 50, "delay": "2s" @@ -247,6 +258,7 @@ "x2tPath": "null", "docbuilderPath": "null", "docbuilderAllFontsPath": "null", + "docbuilderCoreFontsPath": "", "args": "", "spawnOptions": {}, "errorfiles": "", diff --git a/Common/config/development-linux.json b/Common/config/development-linux.json index 7243ac7cb..d20dbe5eb 100644 --- a/Common/config/development-linux.json +++ b/Common/config/development-linux.json @@ -24,6 +24,9 @@ "/sdkjs-plugins": { "path": "../../../sdkjs-plugins" }, + "/dictionaries": { + "path": "../../../dictionaries" + }, "/info": { "path": "../branding/info" } @@ -52,7 +55,8 @@ "presentationThemesDir": "../../../sdkjs/slide/themes", "x2tPath": "../../FileConverter/bin/x2t", "docbuilderPath": "../../FileConverter/bin/docbuilder", - "docbuilderAllFontsPath": "../../App_Data/docbuilder/AllFonts.js" + "docbuilderAllFontsPath": "../../App_Data/docbuilder/AllFonts.js", + "docbuilderCoreFontsPath": "../../../core-fonts" } }, "SpellChecker": { diff --git a/Common/config/development-mac.json b/Common/config/development-mac.json index 8da2ab528..8ba54d7dc 100644 --- a/Common/config/development-mac.json +++ b/Common/config/development-mac.json @@ -24,6 +24,9 @@ "/sdkjs-plugins": { "path": "../../../sdkjs-plugins" }, + "/dictionaries": { + "path": "../../../dictionaries" + }, "/info": { "path": "../../branding/info" } @@ -42,9 +45,6 @@ "allowPrivateIPAddress": true, "allowMetaIPAddress": true }, - "editor": { - "spellcheckerUrl": "http://127.0.0.1:8080" - }, "sockjs": { "sockjs_url": "/office/vendor/sockjs/sockjs.min.js" } @@ -62,6 +62,7 @@ "x2tPath": "../../FileConverter/bin/x2t", "docbuilderPath": "../../FileConverter/Bin/docbuilder", "docbuilderAllFontsPath": "../../App_Data/docbuilder/AllFonts.js", + "docbuilderCoreFontsPath": "../../../core-fonts", "errorfiles": "error" } }, diff --git a/Common/config/development-windows.json b/Common/config/development-windows.json index 2712b6917..2647b67a2 100644 --- a/Common/config/development-windows.json +++ b/Common/config/development-windows.json @@ -24,6 +24,9 @@ "/sdkjs-plugins": { "path": "../../../sdkjs-plugins" }, + "/dictionaries": { + "path": "../../../dictionaries" + }, "/info": { "path": "../../branding/info" } @@ -42,9 +45,6 @@ "allowPrivateIPAddress": true, "allowMetaIPAddress": true }, - "editor": { - "spellcheckerUrl": "http://127.0.0.1:8080" - }, "sockjs": { "sockjs_url": "/web-apps/vendor/sockjs/sockjs.min.js" } @@ -62,6 +62,7 @@ "x2tPath": "../../FileConverter/Bin/x2t.exe", "docbuilderPath": "../../FileConverter/Bin/docbuilder.exe", "docbuilderAllFontsPath": "../../App_Data/docbuilder/AllFonts.js", + "docbuilderCoreFontsPath": "../../../core-fonts", "errorfiles": "error" } }, diff --git a/Common/config/production-linux.json b/Common/config/production-linux.json index 0a13aa542..0e2a99705 100644 --- a/Common/config/production-linux.json +++ b/Common/config/production-linux.json @@ -34,6 +34,10 @@ "/sdkjs-plugins": { "path": "/var/www/onlyoffice/documentserver/sdkjs-plugins", "options": {"maxAge": "7d"} + }, + "/dictionaries": { + "path": "/var/www/onlyoffice/documentserver/server/SpellChecker/dictionaries", + "options": {"maxAge": "7d"} } } }, @@ -56,7 +60,8 @@ "presentationThemesDir": "/var/www/onlyoffice/documentserver/sdkjs/slide/themes", "x2tPath": "/var/www/onlyoffice/documentserver/server/FileConverter/bin/x2t", "docbuilderPath": "/var/www/onlyoffice/documentserver/server/FileConverter/bin/docbuilder", - "docbuilderAllFontsPath": "/var/lib/onlyoffice/documentserver/App_Data/docbuilder/AllFonts.js" + "docbuilderAllFontsPath": "/var/lib/onlyoffice/documentserver/App_Data/docbuilder/AllFonts.js", + "docbuilderCoreFontsPath": "/var/www/onlyoffice/documentserver/core-fonts" } }, "FileStorage": { diff --git a/Common/config/production-windows.json b/Common/config/production-windows.json index cb99ede61..22fd43e77 100644 --- a/Common/config/production-windows.json +++ b/Common/config/production-windows.json @@ -27,6 +27,10 @@ "path": "../../sdkjs-plugins", "options": {"maxAge": "7d"} }, + "/dictionaries": { + "path": "../SpellChecker/dictionaries", + "options": {"maxAge": "7d"} + }, "/welcome": { "path": "../welcome", "options": {"maxAge": "7d"} @@ -56,7 +60,8 @@ "presentationThemesDir": "../../sdkjs/slide/themes", "x2tPath": "../FileConverter/bin/x2t.exe", "docbuilderPath": "../FileConverter/bin/docbuilder.exe", - "docbuilderAllFontsPath": "../App_Data/docbuilder/AllFonts.js" + "docbuilderAllFontsPath": "../App_Data/docbuilder/AllFonts.js", + "docbuilderCoreFontsPath": "../../core-fonts" } }, "SpellChecker": { diff --git a/Common/npm-shrinkwrap.json b/Common/npm-shrinkwrap.json index 270d857d1..422937b4c 100644 --- a/Common/npm-shrinkwrap.json +++ b/Common/npm-shrinkwrap.json @@ -22,7 +22,7 @@ "amqplib": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", - "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", + "integrity": "sha1-0tcxPH/6pNELzx5iUt5FkbbMe2M=", "requires": { "bitsyntax": "~0.0.4", "bluebird": "^3.4.6", @@ -39,11 +39,22 @@ "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", - "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "integrity": "sha1-jSR136tVO7M+d7VOWeiAu4ziMTY=", "requires": { "safer-buffer": "~2.1.0" } }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", @@ -57,7 +68,7 @@ "aws-sdk": { "version": "2.346.0", "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.346.0.tgz", - "integrity": "sha512-4nJfbsK5Chu1ujIHHuvzRz7Ypu9Rbb8KQ/9T5QkVKUaQkl7AUnaUyENykIjhUybQlyg6uqPXg4JTK0801P+OfA==", + "integrity": "sha1-jhSfKOR6xMrph2ZBMr2YNmUSuPA=", "requires": { "buffer": "4.9.1", "events": "1.1.1", @@ -78,12 +89,12 @@ "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "integrity": "sha1-8OAD2cqef1nHpQiUXXsu+aBKVC8=" }, "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", - "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==" + "integrity": "sha1-yrHmEY8FEJXli1KBrqjBzSK/wOM=" }, "bcrypt-pbkdf": { "version": "1.0.2", @@ -104,7 +115,12 @@ "bluebird": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", - "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==" + "integrity": "sha1-G+CQjgVKdRdUVJwnBInBUF1KsVo=" + }, + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==" }, "buffer": { "version": "4.9.1", @@ -141,7 +157,7 @@ "circular-json": { "version": "0.5.9", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.9.tgz", - "integrity": "sha512-4ivwqHpIFJZBuhN3g/pEcdbnGUywkBblloGbkglyloVjjR3uT6tieI89MVOfbP2tHX5sgb01FuLgAOzebNlJNQ==" + "integrity": "sha1-kydjroj0996teg0JyKUaR0OlOx0=" }, "clone": { "version": "2.1.2", @@ -156,7 +172,7 @@ "combined-stream": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "integrity": "sha1-LR0kMXr7ir6V1tLAsHtXgTU52Cg=", "requires": { "delayed-stream": "~1.0.0" } @@ -164,7 +180,7 @@ "config": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/config/-/config-2.0.1.tgz", - "integrity": "sha512-aTaviJnC8ZjQYx8kQf4u6tWqIxWolyQQ3LqXgnCLAsIb78JrUshHG0YuzIarzTaVVe1Pazms3TXImfYra8UsyQ==", + "integrity": "sha1-mVzMgXVGBXjWRqwKLkAY/6RMoEY=", "requires": { "json5": "^1.0.1" } @@ -190,7 +206,7 @@ "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=", "requires": { "ms": "^2.1.1" } @@ -239,7 +255,7 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=" }, "extsprintf": { "version": "1.3.0", @@ -264,7 +280,7 @@ "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=", "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -279,7 +295,7 @@ "fs-extra": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.0.tgz", - "integrity": "sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==", + "integrity": "sha1-jMP0fOB+97NZOhG5+yRffjTAQdY=", "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -307,7 +323,7 @@ "har-validator": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.0.tgz", - "integrity": "sha512-+qnmNjI4OfH2ipQ9VQOw23bBd/ibtfbVdK2fYbY4acTDqKTW/YDp9McimZdDbG8iV9fZizUqQMD5xvriB146TA==", + "integrity": "sha1-RGV/VoiiLP1LckhugbOj+xF0LCk=", "requires": { "ajv": "^5.3.0", "har-schema": "^2.0.0" @@ -328,6 +344,11 @@ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=" }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", @@ -381,7 +402,7 @@ "json5": { "version": "1.0.1", "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "integrity": "sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4=", "requires": { "minimist": "^1.2.0" } @@ -397,7 +418,7 @@ "jsonwebtoken": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz", - "integrity": "sha512-oge/hvlmeJCH+iIz1DwcO7vKPkNGJHhgkspk8OH3VKlw+mbi42WtD4ig1+VXRln765vxptAv+xT26Fd3cteqag==", + "integrity": "sha1-BWyQ7ummXtbmxy3bCh0yUQmq9kM=", "requires": { "jws": "^3.1.5", "lodash.includes": "^4.3.0", @@ -424,7 +445,7 @@ "jwa": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz", - "integrity": "sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw==", + "integrity": "sha1-hyQOdsmAjb3hh4PPImTvSSnuUOY=", "requires": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.10", @@ -434,16 +455,16 @@ "jws": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz", - "integrity": "sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ==", + "integrity": "sha1-gNEtBbKT0ehB58uLTmnlYa3Pg08=", "requires": { "jwa": "^1.1.5", "safe-buffer": "^5.0.1" } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash._baseclone": { "version": "4.5.7", @@ -496,7 +517,7 @@ "log4js": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/log4js/-/log4js-3.0.6.tgz", - "integrity": "sha512-ezXZk6oPJCWL483zj64pNkMuY/NcRX5MPiB0zE6tjZM137aeusrOnW1ecxgF9cmwMWkBMhjteQxBPoZBh9FDxQ==", + "integrity": "sha1-5srO2Uln7uuc45n5+GgqSysoyP8=", "requires": { "circular-json": "^0.5.5", "date-format": "^1.2.0", @@ -508,45 +529,43 @@ "mime": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", - "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==" + "integrity": "sha1-sWIcVNY7l8R9PP5/chX31kUXw2k=" }, "mime-db": { "version": "1.37.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" + "integrity": "sha1-C2oM5v2+lXbiXx8tL96IMNwK0Ng=" }, "mime-types": { "version": "2.1.21", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "integrity": "sha1-KJlaoey3cHQv5q5+WPkYHHRLP5Y=", "requires": { "mime-db": "~1.37.0" } }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, "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==" }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "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": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } + "minimist": "^1.2.5" } }, "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=" }, "node-cache": { "version": "4.2.1", @@ -557,6 +576,19 @@ "lodash": "^4.17.15" } }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + }, + "node-localstorage": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-localstorage/-/node-localstorage-1.3.1.tgz", + "integrity": "sha512-NMWCSWWc6JbHT5PyWlNT2i8r7PgGYXVntmKawY83k/M0UJScZ5jirb61TLnqKwd815DfBQu+lR3sRw08SPzIaQ==", + "requires": { + "write-file-atomic": "^1.1.4" + } + }, "node-statsd": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/node-statsd/-/node-statsd-0.1.1.tgz", @@ -565,7 +597,17 @@ "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "integrity": "sha1-R6ewFrqmi1+g7PPe4IqFxnmsZFU=" + }, + "openpgp": { + "version": "4.10.8", + "resolved": "https://registry.npmjs.org/openpgp/-/openpgp-4.10.8.tgz", + "integrity": "sha512-l+/u3TyR3+qS7mN0+HoNQRu/2BzHdLOMOOCDRLDE9gZGAqpKkD9ZD7hkpjan+GGY3f0nHaE7Qv7kI6qmQK+AkA==", + "requires": { + "asn1.js": "^5.0.0", + "node-fetch": "^2.1.2", + "node-localstorage": "~1.3.0" + } }, "performance-now": { "version": "2.1.0", @@ -575,12 +617,12 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" }, "psl": { "version": "1.1.29", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==" + "integrity": "sha1-YPWA02AXC7cip5fMcEQR5tqFDGc=" }, "punycode": { "version": "1.3.2", @@ -590,7 +632,7 @@ "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=" }, "querystring": { "version": "0.2.0", @@ -611,7 +653,7 @@ "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "integrity": "sha1-nC/KT301tZLv5Xx/ClXoEFIST+8=", "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -638,7 +680,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=" } } }, @@ -660,12 +702,12 @@ "rfdc": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.1.2.tgz", - "integrity": "sha512-92ktAgvZhBzYTIK0Mja9uen5q5J3NRVMoDkJL2VMwq6SXjVCgqvQeVP2XAaUY6HT+XpQYeLSjb3UoitBryKmdA==" + "integrity": "sha1-5uctdPXcOd6PU49l4Aw2wYAY40k=" }, "rhea": { "version": "0.3.9", "resolved": "https://registry.npmjs.org/rhea/-/rhea-0.3.9.tgz", - "integrity": "sha512-16mqaARtj9ZgiYmD5F9uwcgvy5pOB64mWIbkBgrje4zEByIBjHdYB25EyeWb3baiI9OYAYMWb2rnqBfyv5weOg==", + "integrity": "sha1-JUe5dq3sT1wixqGn7JKmSHbBbRE=", "requires": { "debug": "0.8.0 - 3.5.0" } @@ -673,22 +715,27 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, + "slide": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", + "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=" + }, "sshpk": { "version": "1.15.2", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", - "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", + "integrity": "sha1-yUbWvZsaOdDoY1dj9SQtbtbctik=", "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -704,7 +751,7 @@ "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", - "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", + "integrity": "sha1-odG3z4PTmvsNYwSaWsv5NJO99ks=", "requires": { "date-format": "^1.2.0", "debug": "^3.1.0", @@ -720,7 +767,7 @@ "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -734,7 +781,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "requires": { "safe-buffer": "~5.1.0" } @@ -749,7 +796,7 @@ "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "integrity": "sha1-U/Nto/R3g7CSWvoG/587FlKA94E=", "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -778,12 +825,12 @@ "universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + "integrity": "sha1-tkb2m+OULavOzJ1mOcgNwQXvqmY=" }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", "requires": { "punycode": "^2.1.0" }, @@ -791,7 +838,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=" } } }, @@ -812,7 +859,7 @@ "uuid": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + "integrity": "sha1-PdPT55Crwk17DToDT/q6vijrvAQ=" }, "verror": { "version": "1.10.0", @@ -824,10 +871,20 @@ "extsprintf": "^1.2.0" } }, + "write-file-atomic": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", + "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "slide": "^1.1.5" + } + }, "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "integrity": "sha1-aGwg8hMgnpSr8NG88e+qKRx4J6c=", "requires": { "sax": ">=0.6.0", "xmlbuilder": "~9.0.1" diff --git a/Common/package.json b/Common/package.json index ba743d3ae..b3a44bef9 100644 --- a/Common/package.json +++ b/Common/package.json @@ -1,7 +1,7 @@ { "name": "common", "version": "1.0.1", - "homepage": "http://www.onlyoffice.com", + "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", @@ -21,6 +21,7 @@ "ms": "^2.1.1", "node-cache": "^4.2.1", "node-statsd": "^0.1.1", + "openpgp": "^4.10.8", "request": "^2.88.0", "request-filtering-agent": "^1.0.5", "rhea": "^0.3.9", diff --git a/Common/sources/commondefines.js b/Common/sources/commondefines.js index a57f35341..ec6a87015 100644 --- a/Common/sources/commondefines.js +++ b/Common/sources/commondefines.js @@ -38,11 +38,13 @@ function InputCommand(data, copyExplicit) { //must be set explicitly to prevent vulnerability(downloadAs(with url) creates request to integrator with authorization) this['withAuthorization'] = undefined;//bool this['isbuilder'] = undefined;//bool + this['externalChangeInfo'] = undefined;//zero DB changes case: set password, undo all changes if (data) { this['c'] = data['c']; this['id'] = data['id']; this['userid'] = data['userid']; this['userindex'] = data['userindex']; + this['username'] = data['username']; this['tokenSession'] = data['tokenSession']; this['tokenDownload'] = data['tokenDownload']; this['tokenHistory'] = data['tokenHistory']; @@ -73,6 +75,7 @@ function InputCommand(data, copyExplicit) { this['status_info'] = data['status_info']; this['savekey'] = data['savekey']; this['userconnectionid'] = data['userconnectionid']; + this['responsekey'] = data['responsekey']; this['docconnectionid'] = data['docconnectionid']; this['jsonparams'] = data['jsonparams']; this['lcid'] = data['lcid']; @@ -86,6 +89,8 @@ function InputCommand(data, copyExplicit) { this['userdata'] = data['userdata']; this['inline'] = data['inline']; this['password'] = data['password']; + this['savepassword'] = data['savepassword']; + this['withoutPassword'] = data['withoutPassword']; this['outputurls'] = data['outputurls']; this['closeonerror'] = data['closeonerror']; this['serverVersion'] = data['serverVersion']; @@ -97,12 +102,14 @@ function InputCommand(data, copyExplicit) { if (copyExplicit) { this['withAuthorization'] = data['withAuthorization']; this['isbuilder'] = data['isbuilder']; + this['externalChangeInfo'] = data['externalChangeInfo']; } } else { this['c'] = undefined;//string command this['id'] = undefined;//string document id this['userid'] = undefined;//string this['userindex'] = undefined; + this['username'] = undefined; this['tokenSession'] = undefined;//string validate this['tokenDownload'] = undefined;//string validate this['tokenHistory'] = undefined;//string validate @@ -129,6 +136,7 @@ function InputCommand(data, copyExplicit) { this['status_info'] = undefined;//int this['savekey'] = undefined;//int document id to save this['userconnectionid'] = undefined;//string internal + this['responsekey'] = undefined; this['docconnectionid'] = undefined;//string internal this['jsonparams'] = undefined;//string this['lcid'] = undefined; @@ -138,6 +146,8 @@ function InputCommand(data, copyExplicit) { this['userdata'] = undefined; this['inline'] = undefined;//content disposition this['password'] = undefined; + this['savepassword'] = undefined; + this['withoutPassword'] = undefined; this['outputurls'] = undefined; this['closeonerror'] = undefined; this['serverVersion'] = undefined; @@ -176,6 +186,12 @@ InputCommand.prototype = { setUserIndex: function(data) { this['userindex'] = data; }, + getUserName: function() { + return this['username']; + }, + setUserName: function(data) { + this['username'] = data; + }, getTokenSession: function() { return this['tokenSession']; }, @@ -299,6 +315,12 @@ InputCommand.prototype = { setUserConnectionId: function(data) { this['userconnectionid'] = data; }, + getResponseKey: function() { + return this['responsekey']; + }, + setResponseKey: function(data) { + this['responsekey'] = data; + }, getDocConnectionId: function() { return this['docconnectionid']; }, @@ -353,6 +375,18 @@ InputCommand.prototype = { setPassword: function(data) { this['password'] = data; }, + getSavePassword: function() { + return this['savepassword']; + }, + setSavePassword: function(data) { + this['savepassword'] = data; + }, + getWithoutPassword: function() { + return this['withoutPassword']; + }, + setWithoutPassword: function(data) { + this['withoutPassword'] = data; + }, setOutputUrls: function(data) { this['outputurls'] = data; }, @@ -406,6 +440,12 @@ InputCommand.prototype = { }, setWithAuthorization: function(data) { this['withAuthorization'] = data; + }, + getExternalChangeInfo: function() { + return this['externalChangeInfo']; + }, + setExternalChangeInfo: function(data) { + this['externalChangeInfo'] = data; } }; @@ -868,7 +908,9 @@ const c_oPublishType = { meta: 11, forceSave: 12, closeConnection: 13, - changesNotify: 14 + changesNotify: 14, + changeConnecitonInfo: 15, + rpc: 16 }; const c_oAscCsvDelimiter = { None: 0, @@ -970,7 +1012,8 @@ const c_oAscServerCommandErrors = { const c_oAscForceSaveTypes = { Command: 0, Button: 1, - Timeout: 2 + Timeout: 2, + Form: 3 }; const c_oAscUrlTypes = { Session: 0, diff --git a/Common/sources/constants.js b/Common/sources/constants.js index 2b79e02ef..f976ed9a9 100644 --- a/Common/sources/constants.js +++ b/Common/sources/constants.js @@ -159,6 +159,7 @@ exports.NO_ERROR = 0; exports.UNKNOWN = -1; exports.READ_REQUEST_STREAM = -3; exports.WEB_REQUEST = -4; +exports.CHANGE_DOC_INFO = -5; exports.TASK_QUEUE = -20; exports.TASK_RESULT = -40; exports.STORAGE = -60; @@ -194,6 +195,7 @@ exports.VKEY_USER_COUNT_EXCEED = -123; exports.VKEY_TIME_EXPIRE = -124; exports.VKEY_TIME_INCORRECT = -125; exports.EDITOR_CHANGES = -160; +exports.PASSWORD = -180; exports.QUEUE_PRIORITY_VERY_LOW = 0; exports.QUEUE_PRIORITY_LOW = 1; @@ -256,6 +258,7 @@ exports.CONTENT_DISPOSITION_ATTACHMENT = 'attachment'; exports.CONN_CLOSED = 3; +exports.FILE_STATUS_OK = 'ok'; exports.FILE_STATUS_UPDATE_VERSION = 'updateversion'; exports.ACTIVEMQ_QUEUE_PREFIX = 'queue://'; diff --git a/Common/sources/storage-base.js b/Common/sources/storage-base.js index 9cab0d8b5..785e6e9a9 100644 --- a/Common/sources/storage-base.js +++ b/Common/sources/storage-base.js @@ -78,13 +78,13 @@ exports.deletePath = function(strPath) { return exports.deleteObjects(list); }); }; -exports.getSignedUrl = function(baseUrl, strPath, urlType, optFilename, opt_type) { - return storage.getSignedUrl(baseUrl, getStoragePath(strPath), urlType, optFilename, opt_type); +exports.getSignedUrl = function(baseUrl, strPath, urlType, optFilename, opt_type, opt_creationDate) { + return storage.getSignedUrl(baseUrl, getStoragePath(strPath), urlType, optFilename, opt_type, opt_creationDate); }; -exports.getSignedUrls = function(baseUrl, strPath, urlType) { +exports.getSignedUrls = function(baseUrl, strPath, urlType, opt_creationDate) { return exports.listObjects(getStoragePath(strPath)).then(function(list) { return Promise.all(list.map(function(curValue) { - return exports.getSignedUrl(baseUrl, curValue, urlType); + return exports.getSignedUrl(baseUrl, curValue, urlType, undefined, undefined, opt_creationDate); })).then(function(urls) { var outputMap = {}; for (var i = 0; i < list.length && i < urls.length; ++i) { diff --git a/Common/sources/storage-fs.js b/Common/sources/storage-fs.js index 6e20b795e..784e9ca86 100644 --- a/Common/sources/storage-fs.js +++ b/Common/sources/storage-fs.js @@ -155,16 +155,20 @@ exports.deleteObject = function(strPath) { exports.deleteObjects = function(strPaths) { return Promise.all(strPaths.map(exports.deleteObject)); }; -exports.getSignedUrl = function(baseUrl, strPath, urlType, optFilename, opt_type) { +exports.getSignedUrl = function(baseUrl, strPath, urlType, optFilename, opt_type, opt_creationDate) { return new Promise(function(resolve, reject) { //replace '/' with %2f before encodeURIComponent becase nginx determine %2f as '/' and get wrong system path var userFriendlyName = optFilename ? encodeURIComponent(optFilename.replace(/\//g, "%2f")) : path.basename(strPath); var uri = '/' + cfgBucketName + '/' + cfgStorageFolderName + '/' + strPath + '/' + userFriendlyName; var url = (cfgStorageExternalHost ? cfgStorageExternalHost : baseUrl) + uri; - var date = new Date(); - var expires = Math.ceil(date.getTime() / 1000); - expires += (commonDefines.c_oAscUrlTypes.Session === urlType ? (cfgExpSessionAbsolute / 1000) : cfgStorageUrlExpires) || 31536000; + var date = Date.now(); + let creationDate = opt_creationDate || date; + let expiredAfter = (commonDefines.c_oAscUrlTypes.Session === urlType ? (cfgExpSessionAbsolute / 1000) : cfgStorageUrlExpires) || 31536000; + //todo creationDate can be greater because mysql CURRENT_TIMESTAMP uses local time, not UTC + var expires = creationDate + Math.ceil(Math.abs(date - creationDate)/expiredAfter) * expiredAfter; + expires = Math.ceil(expires / 1000); + expires += expiredAfter; var md5 = crypto.createHash('md5').update(expires + decodeURIComponent(uri) + cfgStorageSecretString).digest("base64"); md5 = md5.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); diff --git a/Common/sources/storage-s3.js b/Common/sources/storage-s3.js index 69fc35d8e..5a651fe2c 100644 --- a/Common/sources/storage-s3.js +++ b/Common/sources/storage-s3.js @@ -204,7 +204,7 @@ exports.deleteObjects = function(strPaths) { } return Promise.all(deletePromises); }; -exports.getSignedUrl = function(baseUrl, strPath, urlType, optFilename, opt_type) { +exports.getSignedUrl = function(baseUrl, strPath, urlType, optFilename, opt_type, opt_creationDate) { return new Promise(function(resolve, reject) { var expires = (commonDefines.c_oAscUrlTypes.Session === urlType ? cfgExpSessionAbsolute : cfgStorageUrlExpires) || 31536000; var userFriendlyName = optFilename ? optFilename.replace(/\//g, "%2f") : path.basename(strPath); diff --git a/Common/sources/utils.js b/Common/sources/utils.js index 15bb019f8..a80ce1fc1 100644 --- a/Common/sources/utils.js +++ b/Common/sources/utils.js @@ -58,6 +58,7 @@ const logger = require('./logger'); const forwarded = require('forwarded'); const mime = require('mime'); const { RequestFilteringHttpAgent, RequestFilteringHttpsAgent } = require("request-filtering-agent"); +const openpgp = require('openpgp'); var configIpFilter = config.get('services.CoAuthoring.ipfilter'); var cfgIpFilterRules = configIpFilter.get('rules'); @@ -76,8 +77,13 @@ var cfgRequestDefaults = config.get('services.CoAuthoring.requestDefaults'); const cfgTokenOutboxInBody = config.get('services.CoAuthoring.token.outbox.inBody'); const cfgTokenEnableRequestOutbox = config.get('services.CoAuthoring.token.enable.request.outbox'); const cfgTokenOutboxUrlExclusionRegex = config.get('services.CoAuthoring.token.outbox.urlExclusionRegex'); +const cfgPasswordEncrypt = config.get('openpgpjs.encrypt'); +const cfgPasswordDecrypt = config.get('openpgpjs.decrypt'); +const cfgPasswordConfig = config.get('openpgpjs.config'); const cfgRequesFilteringAgent = config.get('services.CoAuthoring.request-filtering-agent'); +Object.assign(openpgp.config, cfgPasswordConfig); + var ANDROID_SAFE_FILENAME = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ._-+,@£$€!½§~\'=()[]{}0123456789'; var baseRequest = request.defaults(cfgRequestDefaults); @@ -849,3 +855,16 @@ exports.canIncludeOutboxAuthorization = function (url) { } return false; }; +exports.encryptPassword = co.wrap(function* (password) { + let params = {message: openpgp.message.fromText(password)}; + Object.assign(params, cfgPasswordEncrypt); + const { data: encrypted } = yield openpgp.encrypt(params); + return encrypted; +}); +exports.decryptPassword = co.wrap(function* (password) { + const message = yield openpgp.message.readArmored(password); + let params = {message: message}; + Object.assign(params, cfgPasswordDecrypt); + const { data: decrypted } = yield openpgp.decrypt(params); + return decrypted; +}); diff --git a/DocService/npm-shrinkwrap.json b/DocService/npm-shrinkwrap.json index 08ca6176b..17b0e2878 100644 --- a/DocService/npm-shrinkwrap.json +++ b/DocService/npm-shrinkwrap.json @@ -5,12 +5,27 @@ "requires": true, "dependencies": { "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", "requires": { - "mime-types": "~2.1.18", - "negotiator": "0.6.1" + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "dependencies": { + "mime-db": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", + "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==" + }, + "mime-types": { + "version": "2.1.29", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", + "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "requires": { + "mime-db": "1.46.0" + } + } } }, "array-flatten": { @@ -21,12 +36,12 @@ "base64-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base64-stream/-/base64-stream-1.0.0.tgz", - "integrity": "sha512-BQQZftaO48FcE1Kof9CmXMFaAdqkcNorgc8CxesZv9nMbbTF1EFyQe89UOuh//QMmdtfUDXyO8rgUalemL5ODA==" + "integrity": "sha1-FXrgC8eIhpXohOH8xRxVH9+oofo=" }, "bignumber.js": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz", - "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA==" + "integrity": "sha1-228UBnwUC9RmJIFaeRbJLZtsJLE=" }, "body-parser": { "version": "1.18.3", @@ -75,25 +90,28 @@ "config": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/config/-/config-2.0.1.tgz", - "integrity": "sha512-aTaviJnC8ZjQYx8kQf4u6tWqIxWolyQQ3LqXgnCLAsIb78JrUshHG0YuzIarzTaVVe1Pazms3TXImfYra8UsyQ==", + "integrity": "sha1-mVzMgXVGBXjWRqwKLkAY/6RMoEY=", "requires": { "json5": "^1.0.1" } }, "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=" + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "requires": { + "safe-buffer": "5.1.2" + } }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" }, "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=" + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==" }, "cookie-signature": { "version": "1.0.6", @@ -108,7 +126,7 @@ "cron": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/cron/-/cron-1.5.0.tgz", - "integrity": "sha512-j7zMFLrcSta53xqOvETUt8ge+PM14GtF47gEGJJeVlM6qP24/eWHSgtiWiEiKBR2sHS8xZaBQZq4D7vFXg8dcQ==", + "integrity": "sha1-UKyxXsZAz/H29CCRyd8rge0wMGY=", "requires": { "moment-timezone": "^0.5.x" } @@ -116,7 +134,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "requires": { "ms": "2.0.0" }, @@ -177,46 +195,126 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, "express": { - "version": "4.16.4", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", - "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", "requires": { - "accepts": "~1.3.5", + "accepts": "~1.3.7", "array-flatten": "1.1.1", - "body-parser": "1.18.3", - "content-disposition": "0.5.2", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", "content-type": "~1.0.4", - "cookie": "0.3.1", + "cookie": "0.4.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "~1.1.2", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.1.1", + "finalhandler": "~1.1.2", "fresh": "0.5.2", "merge-descriptors": "1.0.1", "methods": "~1.1.2", "on-finished": "~2.3.0", - "parseurl": "~1.3.2", + "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.4", - "qs": "6.5.2", - "range-parser": "~1.2.0", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", "safe-buffer": "5.1.2", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "~1.4.0", - "type-is": "~1.6.16", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "dependencies": { - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + } + }, + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==" + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "mime-db": { + "version": "1.46.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.46.0.tgz", + "integrity": "sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==" + }, + "mime-types": { + "version": "2.1.29", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.29.tgz", + "integrity": "sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==", + "requires": { + "mime-db": "1.46.0" + } + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + } + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } } } }, @@ -257,24 +355,17 @@ } }, "finalhandler": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.4.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", "unpipe": "~1.0.0" - }, - "dependencies": { - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" - } } }, "forwarded": { @@ -301,12 +392,12 @@ "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==" + "integrity": "sha1-1l7b7ehDSdDcMDIIFaFdOcw8u9g=" }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "integrity": "sha1-KXhx9jvlB63Pv8pxXQzQ7thOmmM=", "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -317,9 +408,9 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ipaddr.js": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", - "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=" + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, "isarray": { "version": "1.0.0", @@ -329,7 +420,7 @@ "json5": { "version": "1.0.1", "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "integrity": "sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4=", "requires": { "minimist": "^1.2.0" } @@ -337,7 +428,7 @@ "jsonwebtoken": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz", - "integrity": "sha512-oge/hvlmeJCH+iIz1DwcO7vKPkNGJHhgkspk8OH3VKlw+mbi42WtD4ig1+VXRln765vxptAv+xT26Fd3cteqag==", + "integrity": "sha1-BWyQ7ummXtbmxy3bCh0yUQmq9kM=", "requires": { "jws": "^3.1.5", "lodash.includes": "^4.3.0", @@ -353,7 +444,7 @@ "jwa": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.1.6.tgz", - "integrity": "sha512-tBO/cf++BUsJkYql/kBbJroKOgHWEigTKBAjjBEmrMGYd1QMBC74Hr4Wo2zCZw6ZrVhlJPvoMrkcOnlWR/DJfw==", + "integrity": "sha1-hyQOdsmAjb3hh4PPImTvSSnuUOY=", "requires": { "buffer-equal-constant-time": "1.0.1", "ecdsa-sig-formatter": "1.0.10", @@ -363,7 +454,7 @@ "jws": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/jws/-/jws-3.1.5.tgz", - "integrity": "sha512-GsCSexFADNQUr8T5HPJvayTjvPIfoyJPtLQBwn5a4WZQchcrPMPMAWcC1AzJVRDKyD6ZPROPAxgv6rfHViO4uQ==", + "integrity": "sha1-gNEtBbKT0ehB58uLTmnlYa3Pg08=", "requires": { "jwa": "^1.1.5", "safe-buffer": "^5.0.1" @@ -422,25 +513,25 @@ "mime": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz", - "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==" + "integrity": "sha1-sWIcVNY7l8R9PP5/chX31kUXw2k=" }, "mime-db": { "version": "1.37.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==" + "integrity": "sha1-C2oM5v2+lXbiXx8tL96IMNwK0Ng=" }, "mime-types": { "version": "2.1.21", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "integrity": "sha1-KJlaoey3cHQv5q5+WPkYHHRLP5Y=", "requires": { "mime-db": "~1.37.0" } }, "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==" }, "moment": { "version": "2.22.2", @@ -450,7 +541,7 @@ "moment-timezone": { "version": "0.5.23", "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.23.tgz", - "integrity": "sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w==", + "integrity": "sha1-fLsA2ywUxxsZMDy0ew+wpthlFGM=", "requires": { "moment": ">= 2.9.0" } @@ -458,7 +549,7 @@ "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=" }, "multi-integer-range": { "version": "4.0.7", @@ -468,7 +559,7 @@ "multiparty": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/multiparty/-/multiparty-4.2.1.tgz", - "integrity": "sha512-AvESCnNoQlZiOfP9R4mxN8M9csy2L16EIbWIkt3l4FuGti9kXBS8QVzlfyg4HEnarJhrzZilgNFlZtqmoiAIIA==", + "integrity": "sha1-2bbEbYuN6rHucMc0sK93HdRuCxM=", "requires": { "fd-slicer": "1.1.0", "http-errors": "~1.7.0", @@ -479,7 +570,7 @@ "http-errors": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.1.tgz", - "integrity": "sha512-jWEUgtZWGSMba9I1N3gc1HmvpBUaNC9vDdA46yScAdp+C5rdEuKWUBLWTQpW9FwSWSbYYs++b6SDCxf9UEJzfw==", + "integrity": "sha1-ak/+XTUYjhw5+HJTRpBYWFLh8Cc=", "requires": { "depd": "~1.1.2", "inherits": "2.0.3", @@ -493,7 +584,7 @@ "mysql": { "version": "2.16.0", "resolved": "https://registry.npmjs.org/mysql/-/mysql-2.16.0.tgz", - "integrity": "sha512-dPbN2LHonQp7D5ja5DJXNbCLe/HRdu+f3v61aguzNRQIrmZLOeRoymBYyeThrR6ug+FqzDL95Gc9maqZUJS+Gw==", + "integrity": "sha1-sjsiq13kT8LV0yvU9a9mU/xF4ro=", "requires": { "bignumber.js": "4.1.0", "readable-stream": "2.3.6", @@ -502,9 +593,9 @@ } }, "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=" + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, "on-finished": { "version": "2.3.0", @@ -520,9 +611,9 @@ "integrity": "sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc=" }, "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=" + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, "path-to-regexp": { "version": "0.1.7", @@ -537,7 +628,7 @@ "pg": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/pg/-/pg-7.6.0.tgz", - "integrity": "sha512-INUjsobS7O0Slad6fVlSSSVpMd5wozwtdSrWL5/JfEGYCWtPwgka0uQOf2KCo7QbWUmwefcuNQtzijeztDquQg==", + "integrity": "sha1-DJ7K8M5vPH48aM6PYh33nnQaieM=", "requires": { "buffer-writer": "1.0.1", "packet-reader": "0.3.1", @@ -580,7 +671,7 @@ "postgres-array": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-1.0.3.tgz", - "integrity": "sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ==" + "integrity": "sha1-xWH8OyZrIUUfxlVThPSYbXjsgPU=" }, "postgres-bytea": { "version": "1.0.0", @@ -595,7 +686,7 @@ "postgres-interval": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.1.2.tgz", - "integrity": "sha512-fC3xNHeTskCxL1dC8KOtxXt7YeFmlbTYtn7ul8MkVERuTmf7pI4DrkAxcw3kh1fQ9uz4wQmd03a1mRiXUZChfQ==", + "integrity": "sha1-v3H/kCY18hyyQaAT/EIdgdHbFak=", "requires": { "xtend": "^4.0.0" } @@ -603,21 +694,21 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" }, "proxy-addr": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", - "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", "requires": { "forwarded": "~0.1.2", - "ipaddr.js": "1.8.0" + "ipaddr.js": "1.9.1" } }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=" }, "random-bytes": { "version": "1.0.0", @@ -625,14 +716,14 @@ "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" }, "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=" + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" }, "raw-body": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "integrity": "sha1-GzJOzmtXBuFThVvBFIxlu39uoMM=", "requires": { "bytes": "3.0.0", "http-errors": "1.6.3", @@ -650,7 +741,7 @@ "readable-stream": { "version": "2.3.6", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -681,7 +772,7 @@ "redis-commands": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.4.0.tgz", - "integrity": "sha512-cu8EF+MtkwI4DLIT0x9P8qNTLFhQD4jLfxLR0cCNkeGzs87FN6879JOJwNQR/1zD7aSYNbU0hgsV9zGY71Itvw==" + "integrity": "sha1-UvnPmRU+/M5WqPhq+Ya9BOmIYC8=" }, "redis-parser": { "version": "1.3.0", @@ -696,12 +787,12 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" }, "semver": { "version": "4.3.2", @@ -709,9 +800,9 @@ "integrity": "sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c=" }, "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", "requires": { "debug": "2.6.9", "depd": "~1.1.2", @@ -720,51 +811,63 @@ "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "range-parser": "~1.2.1", + "statuses": "~1.5.0" }, "dependencies": { - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==" + "http-errors": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", + "integrity": "sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==", + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" } } }, "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" + "parseurl": "~1.3.3", + "send": "0.17.1" } }, "setprototypeof": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" + "integrity": "sha1-0L2FU2iHtv58DYGMuWLZ2RxU5lY=" }, "sockjs": { "version": "0.3.19", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "integrity": "sha1-2Xa76ACve9IK4IWY1YI5NQiZPA0=", "requires": { "faye-websocket": "^0.10.0", "uuid": "^3.0.1" @@ -773,7 +876,7 @@ "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "integrity": "sha1-YFvZvjA6pZ+zX5Ip++oN3snqB9k=", "requires": { "through": "2" } @@ -791,7 +894,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "requires": { "safe-buffer": "~5.1.0" } @@ -804,12 +907,12 @@ "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==" + "integrity": "sha1-fhvjRw8ed5SLxD2Uo8j013UrpVM=" }, "type-is": { "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", + "integrity": "sha1-+JzjQVQcZysl7nrjxz3uOyvlAZQ=", "requires": { "media-typer": "0.3.0", "mime-types": "~2.1.18" @@ -818,7 +921,7 @@ "uid-safe": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "integrity": "sha1-Kz1cckDo/C5Y+Komnl7knAhXvTo=", "requires": { "random-bytes": "~1.0.0" } @@ -826,7 +929,7 @@ "underscore": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha512-5/4etnCkd9c8gwgowi5/om/mYO5ajCaOgdzj/oW+0eQV9WxKBDZw5+ycmKmeaTXjInS/W0BzpGLo2xR2aBwZdg==" + "integrity": "sha1-BtzjSg5op7q8KbNluOdLiSUgOWE=" }, "unpipe": { "version": "1.0.0", @@ -846,7 +949,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=" }, "vary": { "version": "1.1.2", @@ -865,7 +968,7 @@ "websocket-extensions": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==" + "integrity": "sha1-XS/yKXcAPsaHpLhwc9+7rBRszyk=" }, "windows-locale": { "version": "1.0.1", diff --git a/DocService/package.json b/DocService/package.json index dbef3527b..3afd7e810 100644 --- a/DocService/package.json +++ b/DocService/package.json @@ -1,7 +1,7 @@ { "name": "coauthoring", "version": "1.0.1", - "homepage": "http://www.onlyoffice.com", + "homepage": "https://www.onlyoffice.com", "private": true, "bin": { "docservice": "sources/server.js", @@ -16,7 +16,7 @@ "config": "^2.0.1", "cron": "^1.5.0", "deep-equal": "^1.0.1", - "express": "^4.16.4", + "express": "^4.17.1", "fakeredis": "^2.0.0", "jsonwebtoken": "^8.3.0", "jwa": "^1.1.6", diff --git a/DocService/sources/DocsCoServer.js b/DocService/sources/DocsCoServer.js index bd209ea18..688f3c780 100644 --- a/DocService/sources/DocsCoServer.js +++ b/DocService/sources/DocsCoServer.js @@ -78,7 +78,6 @@ const url = require('url'); const os = require('os'); const cluster = require('cluster'); const crypto = require('crypto'); -const cron = require('cron'); const co = require('co'); const jwt = require('jsonwebtoken'); const jwa = require('jwa'); @@ -148,6 +147,7 @@ const cfgForgottenFiles = config.get('server.forgottenfiles'); const cfgMaxRequestChanges = config.get('server.maxRequestChanges'); const cfgWarningLimitPercents = configCommon.get('license.warning_limit_percents') / 100; const cfgErrorFiles = configCommon.get('FileConverter.converter.errorfiles'); +const cfgOpenProtectedFile = config.get('server.openProtectedFile'); const EditorTypes = { document : 0, @@ -164,6 +164,7 @@ let pubsub; let queue; let licenseInfo = {type: constants.LICENSE_RESULT.Error, light: false, branding: false, customization: false, plugins: false}; let shutdownFlag = false; +let expDocumentsStep = gc.getCronStep(cfgExpDocumentsCron); const MIN_SAVE_EXPIRATION = 60000; const FORCE_SAVE_EXPIRATION = Math.min(Math.max(cfgForceSaveInterval, MIN_SAVE_EXPIRATION), @@ -448,6 +449,40 @@ function removePresence(conn) { }); } +let changeConnectionInfo = co.wrap(function*(conn, cmd) { + if (!conn.denyChangeName && conn.user) { + yield* publish({type: commonDefines.c_oPublishType.changeConnecitonInfo, docId: conn.docId, useridoriginal: conn.user.idOriginal, cmd: cmd}); + return true; + } + return false; +}); +function fillJwtByConnection(conn) { + var docId = conn.docId; + var payload = {document: {}, editorConfig: {user: {}}}; + 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; + //edit.lang = conn.lang; + //edit.mode = conn.mode; + var user = edit.user; + user.id = conn.user.idOriginal; + user.name = conn.user.username; + user.index = conn.user.indexUser; + //no standart + edit.ds_view = conn.user.view; + edit.ds_isCloseCoAuthoring = conn.isCloseCoAuthoring; + edit.ds_isEnterCorrectPassword = conn.isEnterCorrectPassword; + edit.ds_denyChangeName = conn.denyChangeName; + + var options = {algorithm: cfgTokenSessionAlgorithm, expiresIn: cfgTokenSessionExpires / 1000}; + var secret = utils.getSecretByElem(cfgSecretSession); + return jwt.sign(payload, secret, options); +} + function sendData(conn, data) { conn.write(JSON.stringify(data)); const type = data ? data.type : null; @@ -468,8 +503,11 @@ function sendDataMeta(conn, msg) { function sendDataSession(conn, msg) { sendData(conn, {type: "session", messages: msg}); } -function sendDataRefreshToken(conn, msg) { - sendData(conn, {type: "refreshToken", messages: msg}); +function sendDataRefreshToken(conn) { + sendData(conn, {type: "refreshToken", messages: fillJwtByConnection(conn)}); +} +function sendDataRpc(conn, responseKey, data) { + sendData(conn, {type: "rpc", responseKey: responseKey, data: data}); } function sendReleaseLock(conn, userLocks) { sendData(conn, {type: "releaseLock", locks: _.map(userLocks, function(e) { @@ -481,6 +519,14 @@ function sendReleaseLock(conn, userLocks) { }; })}); } +function modifyConnectionForPassword(conn, isEnterCorrectPassword) { + if (isEnterCorrectPassword) { + conn.isEnterCorrectPassword = true; + if (cfgTokenEnableBrowser) { + sendDataRefreshToken(conn); + } + } +} function getParticipants(docId, excludeClosed, excludeUserId, excludeViewer) { return _.filter(connections, function(el) { return el.docId === docId && el.isCloseCoAuthoring !== excludeClosed && @@ -661,21 +707,39 @@ function* getChangesIndex(docId) { } return res; } -function* setForceSave(docId, forceSave, cmd, success) { - if (success) { - yield editorData.checkAndSetForceSave(docId, forceSave.getTime(), forceSave.getIndex(), true, true); - } else { - yield editorData.checkAndSetForceSave(docId, forceSave.getTime(), forceSave.getIndex(), false, false); + +const hasChanges = co.wrap(function*(docId) { + //todo check editorData.getForceSave in case of "undo all changes" + let puckerIndex = yield* getChangesIndex(docId); + if (0 === puckerIndex) { + let selectRes = yield taskResult.select(docId); + if (selectRes.length > 0 && selectRes[0].password) { + return sqlBase.DocumentPassword.prototype.hasPasswordChanges(docId, selectRes[0].password); + } + return false; } + return true; +}); +function* setForceSave(docId, forceSave, cmd, success) { let forceSaveType = forceSave.getType(); + if (commonDefines.c_oAscForceSaveTypes.Form !== forceSaveType) { + if (success) { + yield editorData.checkAndSetForceSave(docId, forceSave.getTime(), forceSave.getIndex(), true, true); + } else { + yield editorData.checkAndSetForceSave(docId, forceSave.getTime(), forceSave.getIndex(), false, false); + } + } + if (commonDefines.c_oAscForceSaveTypes.Command !== forceSaveType) { - yield* publish({ - type: commonDefines.c_oPublishType.forceSave, docId: docId, - data: {type: forceSaveType, time: forceSave.getTime(), success: success} - }, cmd.getUserConnectionId()); + let data = {type: forceSaveType, time: forceSave.getTime(), success: success}; + if(commonDefines.c_oAscForceSaveTypes.Form === forceSaveType) { + yield* publish({type: commonDefines.c_oPublishType.rpc, docId: docId, data: data, responseKey: cmd.getResponseKey()}, cmd.getUserConnectionId()); + } else { + yield* publish({type: commonDefines.c_oPublishType.forceSave, docId: docId, data: data}, cmd.getUserConnectionId()); + } } } -function* startForceSave(docId, type, opt_userdata, opt_userId, opt_userConnectionId, opt_userIndex, opt_baseUrl, opt_queue, opt_pubsub) { +let startForceSave = co.wrap(function*(docId, type, opt_userdata, opt_userId, opt_userConnectionId, opt_userIndex, opt_responseKey, opt_baseUrl, opt_queue, opt_pubsub) { logger.debug('startForceSave start:docId = %s', docId); let res = {code: commonDefines.c_oAscServerCommandErrors.NoError, time: null}; let startedForceSave; @@ -686,7 +750,10 @@ function* startForceSave(docId, type, opt_userdata, opt_userId, opt_userConnecti return !!JSON.parse(currentValue).encrypted; }); if (!hasEncrypted) { - startedForceSave = yield editorData.checkAndStartForceSave(docId); + startedForceSave = commonDefines.c_oAscForceSaveTypes.Form === type; + if (!startedForceSave) { + startedForceSave = yield editorData.checkAndStartForceSave(docId); + } } } logger.debug('startForceSave canStart:docId = %s; hasEncrypted = %s; startedForceSave = %j', docId, hasEncrypted, startedForceSave); @@ -713,8 +780,8 @@ function* startForceSave(docId, type, opt_userdata, opt_userId, opt_userConnecti priority = constants.QUEUE_PRIORITY_LOW; } //start new convert - let status = yield* converterService.convertFromChanges(docId, baseUrl, forceSave, opt_userdata, - opt_userConnectionId, priority, expiration, opt_queue); + let status = yield* converterService.convertFromChanges(docId, baseUrl, forceSave, startedForceSave.changeInfo, opt_userdata, + opt_userConnectionId, opt_responseKey, priority, expiration, opt_queue); if (constants.NO_ERROR === status.err) { res.time = forceSave.getTime(); } else { @@ -726,6 +793,34 @@ function* startForceSave(docId, type, opt_userdata, opt_userId, opt_userConnecti } logger.debug('startForceSave end:docId = %s', docId); return res; +}); +function getExternalChangeInfo(user, date) { + return {user_id: user.id, user_id_original: user.idOriginal, user_name: user.username, change_date: date}; +} +let resetForceSaveAfterChanges = co.wrap(function*(docId, newChangesLastTime, puckerIndex, baseUrl, changeInfo) { + //last save + if (newChangesLastTime) { + yield editorData.setForceSave(docId, newChangesLastTime, puckerIndex, baseUrl, changeInfo); + if (cfgForceSaveEnable) { + let expireAt = newChangesLastTime + cfgForceSaveInterval; + yield editorData.addForceSaveTimerNX(docId, expireAt); + } + } +}); +function* startRPC(conn, responseKey, data) { + let docId = conn.docId; + logger.debug('startRPC start responseKey:%s , %j:docId = %s', responseKey, data, docId); + switch (data.type) { + case 'sendForm': + var forceSaveRes; + if (conn.user) { + forceSaveRes = yield startForceSave(docId, commonDefines.c_oAscForceSaveTypes.Form, undefined, conn.user.idOriginal, conn.user.id, conn.user.indexUser, responseKey); + } else { + sendDataRpc(conn, responseKey); + } + break; + } + logger.debug('startRPC end:docId = %s', docId); } function handleDeadLetter(data, ack) { return co(function*() { @@ -787,8 +882,8 @@ function* sendStatusDocument(docId, bChangeBase, opt_userAction, opt_userIndex, var status = c_oAscServerStatus.Editing; var participants = yield* getOriginalParticipantsId(docId); if (0 === participants.length) { - var puckerIndex = yield* getChangesIndex(docId); - if (!(puckerIndex > 0) || opt_forceClose) { + let bHasChanges = yield hasChanges(docId); + if (!bHasChanges || opt_forceClose) { status = c_oAscServerStatus.Closed; } } @@ -935,6 +1030,7 @@ function* cleanDocumentOnExit(docId, deleteChanges) { yield editorData.cleanDocumentOnExit(docId); //remove changes if (deleteChanges) { + yield taskResult.restoreInitialPassword(docId); sqlBase.deleteChanges(docId, null); //delete forgotten after successful send on callbackUrl yield storage.deletePath(cfgForgottenFiles + '/' + docId); @@ -1077,14 +1173,32 @@ function getLicenseNowUtc() { return Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds()) / 1000; } +let getParticipantMap = co.wrap(function*(docId, opt_hvals) { + const participantsMap = []; + let hvals; + if (opt_hvals) { + hvals = opt_hvals; + } else { + hvals = yield editorData.getPresence(docId, connections); + } + for (let i = 0; i < hvals.length; ++i) { + const elem = JSON.parse(hvals[i]); + if (!elem.isCloseCoAuthoring) { + participantsMap.push(elem); + } + } + return participantsMap; +}); exports.c_oAscServerStatus = c_oAscServerStatus; exports.editorData = editorData; exports.sendData = sendData; +exports.modifyConnectionForPassword = modifyConnectionForPassword; exports.parseUrl = parseUrl; exports.parseReplyData = parseReplyData; exports.sendServerRequest = sendServerRequest; exports.createSaveTimerPromise = co.wrap(_createSaveTimer); +exports.changeConnectionInfo = changeConnectionInfo; exports.publish = publish; exports.addTask = addTask; exports.addDelayed = addDelayed; @@ -1093,11 +1207,13 @@ exports.hasEditors = hasEditors; exports.getEditorsCountPromise = co.wrap(getEditorsCount); exports.getCallback = getCallback; exports.getIsShutdown = getIsShutdown; -exports.getChangesIndexPromise = co.wrap(getChangesIndex); +exports.hasChanges = hasChanges; exports.cleanDocumentOnExitPromise = co.wrap(cleanDocumentOnExit); exports.cleanDocumentOnExitNoChangesPromise = co.wrap(cleanDocumentOnExitNoChanges); exports.setForceSave = setForceSave; -exports.startForceSavePromise = co.wrap(startForceSave); +exports.startForceSave = startForceSave; +exports.resetForceSaveAfterChanges = resetForceSaveAfterChanges; +exports.getExternalChangeInfo = getExternalChangeInfo; exports.checkJwt = checkJwt; exports.getRequestParams = getRequestParams; exports.checkJwtHeader = checkJwtHeader; @@ -1147,6 +1263,7 @@ exports.install = function(server, callbackFunction) { conn.close(constants.ACCESS_DENIED_CODE, constants.ACCESS_DENIED_REASON); return; } + yield* encryptPasswordParams(data); switch (data.type) { case 'auth' : yield* auth(conn, data); @@ -1204,12 +1321,15 @@ exports.install = function(server, callbackFunction) { case 'forceSaveStart' : var forceSaveRes; if (conn.user) { - forceSaveRes = yield* startForceSave(docId, commonDefines.c_oAscForceSaveTypes.Button, undefined, conn.user.idOriginal, conn.user.id, conn.user.indexUser); + forceSaveRes = yield startForceSave(docId, commonDefines.c_oAscForceSaveTypes.Button, undefined, conn.user.idOriginal, conn.user.id, conn.user.indexUser); } else { forceSaveRes = {code: commonDefines.c_oAscServerCommandErrors.UnknownError, time: null}; } sendData(conn, {type: "forceSaveStart", messages: forceSaveRes}); break; + case 'rpc' : + yield* startRPC(conn, data.responseKey, data.data); + break; default: logger.debug("unknown command %s", message); break; @@ -1281,7 +1401,7 @@ exports.install = function(server, callbackFunction) { conn.isCloseCoAuthoring = true; yield addPresence(conn, true); if (cfgTokenEnableBrowser) { - sendDataRefreshToken(conn, fillJwtByConnection(conn)); + sendDataRefreshToken(conn); } } } @@ -1295,7 +1415,7 @@ exports.install = function(server, callbackFunction) { //revert old view to send event var tmpView = tmpUser.view; tmpUser.view = isView; - let participants = yield* getParticipantMap(docId, hvals); + let participants = yield getParticipantMap(docId, hvals); if (!participantsTimestamp) { participantsTimestamp = Date.now(); } @@ -1308,8 +1428,7 @@ exports.install = function(server, callbackFunction) { // Только если редактируем if (false === isView) { bHasEditors = yield* hasEditors(docId, hvals); - var puckerIndex = yield* getChangesIndex(docId); - bHasChanges = puckerIndex > 0; + bHasChanges = yield hasChanges(docId); let needSendStatus = true; if (conn.encrypted) { @@ -1389,7 +1508,7 @@ exports.install = function(server, callbackFunction) { conn.docId = docIdNew; yield addPresence(conn, true); if (cfgTokenEnableBrowser) { - sendDataRefreshToken(conn, fillJwtByConnection(conn)); + sendDataRefreshToken(conn); } } //open @@ -1439,23 +1558,6 @@ exports.install = function(server, callbackFunction) { return userLocks; } - function* getParticipantMap(docId, opt_hvals) { - const participantsMap = []; - let hvals; - if (opt_hvals) { - hvals = opt_hvals; - } else { - hvals = yield editorData.getPresence(docId, connections); - } - for (let i = 0; i < hvals.length; ++i) { - const elem = JSON.parse(hvals[i]); - if (!elem.isCloseCoAuthoring) { - participantsMap.push(elem); - } - } - return participantsMap; - } - function* checkEndAuthLock(unlock, isSave, docId, userId, releaseLocks, deleteIndex, conn) { let result = false; @@ -1474,7 +1576,7 @@ exports.install = function(server, callbackFunction) { if (unlock) { var unlockRes = yield editorData.unlockAuth(docId, userId); if (commonDefines.c_oAscUnlockRes.Unlocked === unlockRes) { - const participantsMap = yield* getParticipantMap(docId); + const participantsMap = yield getParticipantMap(docId); yield* publish({ type: commonDefines.c_oPublishType.auth, docId: docId, @@ -1790,6 +1892,8 @@ exports.install = function(server, callbackFunction) { if (null != edit.ds_isCloseCoAuthoring) { data.isCloseCoAuthoring = edit.ds_isCloseCoAuthoring; } + data.isEnterCorrectPassword = edit.ds_isEnterCorrectPassword; + data.denyChangeName = edit.ds_denyChangeName; if (edit.user) { var dataUser = data.user; var user = edit.user; @@ -1808,10 +1912,13 @@ exports.install = function(server, callbackFunction) { if (null != user.lastname) { dataUser.lastname = user.lastname; } - if (null != user.name) { + if (user.name) { dataUser.username = user.name; } } + if (edit.user && edit.user.name) { + data.denyChangeName = true; + } } //issuer for secret @@ -1837,29 +1944,17 @@ exports.install = function(server, callbackFunction) { } } } - function fillJwtByConnection(conn) { - var docId = conn.docId; - var payload = {document: {}, editorConfig: {user: {}}}; - 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; - //edit.lang = conn.lang; - //edit.mode = conn.mode; - var user = edit.user; - user.id = conn.user.idOriginal; - user.name = conn.user.username; - user.index = conn.user.indexUser; - //no standart - edit.ds_view = conn.user.view; - edit.ds_isCloseCoAuthoring = conn.isCloseCoAuthoring; - - var options = {algorithm: cfgTokenSessionAlgorithm, expiresIn: cfgTokenSessionExpires / 1000}; - var secret = utils.getSecretByElem(cfgSecretSession); - return jwt.sign(payload, secret, options); + + function* encryptPasswordParams(data) { + let dataWithPassword; + if (data.type === 'openDocument' && data.message) { + dataWithPassword = data.message; + } else if (data.type === 'auth' && data.openCmd) { + dataWithPassword = data.openCmd; + } + if (dataWithPassword && dataWithPassword.password) { + dataWithPassword.password = yield utils.encryptPassword(dataWithPassword.password); + } } function* auth(conn, data) { @@ -1911,17 +2006,20 @@ exports.install = function(server, callbackFunction) { return; } - const curUserId = String(user.id) + curIndexUser; + const curUserIdOriginal = String(user.id); + const curUserId = curUserIdOriginal + curIndexUser; conn.docId = data.docid; conn.permissions = data.permissions; conn.user = { id: curUserId, - idOriginal: user.id, + idOriginal: curUserIdOriginal, username: fillUsername(data), indexUser: curIndexUser, view: !isEditMode(data.permissions, data.mode, !data.view) }; conn.isCloseCoAuthoring = data.isCloseCoAuthoring; + conn.isEnterCorrectPassword = data.isEnterCorrectPassword; + conn.denyChangeName = data.denyChangeName; conn.editorType = data['editorType']; if (data.sessionTimeConnect) { conn.sessionTimeConnect = data.sessionTimeConnect; @@ -2076,7 +2174,7 @@ exports.install = function(server, callbackFunction) { connections.push(conn); let firstParticipantNoView, countNoView = 0; yield addPresence(conn, true); - let participantsMap = yield* getParticipantMap(docId); + let participantsMap = yield getParticipantMap(docId); const participantsTimestamp = Date.now(); for (let i = 0; i < participantsMap.length; ++i) { const elem = participantsMap[i]; @@ -2469,13 +2567,8 @@ exports.install = function(server, callbackFunction) { // Автоматически снимаем lock сами и посылаем индекс для сохранения yield* unSaveLock(conn, changesIndex, newChangesLastTime); //last save - if (newChangesLastTime) { - yield editorData.setForceSave(docId, newChangesLastTime, puckerIndex, utils.getBaseUrlByConnection(conn)); - if (cfgForceSaveEnable) { - let expireAt = newChangesLastTime + cfgForceSaveInterval; - yield editorData.addForceSaveTimerNX(docId, expireAt); - } - } + let changeInfo = getExternalChangeInfo(conn.user, newChangesLastTime); + yield resetForceSaveAfterChanges(docId, newChangesLastTime, puckerIndex, utils.getBaseUrlByConnection(conn), changeInfo); } else { let changesToSend = arrNewDocumentChanges; if(changesToSend.length > cfgPubSubMaxChanges) { @@ -2643,7 +2736,7 @@ exports.install = function(server, callbackFunction) { // ToDo docId from url ? const docIdParsed = urlParse.exec(conn.url); if (docIdParsed && 1 < docIdParsed.length) { - const participantsMap = yield* getParticipantMap(docIdParsed[1]); + const participantsMap = yield getParticipantMap(docIdParsed[1]); for (let i = 0; i < participantsMap.length; ++i) { const elem = participantsMap[i]; if (!elem.view) { @@ -2662,6 +2755,7 @@ exports.install = function(server, callbackFunction) { rights: rights, buildVersion: commonDefines.buildVersion, buildNumber: commonDefines.buildNumber, + protectionSupport: cfgOpenProtectedFile, //todo find a better place branding: licenseInfo.branding, customization: licenseInfo.customization, plugins: licenseInfo.plugins @@ -2726,7 +2820,7 @@ exports.install = function(server, callbackFunction) { var participant; var objChangesDocument; var i; - let lockDocumentTimer; + let lockDocumentTimer, cmd; switch (data.type) { case commonDefines.c_oPublishType.drop: for (i = 0; i < data.users.length; ++i) { @@ -2800,7 +2894,7 @@ exports.install = function(server, callbackFunction) { } break; case commonDefines.c_oPublishType.receiveTask: - var cmd = new commonDefines.InputCommand(data.cmd, true); + cmd = new commonDefines.InputCommand(data.cmd, true); var output = new canvasService.OutputDataWrap(); output.fromObject(data.output); var outputData = output.getData(); @@ -2821,13 +2915,14 @@ exports.install = function(server, callbackFunction) { participant = participants[i]; if (data.needUrlKey) { if (0 == data.needUrlMethod) { - outputData.setData(yield storage.getSignedUrls(participant.baseUrl, data.needUrlKey, data.needUrlType)); + outputData.setData(yield storage.getSignedUrls(participant.baseUrl, data.needUrlKey, data.needUrlType, data.creationDate)); } else if (1 == data.needUrlMethod) { - outputData.setData(yield storage.getSignedUrl(participant.baseUrl, data.needUrlKey, data.needUrlType)); + outputData.setData(yield storage.getSignedUrl(participant.baseUrl, data.needUrlKey, data.needUrlType, undefined, undefined, data.creationDate)); } else { var contentDisposition = cmd.getInline() ? constants.CONTENT_DISPOSITION_INLINE : constants.CONTENT_DISPOSITION_ATTACHMENT; - outputData.setData(yield storage.getSignedUrl(participant.baseUrl, data.needUrlKey, data.needUrlType, cmd.getTitle(), contentDisposition)); + outputData.setData(yield storage.getSignedUrl(participant.baseUrl, data.needUrlKey, data.needUrlType, cmd.getTitle(), contentDisposition, data.creationDate)); } + modifyConnectionForPassword(participant, data.needUrlIsCorrectPassword); } sendData(participant, output); } @@ -2874,6 +2969,34 @@ exports.install = function(server, callbackFunction) { sendData(participant, {type: "forceSave", messages: data.data}); }); break; + case commonDefines.c_oPublishType.changeConnecitonInfo: + let hasChanges = false; + cmd = new commonDefines.InputCommand(data.cmd, true); + participants = getParticipants(data.docId); + for (i = 0; i < participants.length; ++i) { + participant = participants[i]; + if (!participant.denyChangeName && participant.user.idOriginal === data.useridoriginal) { + hasChanges = true; + logger.debug('changeConnectionInfo: docId = %s, userId = %s', data.docId, data.useridoriginal); + participant.user.username = cmd.getUserName(); + yield addPresence(participant, false); + if (cfgTokenEnableBrowser) { + sendDataRefreshToken(participant); + } + } + } + if (hasChanges) { + let participants = yield getParticipantMap(data.docId); + let participantsTimestamp = Date.now(); + yield* publish({type: commonDefines.c_oPublishType.participantsState, docId: data.docId, userId: null, participantsTimestamp: participantsTimestamp, participants: participants}); + } + break; + case commonDefines.c_oPublishType.rpc: + participants = getParticipants(data.docId, true, data.userId, true); + _.each(participants, function(participant) { + sendDataRpc(participant, data.responseKey, data.data); + }); + break; default: logger.debug('pubsub unknown message type:%s', msg); } @@ -2888,15 +3011,13 @@ exports.install = function(server, callbackFunction) { yield editorData.setEditorConnections(countEdit, countView, now, PRECISION); } function expireDoc() { - var cronJob = this; return co(function* () { try { var countEditByShard = 0; var countViewByShard = 0; logger.debug('expireDoc connections.length = %d', connections.length); var nowMs = new Date().getTime(); - var nextMs = cronJob.nextDate(); - var maxMs = Math.max(nowMs + cfgExpSessionCloseCommand, nextMs); + var maxMs = nowMs + Math.max(cfgExpSessionCloseCommand, expDocumentsStep); for (var i = 0; i < connections.length; ++i) { var conn = connections[i]; if (cfgExpSessionAbsolute > 0) { @@ -2945,16 +3066,12 @@ exports.install = function(server, callbackFunction) { } } catch (err) { logger.error('expireDoc error:\r\n%s', err.stack); + } finally { + setTimeout(expireDoc, expDocumentsStep); } }); } - var innerPingJob = function(opt_isStart) { - if (!opt_isStart) { - logger.warn('expireDoc restart'); - } - new cron.CronJob(cfgExpDocumentsCron, expireDoc, innerPingJob, true); - }; - innerPingJob(true); + setTimeout(expireDoc, expDocumentsStep); pubsub = new pubsubService(); pubsub.on('message', pubsubOnMessage); @@ -3157,7 +3274,7 @@ exports.commandFromServer = function (req, res) { } break; case 'forcesave': - let forceSaveRes = yield* startForceSave(docId, commonDefines.c_oAscForceSaveTypes.Command, params.userdata, undefined, undefined, undefined, utils.getBaseUrlByRequest(req)); + let forceSaveRes = yield startForceSave(docId, commonDefines.c_oAscForceSaveTypes.Command, params.userdata, undefined, undefined, undefined, undefined, utils.getBaseUrlByRequest(req)); result = forceSaveRes.code; break; case 'meta': diff --git a/DocService/sources/baseConnector.js b/DocService/sources/baseConnector.js index 95c857fa6..eafc0b6e6 100644 --- a/DocService/sources/baseConnector.js +++ b/DocService/sources/baseConnector.js @@ -314,3 +314,55 @@ UserCallback.prototype.getCallbackByUserIndex = function(docId, callbacksStr, op return callbackUrl; }; exports.UserCallback = UserCallback; + +function DocumentPassword() { + this.password = undefined; + this.change = undefined; +} +DocumentPassword.prototype.fromString = function(passwordStr){ + var parsed = JSON.parse(passwordStr); + this.fromValues(parsed.password, parsed.change); +}; +DocumentPassword.prototype.fromValues = function(password, change){ + if(null !== password){ + this.password = password; + } + if(null !== change) { + this.change = change; + } +}; +DocumentPassword.prototype.delimiter = String.fromCharCode(5); +DocumentPassword.prototype.toSQLInsert = function(){ + return this.delimiter + JSON.stringify(this); +}; +DocumentPassword.prototype.isInitial = function(){ + return !this.change; +}; +DocumentPassword.prototype.getDocPassword = function(docId, docPasswordStr) { + let res = {initial: undefined, current: undefined, change: undefined}; + if (docPasswordStr) { + logger.debug("getDocPassword: docId = %s passwords = %s", docId, docPasswordStr); + let passwords = docPasswordStr.split(UserCallback.prototype.delimiter); + + for (let i = 1; i < passwords.length; ++i) { + let password = new DocumentPassword(); + password.fromString(passwords[i]); + if (password.isInitial()) { + res.initial = password.password; + } else { + res.change = password.change; + } + res.current = password.password; + } + } + return res; +}; +DocumentPassword.prototype.getCurPassword = function(docId, docPasswordStr) { + let docPassword = this.getDocPassword(docId, docPasswordStr); + return docPassword.current; +}; +DocumentPassword.prototype.hasPasswordChanges = function(docId, docPasswordStr) { + let docPassword = this.getDocPassword(docId, docPasswordStr); + return docPassword.initial !== docPassword.current; +}; +exports.DocumentPassword = DocumentPassword; diff --git a/DocService/sources/canvasservice.js b/DocService/sources/canvasservice.js index 865e1c008..9fd5f6afd 100644 --- a/DocService/sources/canvasservice.js +++ b/DocService/sources/canvasservice.js @@ -71,6 +71,7 @@ var SAVE_TYPE_COMPLETE_ALL = 3; var clientStatsD = statsDClient.getClient(); var redisKeyShutdown = cfgRedisPrefix + constants.REDIS_KEY_SHUTDOWN; +let hasPasswordCol = false;//stub on upgradev630.sql update failure const retryHttpStatus = new MultiRange(cfgCallbackBackoffOptions.httpStatus); @@ -128,8 +129,16 @@ OutputData.prototype = { } }; -function* getOutputData(cmd, outputData, key, status, statusInfo, optConn, optAdditionalOutput, opt_bIsRestore) { - var docId = cmd.getDocId(); +function* getOutputData(cmd, outputData, key, optConn, optAdditionalOutput, opt_bIsRestore) { + let status, statusInfo, password, creationDate; + let selectRes = yield taskResult.select(key); + if (selectRes.length > 0) { + let row = selectRes[0]; + status = row.status; + statusInfo = row.status_info; + password = sqlBase.DocumentPassword.prototype.getCurPassword(key, row.password); + creationDate = row.created_at && row.created_at.getTime(); + } switch (status) { case taskResult.FileStatus.SaveVersion: case taskResult.FileStatus.UpdateVersion: @@ -143,10 +152,10 @@ function* getOutputData(cmd, outputData, key, status, statusInfo, optConn, optAd outputData.setStatus(constants.FILE_STATUS_UPDATE_VERSION); } else { if (taskResult.FileStatus.UpdateVersion === status) { - logger.warn("UpdateVersion expired: docId = %s", docId); + logger.warn("UpdateVersion expired: docId = %s", key); } var updateMask = new taskResult.TaskResultData(); - updateMask.key = docId; + updateMask.key = key; updateMask.status = status; updateMask.statusInfo = statusInfo; var updateTask = new taskResult.TaskResultData(); @@ -177,12 +186,32 @@ function* getOutputData(cmd, outputData, key, status, statusInfo, optConn, optAd optAdditionalOutput.needUrlType = commonDefines.c_oAscUrlTypes.Temporary; } } else { - if (optConn) { - outputData.setData(yield storage.getSignedUrls(optConn.baseUrl, key, commonDefines.c_oAscUrlTypes.Session)); + let encryptedUserPassword = cmd.getPassword(); + let userPassword; + let decryptedPassword; + let isCorrectPassword; + if (password && encryptedUserPassword) { + decryptedPassword = yield utils.decryptPassword(password); + userPassword = yield utils.decryptPassword(encryptedUserPassword); + isCorrectPassword = decryptedPassword === userPassword; + } + if(password && !isCorrectPassword) { + logger.debug("getOutputData password mismatch: docId = %s", key); + if(encryptedUserPassword) { + outputData.setStatus('needpassword'); + outputData.setData(constants.CONVERT_PASSWORD); + } else { + outputData.setStatus('needpassword'); + outputData.setData(constants.CONVERT_DRM); + } + } else if (optConn) { + outputData.setData(yield storage.getSignedUrls(optConn.baseUrl, key, commonDefines.c_oAscUrlTypes.Session, creationDate)); } else if (optAdditionalOutput) { optAdditionalOutput.needUrlKey = key; optAdditionalOutput.needUrlMethod = 0; optAdditionalOutput.needUrlType = commonDefines.c_oAscUrlTypes.Session; + optAdditionalOutput.needUrlIsCorrectPassword = isCorrectPassword; + optAdditionalOutput.creationDate = creationDate; } } break; @@ -210,6 +239,16 @@ function* getOutputData(cmd, outputData, key, status, statusInfo, optConn, optAd yield cleanupCache(key); } break; + case taskResult.FileStatus.None: + outputData.setStatus('none'); + break; + case taskResult.FileStatus.WaitQueue: + //task in the queue. response will be after convertion + break; + default: + outputData.setStatus('err'); + outputData.setData(constants.UNKNOWN); + break; } } function* addRandomKeyTaskCmd(cmd) { @@ -252,24 +291,32 @@ function getSaveTask(cmd) { //} return queueData; } -function getUpdateResponse(cmd) { +function* getUpdateResponse(cmd) { var updateTask = new taskResult.TaskResultData(); updateTask.key = cmd.getSaveKey() ? cmd.getSaveKey() : cmd.getDocId(); var statusInfo = cmd.getStatusInfo(); if (constants.NO_ERROR == statusInfo) { updateTask.status = taskResult.FileStatus.Ok; + let password = cmd.getPassword(); + if (password) { + if (false === hasPasswordCol) { + let selectRes = yield taskResult.select(updateTask.key); + hasPasswordCol = selectRes.length > 0 && undefined !== selectRes[0].password; + } + if(hasPasswordCol) { + updateTask.password = password; + } + } } else if (constants.CONVERT_DOWNLOAD == statusInfo) { updateTask.status = taskResult.FileStatus.ErrToReload; } else if (constants.CONVERT_NEED_PARAMS == statusInfo) { updateTask.status = taskResult.FileStatus.NeedParams; - } else if (constants.CONVERT_DRM == statusInfo) { + } else if (constants.CONVERT_DRM == statusInfo || constants.CONVERT_PASSWORD == statusInfo) { if (cfgOpenProtectedFile) { - updateTask.status = taskResult.FileStatus.NeedPassword; + updateTask.status = taskResult.FileStatus.NeedPassword; } else { updateTask.status = taskResult.FileStatus.Err; } - } else if (constants.CONVERT_PASSWORD == statusInfo) { - updateTask.status = taskResult.FileStatus.NeedPassword; } else if (constants.CONVERT_DEAD_LETTER == statusInfo) { updateTask.status = taskResult.FileStatus.ErrToReload; } else { @@ -362,47 +409,56 @@ function* commandOpen(conn, cmd, outputData, opt_upsertRes, opt_bIsRestore) { } } function* commandOpenFillOutput(conn, cmd, outputData, opt_bIsRestore) { - let needAddTask = false; - let selectRes = yield taskResult.select(cmd.getDocId()); - if (selectRes.length > 0) { - let row = selectRes[0]; - if (taskResult.FileStatus.None === row.status) { - needAddTask = true; - } else { - yield* getOutputData(cmd, outputData, cmd.getDocId(), row.status, row.status_info, conn, undefined, opt_bIsRestore); - } - } - return needAddTask; + yield* getOutputData(cmd, outputData, cmd.getDocId(), conn, undefined, opt_bIsRestore); + return 'none' === outputData.getStatus(); } -function* commandReopen(cmd) { +function* commandReopen(conn, cmd, outputData) { let res = true; let isPassword = undefined !== cmd.getPassword(); + if (isPassword) { + let selectRes = yield taskResult.select(cmd.getDocId()); + if (selectRes.length > 0) { + let row = selectRes[0]; + if (sqlBase.DocumentPassword.prototype.getCurPassword(cmd.getDocId(), row.password)) { + logger.debug('commandReopen has password: docId = %s', cmd.getDocId()); + yield* commandOpenFillOutput(conn, cmd, outputData, false); + docsCoServer.modifyConnectionForPassword(conn, constants.FILE_STATUS_OK === outputData.getStatus()); + return res; + } + } + } if (!isPassword || cfgOpenProtectedFile) { - let updateMask = new taskResult.TaskResultData(); - updateMask.key = cmd.getDocId(); + let updateMask = new taskResult.TaskResultData(); + updateMask.key = cmd.getDocId(); updateMask.status = isPassword ? taskResult.FileStatus.NeedPassword : taskResult.FileStatus.NeedParams; - var task = new taskResult.TaskResultData(); - task.key = cmd.getDocId(); - task.status = taskResult.FileStatus.WaitQueue; - task.statusInfo = constants.NO_ERROR; + var task = new taskResult.TaskResultData(); + task.key = cmd.getDocId(); + task.status = taskResult.FileStatus.WaitQueue; + task.statusInfo = constants.NO_ERROR; - var upsertRes = yield taskResult.updateIf(task, updateMask); - if (upsertRes.affectedRows > 0) { - //add task - cmd.setUrl(null);//url may expire - cmd.setSaveKey(cmd.getDocId()); - cmd.setOutputFormat(constants.AVS_OFFICESTUDIO_FILE_CANVAS); - cmd.setEmbeddedFonts(false); - var dataQueue = new commonDefines.TaskQueueData(); - dataQueue.setCmd(cmd); - dataQueue.setToFile('Editor.bin'); - dataQueue.setFromSettings(true); - yield* docsCoServer.addTask(dataQueue, constants.QUEUE_PRIORITY_HIGH); - } + var upsertRes = yield taskResult.updateIf(task, updateMask); + if (upsertRes.affectedRows > 0) { + //add task + cmd.setUrl(null);//url may expire + cmd.setSaveKey(cmd.getDocId()); + cmd.setOutputFormat(constants.AVS_OFFICESTUDIO_FILE_CANVAS); + cmd.setEmbeddedFonts(false); + if (isPassword) { + cmd.setUserConnectionId(conn.user.id); + } + var dataQueue = new commonDefines.TaskQueueData(); + dataQueue.setCmd(cmd); + dataQueue.setToFile('Editor.bin'); + dataQueue.setFromSettings(true); + yield* docsCoServer.addTask(dataQueue, constants.QUEUE_PRIORITY_HIGH); + } else { + outputData.setStatus('needpassword'); + outputData.setData(constants.CONVERT_PASSWORD); + } } else { res = false; -} + } return res; } function* commandSave(cmd, outputData) { @@ -444,6 +500,15 @@ function* commandSendMailMerge(cmd, outputData) { } function* commandSfctByCmd(cmd, opt_priority, opt_expiration, opt_queue) { yield* addRandomKeyTaskCmd(cmd); + var selectRes = yield taskResult.select(cmd.getDocId()); + var row = selectRes.length > 0 ? selectRes[0] : null; + let docPassword = row && sqlBase.DocumentPassword.prototype.getDocPassword(cmd.getDocId(), row.password); + if (docPassword.current) { + cmd.setSavePassword(docPassword.current); + if (docPassword.change) { + cmd.setExternalChangeInfo(docPassword.change); + } + } var queueData = getSaveTask(cmd); queueData.setFromChanges(true); let priority = null != opt_priority ? opt_priority : constants.QUEUE_PRIORITY_LOW; @@ -632,6 +697,59 @@ function* commandSaveFromOrigin(cmd, outputData) { outputData.setStatus('ok'); outputData.setData(cmd.getSaveKey()); } +function* commandSetPassword(conn, cmd, outputData) { + let hasDocumentPassword = false; + let selectRes = yield taskResult.select(cmd.getDocId()); + if (selectRes.length > 0) { + let row = selectRes[0]; + hasPasswordCol = undefined !== row.password; + if (taskResult.FileStatus.Ok === row.status && sqlBase.DocumentPassword.prototype.getCurPassword(cmd.getDocId(), row.password)) { + hasDocumentPassword = true; + } + } + logger.debug('commandSetPassword isEnterCorrectPassword=%s, hasDocumentPassword=%s, hasPasswordCol=%s: docId = %s', conn.isEnterCorrectPassword, hasDocumentPassword, hasPasswordCol, cmd.getDocId()); + if (cfgOpenProtectedFile && (conn.isEnterCorrectPassword || !hasDocumentPassword) && hasPasswordCol) { + let updateMask = new taskResult.TaskResultData(); + updateMask.key = cmd.getDocId(); + updateMask.status = taskResult.FileStatus.Ok; + + let newChangesLastDate = new Date(); + newChangesLastDate.setMilliseconds(0);//remove milliseconds avoid issues with MySQL datetime rounding + + var task = new taskResult.TaskResultData(); + task.key = cmd.getDocId(); + task.password = cmd.getPassword() || ""; + let changeInfo = null; + if (conn.user) { + changeInfo = task.innerPasswordChange = docsCoServer.getExternalChangeInfo(conn.user, newChangesLastDate.getTime()); + } + + var upsertRes = yield taskResult.updateIf(task, updateMask); + if (upsertRes.affectedRows > 0) { + outputData.setStatus('ok'); + if (!conn.isEnterCorrectPassword) { + docsCoServer.modifyConnectionForPassword(conn, true); + } + yield docsCoServer.resetForceSaveAfterChanges(cmd.getDocId(), newChangesLastDate.getTime(), 0, utils.getBaseUrlByConnection(conn), changeInfo); + } else { + logger.debug('commandSetPassword sql update error: docId = %s', cmd.getDocId()); + outputData.setStatus('err'); + outputData.setData(constants.PASSWORD); + } + } else { + outputData.setStatus('err'); + outputData.setData(constants.PASSWORD); + } +} +function* commandChangeDocInfo(conn, cmd, outputData) { + let res = yield docsCoServer.changeConnectionInfo(conn, cmd); + if(res) { + outputData.setStatus('ok'); + } else { + outputData.setStatus('err'); + outputData.setData(constants.CHANGE_DOC_INFO); + } +} function checkAuthorizationLength(authorization, data){ //todo it is stub (remove in future versions) //8kb(https://stackoverflow.com/questions/686217/maximum-on-http-header-values) - 1kb(for other header) @@ -709,7 +827,7 @@ function* commandSfcCallback(cmd, isSfcm, isEncrypted) { } else { isError = true; } - if (getRes) { + if (getRes && userLastChangeId) { logger.debug('Callback commandSfcCallback: docId = %s callback = %s', docId, getRes.server.href); var outputSfc = new commonDefines.OutputSfcData(); outputSfc.setKey(docId); @@ -848,7 +966,7 @@ function* commandSfcCallback(cmd, isSfcm, isEncrypted) { } } } else { - logger.warn('Empty Callback commandSfcCallback: docId = %s', docId); + logger.warn('Empty Callback or userLastChangeId=%s commandSfcCallback: docId = %s', userLastChangeId, docId); storeForgotten = true; } if (undefined !== updateIfTask && !isSfcm) { @@ -971,7 +1089,7 @@ exports.openDocument = function(conn, cmd, opt_upsertRes, opt_bIsRestore) { yield* commandOpen(conn, cmd, outputData, opt_upsertRes, opt_bIsRestore); break; case 'reopen': - res = yield* commandReopen(cmd); + res = yield* commandReopen(conn, cmd, outputData); break; case 'imgurls': yield* commandImgurls(conn, cmd, outputData); @@ -982,6 +1100,12 @@ exports.openDocument = function(conn, cmd, opt_upsertRes, opt_bIsRestore) { case 'pathurls': yield* commandPathUrls(conn, cmd, outputData); break; + case 'setpassword': + yield* commandSetPassword(conn, cmd, outputData); + break; + case 'changedocinfo': + yield* commandChangeDocInfo(conn, cmd, outputData); + break; default: res = false; break; @@ -1058,7 +1182,12 @@ exports.downloadAs = function(req, res) { return; } } - + var selectRes = yield taskResult.select(docId); + var row = selectRes.length > 0 ? selectRes[0] : null; + let password = row && sqlBase.DocumentPassword.prototype.getCurPassword(cmd.getDocId(), row.password); + if (password && !cmd.getWithoutPassword()) { + cmd.setSavePassword(password); + } cmd.setData(req.body); var outputData = new OutputData(cmd.getCommand()); switch (cmd.getCommand()) { @@ -1173,6 +1302,13 @@ exports.saveFromChanges = function(docId, statusInfo, optFormat, opt_userId, opt cmd.setStatusInfoIn(statusInfo); cmd.setUserActionId(opt_userId); cmd.setUserActionIndex(opt_userIndex); + let docPassword = row && sqlBase.DocumentPassword.prototype.getDocPassword(cmd.getDocId(), row.password); + if (docPassword.current) { + cmd.setSavePassword(docPassword.current); + if (docPassword.change) { + cmd.setExternalChangeInfo(docPassword.change); + } + } yield* addRandomKeyTaskCmd(cmd); var queueData = getSaveTask(cmd); queueData.setFromChanges(true); @@ -1204,19 +1340,16 @@ exports.receiveTask = function(data, ack) { var cmd = task.getCmd(); docId = cmd.getDocId(); logger.debug('Start receiveTask: docId = %s %s', docId, data); - var updateTask = getUpdateResponse(cmd); + var updateTask = yield* getUpdateResponse(cmd); var updateRes = yield taskResult.update(updateTask); if (updateRes.affectedRows > 0) { var outputData = new OutputData(cmd.getCommand()); var command = cmd.getCommand(); - var additionalOutput = {needUrlKey: null, needUrlMethod: null, needUrlType: null}; + var additionalOutput = {needUrlKey: null, needUrlMethod: null, needUrlType: null, needUrlIsCorrectPassword: undefined, creationDate: undefined}; if ('open' == command || 'reopen' == command) { - //yield utils.sleep(5000); - yield* getOutputData(cmd, outputData, cmd.getDocId(), updateTask.status, - updateTask.statusInfo, null, additionalOutput); + yield* getOutputData(cmd, outputData, cmd.getDocId(), null, additionalOutput); } else if ('save' == command || 'savefromorigin' == command || 'sfct' == command) { - yield* getOutputData(cmd, outputData, cmd.getSaveKey(), updateTask.status, - updateTask.statusInfo, null, additionalOutput); + yield* getOutputData(cmd, outputData, cmd.getSaveKey(), null, additionalOutput); } else if ('sfcm' == command) { yield* commandSfcCallback(cmd, true); } else if ('sfc' == command) { @@ -1233,7 +1366,9 @@ exports.receiveTask = function(data, ack) { type: commonDefines.c_oPublishType.receiveTask, cmd: cmd, output: output, needUrlKey: additionalOutput.needUrlKey, needUrlMethod: additionalOutput.needUrlMethod, - needUrlType: additionalOutput.needUrlType + needUrlType: additionalOutput.needUrlType, + needUrlIsCorrectPassword: additionalOutput.needUrlIsCorrectPassword, + creationDate: additionalOutput.creationDate }); } } diff --git a/DocService/sources/converterservice.js b/DocService/sources/converterservice.js index 5111e227a..a539d1676 100644 --- a/DocService/sources/converterservice.js +++ b/DocService/sources/converterservice.js @@ -148,8 +148,8 @@ function* convertByCmd(cmd, async, baseUrl, opt_fileTo, opt_taskExist, opt_prior return status; } -function* convertFromChanges(docId, baseUrl, forceSave, opt_userdata, opt_userConnectionId, opt_priority, - opt_expiration, opt_queue, opt_redisKey) { +function* convertFromChanges(docId, baseUrl, forceSave, externalChangeInfo, opt_userdata, opt_userConnectionId, + opt_responseKey, opt_priority, opt_expiration, opt_queue, opt_redisKey) { var cmd = new commonDefines.InputCommand(); cmd.setCommand('sfcm'); cmd.setDocId(docId); @@ -158,12 +158,16 @@ function* convertFromChanges(docId, baseUrl, forceSave, opt_userdata, opt_userCo cmd.setCodepage(commonDefines.c_oAscCodePageUtf8); cmd.setDelimiter(commonDefines.c_oAscCsvDelimiter.Comma); cmd.setForceSave(forceSave); + cmd.setExternalChangeInfo(externalChangeInfo); if (opt_userdata) { cmd.setUserData(opt_userdata); } if (opt_userConnectionId) { cmd.setUserConnectionId(opt_userConnectionId); } + if (opt_responseKey) { + cmd.setResponseKey(opt_responseKey); + } if (opt_redisKey) { cmd.setRedisKey(opt_redisKey); } @@ -224,7 +228,10 @@ function convertRequest(req, res, isJson) { if (params.spreadsheetLayout) { cmd.setJsonParams(JSON.stringify({'spreadsheetLayout': params.spreadsheetLayout})); } - cmd.setPassword(params.password); + if (params.password) { + let encryptedPassword = yield utils.encryptPassword(params.password); + cmd.setPassword(encryptedPassword); + } cmd.setWithAuthorization(true); var thumbnail = params.thumbnail; if (thumbnail) { diff --git a/DocService/sources/editorDataMemory.js b/DocService/sources/editorDataMemory.js index 22b560339..6bd29434e 100644 --- a/DocService/sources/editorDataMemory.js +++ b/DocService/sources/editorDataMemory.js @@ -162,9 +162,9 @@ EditorData.prototype.getdelSaved = function(docId) { data.saved = undefined; return Promise.resolve(res); }; -EditorData.prototype.setForceSave = function(docId, time, index, baseUrl) { +EditorData.prototype.setForceSave = function(docId, time, index, baseUrl, changeInfo) { let data = this._getDocumentData(docId); - data.forceSave = {time: time, index: index, baseUrl: baseUrl, started: false, ended: false}; + data.forceSave = {time: time, index: index, baseUrl: baseUrl, changeInfo: changeInfo, started: false, ended: false}; return Promise.resolve(); }; EditorData.prototype.getForceSave = function(docId) { diff --git a/DocService/sources/gc.js b/DocService/sources/gc.js index 95e308fa9..bff66a8d3 100644 --- a/DocService/sources/gc.js +++ b/DocService/sources/gc.js @@ -47,7 +47,6 @@ var constants = require('./../../Common/sources/constants'); var commondefines = require('./../../Common/sources/commondefines'); var queueService = require('./../../Common/sources/taskqueueRabbitMQ'); var pubsubService = require('./pubsubRabbitMQ'); -const editorDataStorage = require('./' + configCommon.get('services.CoAuthoring.server.editorDataStorage')); var cfgExpFilesCron = config.get('expire.filesCron'); var cfgExpDocumentsCron = config.get('expire.documentsCron'); @@ -56,6 +55,14 @@ var cfgExpFilesRemovedAtOnce = config.get('expire.filesremovedatonce'); var cfgForceSaveEnable = config.get('autoAssembly.enable'); var cfgForceSaveStep = ms(config.get('autoAssembly.step')); +function getCronStep(cronTime){ + let cronJob = new cron.CronJob(cronTime, function(){}); + let dates = cronJob.nextDates(2); + return dates[1] - dates[0]; +} +let expFilesStep = getCronStep(cfgExpFilesCron); +let expDocumentsStep = getCronStep(cfgExpDocumentsCron); + var checkFileExpire = function() { return co(function* () { try { @@ -83,6 +90,8 @@ var checkFileExpire = function() { logger.debug('checkFileExpire end: removedCount = %d', removedCount); } catch (e) { logger.error('checkFileExpire error:\r\n%s', e.stack); + } finally { + setTimeout(checkFileExpire, expFilesStep); } }); }; @@ -102,8 +111,8 @@ var checkDocumentExpire = function() { for (var i = 0; i < expiredKeys.length; ++i) { var docId = expiredKeys[i]; if (docId) { - var puckerIndex = yield docsCoServer.getChangesIndexPromise(docId); - if (puckerIndex > 0) { + var hasChanges = yield docsCoServer.hasChanges(docId); + if (hasChanges) { yield docsCoServer.createSaveTimerPromise(docId, null, null, queue, true); startSaveCount++; } else { @@ -124,6 +133,7 @@ var checkDocumentExpire = function() { logger.error('checkDocumentExpire error:\r\n%s', e.stack); } logger.debug('checkDocumentExpire end: startSaveCount = %d, removedCount = %d', startSaveCount, removedCount); + setTimeout(checkDocumentExpire, expDocumentsStep); } }); }; @@ -146,8 +156,8 @@ let forceSaveTimeout = function() { for (let i = 0; i < expiredKeys.length; ++i) { let docId = expiredKeys[i]; if (docId) { - actions.push(docsCoServer.startForceSavePromise(docId, commondefines.c_oAscForceSaveTypes.Timeout, - undefined, undefined, undefined, undefined, undefined, queue, pubsub)); + actions.push(docsCoServer.startForceSave(docId, commondefines.c_oAscForceSaveTypes.Timeout, + undefined, undefined, undefined, undefined, undefined, undefined, queue, pubsub)); } } yield Promise.all(actions); @@ -172,24 +182,11 @@ let forceSaveTimeout = function() { }); }; -var documentExpireJob = function(opt_isStart) { - if (!opt_isStart) { - logger.warn('checkDocumentExpire restart'); - } - new cron.CronJob(cfgExpDocumentsCron, checkDocumentExpire, documentExpireJob, true); -}; - -var fileExpireJob = function(opt_isStart) { - if (!opt_isStart) { - logger.warn('checkFileExpire restart'); - } - new cron.CronJob(cfgExpFilesCron, checkFileExpire, fileExpireJob, true); -}; - exports.startGC = function() { - documentExpireJob(true); - fileExpireJob(true); + setTimeout(checkDocumentExpire, expDocumentsStep); + setTimeout(checkFileExpire, expFilesStep); if (cfgForceSaveEnable) { setTimeout(forceSaveTimeout, cfgForceSaveStep); } }; +exports.getCronStep = getCronStep; diff --git a/DocService/sources/mySqlBaseConnector.js b/DocService/sources/mySqlBaseConnector.js index 1c04fd7d1..69c594bb2 100644 --- a/DocService/sources/mySqlBaseConnector.js +++ b/DocService/sources/mySqlBaseConnector.js @@ -78,7 +78,7 @@ let addSqlParam = function (val, values) { }; exports.addSqlParameter = addSqlParam; let concatParams = function (val1, val2) { - return `CONCAT(${val1}, ${val2})`; + return `CONCAT(COALESCE(${val1}, ''), COALESCE(${val2}, ''))`; }; exports.concatParams = concatParams; diff --git a/DocService/sources/postgreSqlBaseConnector.js b/DocService/sources/postgreSqlBaseConnector.js index 0c54b5d0d..204af6690 100644 --- a/DocService/sources/postgreSqlBaseConnector.js +++ b/DocService/sources/postgreSqlBaseConnector.js @@ -96,7 +96,7 @@ let addSqlParam = function (val, values) { }; exports.addSqlParameter = addSqlParam; let concatParams = function (val1, val2) { - return `${val1} || ${val2}`; + return `COALESCE(${val1}, '') || COALESCE(${val2}, '')`; }; exports.concatParams = concatParams; var isSupportOnConflict = true; diff --git a/DocService/sources/taskresult.js b/DocService/sources/taskresult.js index f1386767a..708da59a1 100644 --- a/DocService/sources/taskresult.js +++ b/DocService/sources/taskresult.js @@ -60,10 +60,14 @@ function TaskResultData() { 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.innerPasswordChange = null;//not a DB field } TaskResultData.prototype.completeDefaults = function() { if (!this.key) { @@ -78,6 +82,9 @@ TaskResultData.prototype.completeDefaults = function() { if (!this.lastOpenDate) { this.lastOpenDate = new Date(); } + if (!this.creationDate) { + this.creationDate = new Date(); + } if (!this.userIndex) { this.userIndex = 1; } @@ -110,7 +117,7 @@ function select(docId) { }, undefined, undefined, values); }); } -function toUpdateArray(task, updateTime, isMask, values) { +function toUpdateArray(task, updateTime, isMask, values, setPassword) { var res = []; if (null != task.status) { let sqlParam = addSqlParam(task.status, values); @@ -146,13 +153,22 @@ function toUpdateArray(task, updateTime, isMask, values) { 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)}`); + } return res; } -function update(task) { +function update(task, setPassword) { return new Promise(function(resolve, reject) { let values = []; - let updateElems = toUpdateArray(task, true, false, values); + let updateElems = toUpdateArray(task, true, false, values, setPassword); let sqlSet = updateElems.join(', '); let sqlParam = addSqlParam(task.key, values); let sqlCommand = `UPDATE task_result SET ${sqlSet} WHERE id=${sqlParam};`; @@ -169,8 +185,8 @@ function update(task) { function updateIf(task, mask) { return new Promise(function(resolve, reject) { let values = []; - let commandArg = toUpdateArray(task, true, false, values); - let commandArgMask = toUpdateArray(mask, false, true, values); + let commandArg = toUpdateArray(task, true, false, values, false); + let commandArgMask = toUpdateArray(mask, false, true, values, false); commandArgMask.push('id=' + addSqlParam(mask.key, values)); let sqlSet = commandArg.join(', '); let sqlWhere = commandArgMask.join(' AND '); @@ -184,6 +200,25 @@ function updateIf(task, mask) { }, undefined, undefined, values); }); } +function restoreInitialPassword(docId) { + return select(docId).then(function(selectRes) { + if (selectRes.length > 0) { + var row = selectRes[0]; + let docPassword = sqlBase.DocumentPassword.prototype.getDocPassword(docId, row.password); + var updateTask = new TaskResultData(); + updateTask.key = docId; + if (docPassword.initial) { + var documentPassword = new sqlBase.DocumentPassword(); + documentPassword.fromValues(docPassword.initial); + updateTask.password = documentPassword.toSQLInsert(); + return update(updateTask, true); + } else if (docPassword.current) { + updateTask.password = null; + return update(updateTask, true); + } + } + }); +} function addRandomKey(task, opt_prefix, opt_size) { return new Promise(function(resolve, reject) { @@ -277,6 +312,7 @@ exports.upsert = upsert; exports.select = select; exports.update = update; exports.updateIf = updateIf; +exports.restoreInitialPassword = restoreInitialPassword; exports.addRandomKeyTask = addRandomKeyTask; exports.remove = remove; exports.getExpired = getExpired; diff --git a/FileConverter/npm-shrinkwrap.json b/FileConverter/npm-shrinkwrap.json index 9fca47e27..c8c6c7b3a 100644 --- a/FileConverter/npm-shrinkwrap.json +++ b/FileConverter/npm-shrinkwrap.json @@ -25,7 +25,7 @@ "config": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/config/-/config-2.0.1.tgz", - "integrity": "sha512-aTaviJnC8ZjQYx8kQf4u6tWqIxWolyQQ3LqXgnCLAsIb78JrUshHG0YuzIarzTaVVe1Pazms3TXImfYra8UsyQ==", + "integrity": "sha1-mVzMgXVGBXjWRqwKLkAY/6RMoEY=", "requires": { "json5": "^1.0.1" } @@ -48,7 +48,7 @@ "json5": { "version": "1.0.1", "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "integrity": "sha1-d5+wAYYE+oVOrL9iUhgNg1Q+Pb4=", "requires": { "minimist": "^1.2.0" } @@ -56,16 +56,16 @@ "lru-cache": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "integrity": "sha1-oRdc80lt/IQ2wVbDNLSVWZK85pw=", "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "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==" }, "pseudomap": { "version": "1.0.2", @@ -88,7 +88,7 @@ "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", "requires": { "isexe": "^2.0.0" } diff --git a/FileConverter/package.json b/FileConverter/package.json index 7e53f0277..46ccfbcfe 100644 --- a/FileConverter/package.json +++ b/FileConverter/package.json @@ -1,7 +1,7 @@ { "name": "fileconverter", "version": "1.0.1", - "homepage": "http://www.onlyoffice.com", + "homepage": "https://www.onlyoffice.com", "private": true, "bin": "sources/convertermaster.js", "dependencies": { diff --git a/FileConverter/sources/converter.js b/FileConverter/sources/converter.js index 8b3f00f05..8ac3df229 100644 --- a/FileConverter/sources/converter.js +++ b/FileConverter/sources/converter.js @@ -60,6 +60,7 @@ var cfgPresentationThemesDir = configConverter.get('presentationThemesDir'); var cfgX2tPath = configConverter.get('x2tPath'); var cfgDocbuilderPath = configConverter.get('docbuilderPath'); var cfgDocbuilderAllFontsPath = configConverter.get('docbuilderAllFontsPath'); +var cfgDocbuilderCoreFontsPath = configConverter.get('docbuilderCoreFontsPath'); var cfgArgs = configConverter.get('args'); var cfgSpawnOptions = configConverter.get('spawnOptions'); if (cfgSpawnOptions.env) { @@ -91,6 +92,7 @@ function TaskQueueDataConvert(task) { this.key = cmd.savekey ? cmd.savekey : cmd.id; this.fileFrom = null; this.fileTo = null; + this.title = cmd.getTitle(); if(constants.AVS_OFFICESTUDIO_FILE_OTHER_PDFA !== cmd.outputformat){ this.formatTo = cmd.outputformat; } else { @@ -115,6 +117,7 @@ function TaskQueueDataConvert(task) { this.jsonParams = cmd.getJsonParams(); this.lcid = cmd.getLCID(); this.password = cmd.getPassword(); + this.savePassword = cmd.getSavePassword(); this.noBase64 = cmd.getNoBase64(); this.timestamp = new Date(); } @@ -126,6 +129,7 @@ TaskQueueDataConvert.prototype = { xml += this.serializeXmlProp('m_sKey', this.key); xml += this.serializeXmlProp('m_sFileFrom', this.fileFrom); xml += this.serializeXmlProp('m_sFileTo', this.fileTo); + xml += this.serializeXmlProp('m_sTitle', this.title); xml += this.serializeXmlProp('m_nFormatTo', this.formatTo); xml += this.serializeXmlProp('m_bIsPDFA', this.isPDFA); xml += this.serializeXmlProp('m_nCsvTxtEncoding', this.csvTxtEncoding); @@ -149,13 +153,25 @@ TaskQueueDataConvert.prototype = { xml += this.serializeLimit(); xml += ''; fs.writeFileSync(fsPath, xml, {encoding: 'utf8'}); - let hiddenXml; - if (undefined !== this.password) { - hiddenXml = ''; - hiddenXml += this.serializeXmlProp('m_sPassword', this.password); - hiddenXml += ''; - } - return hiddenXml; + }, + serializeHidden: function() { + var t = this; + return co(function* () { + let xml; + if (t.password || t.savePassword) { + xml = ''; + if(t.password) { + let password = yield utils.decryptPassword(t.password); + xml += t.serializeXmlProp('m_sPassword', password); + } + if(t.savePassword) { + let savePassword = yield utils.decryptPassword(t.savePassword); + xml += t.serializeXmlProp('m_sSavePassword', savePassword); + } + xml += ''; + } + return xml; + }); }, serializeMailMerge: function(data) { var xml = ''; @@ -387,15 +403,32 @@ function* processChanges(tempDirs, cmd, authorProps) { let forceSave = cmd.getForceSave(); let forceSaveTime; let forceSaveIndex = Number.MAX_VALUE; - if (forceSave) { + if (forceSave && undefined !== forceSave.getTime() && undefined !== forceSave.getIndex()) { forceSaveTime = forceSave.getTime(); forceSaveIndex = forceSave.getIndex(); } + let extChangeInfo = cmd.getExternalChangeInfo(); + let extChanges; + if (extChangeInfo) { + extChanges = [{ + id: cmd.getDocId(), change_id: 0, change_data: "", user_id: extChangeInfo.user_id, + user_id_original: extChangeInfo.user_id_original, user_name: extChangeInfo.user_name, + change_date: new Date(extChangeInfo.change_date) + }]; + } + let streamObj = yield* streamCreate(cmd.getDocId(), changesDir, indexFile++, {highWaterMark: cfgStreamWriterBufferSize}); let curIndexStart = 0; let curIndexEnd = Math.min(curIndexStart + cfgMaxRequestChanges, forceSaveIndex); - while (curIndexStart < curIndexEnd) { - let changes = yield baseConnector.getChangesPromise(cmd.getDocId(), curIndexStart, curIndexEnd, forceSaveTime); + while (curIndexStart < curIndexEnd || extChanges) { + let changes = []; + if (curIndexStart < curIndexEnd) { + changes = yield baseConnector.getChangesPromise(cmd.getDocId(), curIndexStart, curIndexEnd, forceSaveTime); + } + if (0 === changes.length && extChanges) { + changes = extChanges; + } + extChanges = undefined; for (let i = 0; i < changes.length; ++i) { let change = changes[i]; if (change.change_data.startsWith('ENCRYPTED;')) { @@ -411,8 +444,7 @@ function* processChanges(tempDirs, cmd, authorProps) { } changesAuthor = change.user_id_original; changesIndex = utils.getIndexFromUserId(change.user_id, change.user_id_original); - authorProps.lastModifiedBy = change.user_name; - authorProps.modified = change.change_date.toISOString().slice(0, 19) + 'Z'; + let strDate = baseConnector.getDateTime(change.change_date); changesHistory.changes.push({'created': strDate, 'user': {'id': changesAuthor, 'name': change.user_name}}); yield* streamWrite(streamObj, '['); @@ -422,6 +454,10 @@ function* processChanges(tempDirs, cmd, authorProps) { yield* streamWrite(streamObj, change.change_data); streamObj.isNoChangesInFile = false; } + if (changes.length > 0) { + authorProps.lastModifiedBy = changes[changes.length - 1].user_name; + authorProps.modified = changes[changes.length - 1].change_date.toISOString().slice(0, 19) + 'Z'; + } if (changes.length === curIndexEnd - curIndexStart) { curIndexStart += cfgMaxRequestChanges; curIndexEnd = Math.min(curIndexStart + cfgMaxRequestChanges, forceSaveIndex); @@ -433,6 +469,11 @@ function* processChanges(tempDirs, cmd, authorProps) { if (streamObj.isNoChangesInFile) { fs.unlinkSync(streamObj.filePath); } + if (null == changesAuthor && null == changesIndex && forceSave && undefined !== forceSave.getAuthorUserId() && + undefined !== forceSave.getAuthorUserIndex()) { + changesAuthor = forceSave.getAuthorUserId(); + changesIndex = forceSave.getAuthorUserIndex(); + } cmd.setUserId(changesAuthor); cmd.setUserIndex(changesIndex); fs.writeFileSync(path.join(tempDirs.result, 'changesHistory.json'), JSON.stringify(changesHistory), 'utf8'); @@ -650,8 +691,9 @@ function* ExecuteTask(task) { if (!isBuilder) { processPath = cfgX2tPath; let paramsFile = path.join(tempDirs.temp, 'params.xml'); - let hiddenXml = dataConvert.serialize(paramsFile); + dataConvert.serialize(paramsFile); childArgs.push(paramsFile); + let hiddenXml = yield dataConvert.serializeHidden(); if (hiddenXml) { childArgs.push(hiddenXml); } @@ -659,6 +701,9 @@ function* ExecuteTask(task) { fs.mkdirSync(path.join(tempDirs.result, 'output')); processPath = cfgDocbuilderPath; childArgs.push('--all-fonts-path=' + cfgDocbuilderAllFontsPath); + if (cfgDocbuilderCoreFontsPath) { + childArgs.push('--fonts-dir=' + cfgDocbuilderCoreFontsPath); + } childArgs.push('--save-use-only-names=' + tempDirs.result + '/output'); childArgs.push(dataConvert.fileFrom); } diff --git a/Metrics/package.json b/Metrics/package.json index 5c9975284..73acb162a 100644 --- a/Metrics/package.json +++ b/Metrics/package.json @@ -1,7 +1,7 @@ { "name": "metrics", "version": "1.0.0", - "homepage": "http://www.onlyoffice.com", + "homepage": "https://www.onlyoffice.com", "private": true, "bin": "node_modules/statsd/bin/statsd", "dependencies": { diff --git a/SpellChecker/package.json b/SpellChecker/package.json index 7c3053991..857d09219 100644 --- a/SpellChecker/package.json +++ b/SpellChecker/package.json @@ -1,7 +1,7 @@ { "name": "spellchecker", "version": "1.0.1", - "homepage": "http://www.onlyoffice.com", + "homepage": "https://www.onlyoffice.com", "private": true, "bin": "sources/server.js", "dependencies": { diff --git a/package.json b/package.json index 9201967eb..06d75eb6c 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "builder", - "version": "0.0.0", - "homepage": "http://www.teamlab.com", + "version": "1.0.1", + "homepage": "https://www.onlyoffice.com", "private": true, "grunt": { "copy": { diff --git a/schema/mysql/createdb.sql b/schema/mysql/createdb.sql index 235b75ba5..e0c37cb83 100644 --- a/schema/mysql/createdb.sql +++ b/schema/mysql/createdb.sql @@ -51,11 +51,13 @@ CREATE TABLE IF NOT EXISTS `task_result` ( `id` varchar(255) NOT NULL, `status` tinyint(3) NOT NULL, `status_info` int(10) NOT NULL, + `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `last_open_date` datetime NOT NULL, `user_index` int(10) unsigned NOT NULL DEFAULT 1, `change_id` int(10) unsigned NOT NULL DEFAULT 0, `callback` longtext NOT NULL, `baseurl` text NOT NULL, + `password` longtext NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; diff --git a/schema/mysql/upgrade/upgradev630.sql b/schema/mysql/upgrade/upgradev630.sql new file mode 100644 index 000000000..d5bdc3a4e --- /dev/null +++ b/schema/mysql/upgrade/upgradev630.sql @@ -0,0 +1,21 @@ +DELIMITER DLM00 + +DROP PROCEDURE IF EXISTS upgrade630 DLM00 + +CREATE PROCEDURE upgrade630() +BEGIN + + IF (SELECT DATA_TYPE FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'task_result' AND COLUMN_NAME = 'callback') <> 'longtext' THEN + ALTER TABLE `task_result` CHANGE COLUMN `callback` `callback` LONGTEXT NOT NULL ; + END IF; + + IF NOT EXISTS(SELECT * FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'task_result' AND COLUMN_NAME = 'created_at') THEN + ALTER TABLE `task_result` ADD COLUMN `created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP AFTER `status_info`; + ALTER TABLE `task_result` ADD COLUMN `password` LONGTEXT NULL AFTER `baseurl`; + END IF; + +END DLM00 + +CALL upgrade630() DLM00 + +DELIMITER ; diff --git a/schema/postgresql/createdb.sql b/schema/postgresql/createdb.sql index 96b553a82..0edbb56e9 100644 --- a/schema/postgresql/createdb.sql +++ b/schema/postgresql/createdb.sql @@ -26,11 +26,13 @@ CREATE TABLE IF NOT EXISTS "public"."task_result" ( "id" varchar(255) COLLATE "default" NOT NULL, "status" int2 NOT NULL, "status_info" int4 NOT NULL, +"created_at" timestamp without time zone DEFAULT NOW(), "last_open_date" timestamp without time zone NOT NULL, "user_index" int4 NOT NULL DEFAULT 1, "change_id" int4 NOT NULL DEFAULT 0, "callback" text COLLATE "default" NOT NULL, "baseurl" text COLLATE "default" NOT NULL, +"password" text COLLATE "default" NULL, PRIMARY KEY ("id") ) WITH (OIDS=FALSE); diff --git a/schema/postgresql/upgrade/upgradev630.sql b/schema/postgresql/upgrade/upgradev630.sql new file mode 100644 index 000000000..57a8ea13b --- /dev/null +++ b/schema/postgresql/upgrade/upgradev630.sql @@ -0,0 +1,15 @@ +DO $$ + BEGIN + BEGIN + ALTER TABLE "task_result" ADD COLUMN "created_at" timestamp without time zone DEFAULT NOW(); + EXCEPTION + WHEN duplicate_column THEN RAISE NOTICE 'column created_at already exists.'; + END; + + BEGIN + ALTER TABLE "task_result" ADD COLUMN "password" text; + EXCEPTION + WHEN duplicate_column THEN RAISE NOTICE 'column password already exists.'; + END; + END; +$$ \ No newline at end of file