mirror of
https://github.com/ONLYOFFICE/server.git
synced 2026-02-10 18:05:07 +08:00
[feature] add azure blob storage
This commit is contained in:
committed by
Sergey Konovalov
parent
f8ec53f19b
commit
c75a88aecb
281
Common/npm-shrinkwrap.json
generated
281
Common/npm-shrinkwrap.json
generated
@ -3076,6 +3076,219 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@azure/abort-controller": {
|
||||||
|
"version": "2.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz",
|
||||||
|
"integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/core-auth": {
|
||||||
|
"version": "1.9.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.9.0.tgz",
|
||||||
|
"integrity": "sha512-FPwHpZywuyasDSLMqJ6fhbOK3TqUdviZNF8OqRGA4W5Ewib2lEEZ+pBsYcBa88B2NGO/SEnYPGhyBqNlE8ilSw==",
|
||||||
|
"requires": {
|
||||||
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
"@azure/core-util": "^1.11.0",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/core-client": {
|
||||||
|
"version": "1.9.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-client/-/core-client-1.9.3.tgz",
|
||||||
|
"integrity": "sha512-/wGw8fJ4mdpJ1Cum7s1S+VQyXt1ihwKLzfabS1O/RDADnmzVc01dHn44qD0BvGH6KlZNzOMW95tEpKqhkCChPA==",
|
||||||
|
"requires": {
|
||||||
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
"@azure/core-auth": "^1.4.0",
|
||||||
|
"@azure/core-rest-pipeline": "^1.9.1",
|
||||||
|
"@azure/core-tracing": "^1.0.0",
|
||||||
|
"@azure/core-util": "^1.6.1",
|
||||||
|
"@azure/logger": "^1.0.0",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/core-http-compat": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-http-compat/-/core-http-compat-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-1kW8ZhN0CfbNOG6C688z5uh2yrzALE7dDXHiR9dY4vt+EbhGZQSbjDa5bQd2rf3X2pdWMsXbqbArxUyeNdvtmg==",
|
||||||
|
"requires": {
|
||||||
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
"@azure/core-client": "^1.3.0",
|
||||||
|
"@azure/core-rest-pipeline": "^1.19.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/core-lro": {
|
||||||
|
"version": "2.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-lro/-/core-lro-2.7.2.tgz",
|
||||||
|
"integrity": "sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw==",
|
||||||
|
"requires": {
|
||||||
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
"@azure/core-util": "^1.2.0",
|
||||||
|
"@azure/logger": "^1.0.0",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/core-paging": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-paging/-/core-paging-1.6.2.tgz",
|
||||||
|
"integrity": "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/core-rest-pipeline": {
|
||||||
|
"version": "1.19.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.19.1.tgz",
|
||||||
|
"integrity": "sha512-zHeoI3NCs53lLBbWNzQycjnYKsA1CVKlnzSNuSFcUDwBp8HHVObePxrM7HaX+Ha5Ks639H7chNC9HOaIhNS03w==",
|
||||||
|
"requires": {
|
||||||
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
"@azure/core-auth": "^1.8.0",
|
||||||
|
"@azure/core-tracing": "^1.0.1",
|
||||||
|
"@azure/core-util": "^1.11.0",
|
||||||
|
"@azure/logger": "^1.0.0",
|
||||||
|
"http-proxy-agent": "^7.0.0",
|
||||||
|
"https-proxy-agent": "^7.0.0",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/core-tracing": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-UKTiEJPkWcESPYJz3X5uKRYyOcJD+4nYph+KpfdPRnQJVrZfk0KJgdnaAWKfhsBBtAf/D58Az4AvCJEmWgIBAg==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/core-util": {
|
||||||
|
"version": "1.11.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.11.0.tgz",
|
||||||
|
"integrity": "sha512-DxOSLua+NdpWoSqULhjDyAZTXFdP/LKkqtYuxxz1SCN289zk3OG8UOpnCQAz/tygyACBtWp/BoO72ptK7msY8g==",
|
||||||
|
"requires": {
|
||||||
|
"@azure/abort-controller": "^2.0.0",
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/core-xml": {
|
||||||
|
"version": "1.4.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/core-xml/-/core-xml-1.4.5.tgz",
|
||||||
|
"integrity": "sha512-gT4H8mTaSXRz7eGTuQyq1aIJnJqeXzpOe9Ay7Z3FrCouer14CbV3VzjnJrNrQfbBpGBLO9oy8BmrY75A0p53cA==",
|
||||||
|
"requires": {
|
||||||
|
"fast-xml-parser": "^5.0.7",
|
||||||
|
"tslib": "^2.8.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"fast-xml-parser": {
|
||||||
|
"version": "5.0.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.0.9.tgz",
|
||||||
|
"integrity": "sha512-2mBwCiuW3ycKQQ6SOesSB8WeF+fIGb6I/GG5vU5/XEptwFFhp9PE8b9O7fbs2dpq9fXn4ULR3UsfydNUCntf5A==",
|
||||||
|
"requires": {
|
||||||
|
"strnum": "^2.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"strnum": {
|
||||||
|
"version": "2.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/strnum/-/strnum-2.0.5.tgz",
|
||||||
|
"integrity": "sha512-YAT3K/sgpCUxhxNMrrdhtod3jckkpYwH6JAuwmUdXZsmzH1wUyzTMrrK2wYCEEqlKwrWDd35NeuUkbBy/1iK+Q=="
|
||||||
|
},
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/logger": {
|
||||||
|
"version": "1.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.1.4.tgz",
|
||||||
|
"integrity": "sha512-4IXXzcCdLdlXuCG+8UKEwLA1T1NHqUfanhXYHiQTn+6sfWCZXduqbtXDGceg3Ce5QxTGo7EqmbV6Bi+aqKuClQ==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^2.6.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@azure/storage-blob": {
|
||||||
|
"version": "12.27.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@azure/storage-blob/-/storage-blob-12.27.0.tgz",
|
||||||
|
"integrity": "sha512-IQjj9RIzAKatmNca3D6bT0qJ+Pkox1WZGOg2esJF2YLHb45pQKOwGPIAV+w3rfgkj7zV3RMxpn/c6iftzSOZJQ==",
|
||||||
|
"requires": {
|
||||||
|
"@azure/abort-controller": "^2.1.2",
|
||||||
|
"@azure/core-auth": "^1.4.0",
|
||||||
|
"@azure/core-client": "^1.6.2",
|
||||||
|
"@azure/core-http-compat": "^2.0.0",
|
||||||
|
"@azure/core-lro": "^2.2.0",
|
||||||
|
"@azure/core-paging": "^1.1.1",
|
||||||
|
"@azure/core-rest-pipeline": "^1.10.1",
|
||||||
|
"@azure/core-tracing": "^1.1.2",
|
||||||
|
"@azure/core-util": "^1.6.1",
|
||||||
|
"@azure/core-xml": "^1.4.3",
|
||||||
|
"@azure/logger": "^1.0.0",
|
||||||
|
"events": "^3.0.0",
|
||||||
|
"tslib": "^2.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@smithy/abort-controller": {
|
"@smithy/abort-controller": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-1.0.2.tgz",
|
||||||
@ -4959,6 +5172,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"agent-base": {
|
||||||
|
"version": "7.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
|
||||||
|
"integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw=="
|
||||||
|
},
|
||||||
"ajv": {
|
"ajv": {
|
||||||
"version": "5.5.2",
|
"version": "5.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
|
||||||
@ -4993,7 +5211,7 @@
|
|||||||
"asap": {
|
"asap": {
|
||||||
"version": "2.0.6",
|
"version": "2.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
"integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
|
||||||
},
|
},
|
||||||
"asn1": {
|
"asn1": {
|
||||||
"version": "0.2.4",
|
"version": "0.2.4",
|
||||||
@ -5084,7 +5302,7 @@
|
|||||||
"clone": {
|
"clone": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
|
||||||
"integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18="
|
"integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w=="
|
||||||
},
|
},
|
||||||
"co": {
|
"co": {
|
||||||
"version": "4.6.0",
|
"version": "4.6.0",
|
||||||
@ -5177,6 +5395,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
|
||||||
},
|
},
|
||||||
|
"events": {
|
||||||
|
"version": "3.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||||
|
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="
|
||||||
|
},
|
||||||
"extend": {
|
"extend": {
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||||
@ -5252,6 +5475,30 @@
|
|||||||
"har-schema": "^2.0.0"
|
"har-schema": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"http-proxy-agent": {
|
||||||
|
"version": "7.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz",
|
||||||
|
"integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==",
|
||||||
|
"requires": {
|
||||||
|
"agent-base": "^7.1.0",
|
||||||
|
"debug": "^4.3.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"http-signature": {
|
"http-signature": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||||
@ -5262,6 +5509,30 @@
|
|||||||
"sshpk": "^1.7.0"
|
"sshpk": "^1.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"https-proxy-agent": {
|
||||||
|
"version": "7.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
|
||||||
|
"integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
|
||||||
|
"requires": {
|
||||||
|
"agent-base": "^7.1.2",
|
||||||
|
"debug": "4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "4.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
|
||||||
|
"integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "^2.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.3",
|
"version": "2.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
@ -5489,7 +5760,7 @@
|
|||||||
"pify": {
|
"pify": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
|
||||||
"integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY="
|
"integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg=="
|
||||||
},
|
},
|
||||||
"psl": {
|
"psl": {
|
||||||
"version": "1.1.29",
|
"version": "1.1.29",
|
||||||
@ -5569,7 +5840,7 @@
|
|||||||
"requires-port": {
|
"requires-port": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
"integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
|
||||||
},
|
},
|
||||||
"rfdc": {
|
"rfdc": {
|
||||||
"version": "1.3.0",
|
"version": "1.3.0",
|
||||||
@ -5693,7 +5964,7 @@
|
|||||||
"through": {
|
"through": {
|
||||||
"version": "2.3.8",
|
"version": "2.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||||
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
"integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
|
||||||
},
|
},
|
||||||
"tough-cookie": {
|
"tough-cookie": {
|
||||||
"version": "2.4.3",
|
"version": "2.4.3",
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
"@aws-sdk/client-s3": "3.637.0",
|
"@aws-sdk/client-s3": "3.637.0",
|
||||||
"@aws-sdk/node-http-handler": "3.374.0",
|
"@aws-sdk/node-http-handler": "3.374.0",
|
||||||
"@aws-sdk/s3-request-presigner": "3.370.0",
|
"@aws-sdk/s3-request-presigner": "3.370.0",
|
||||||
|
"@azure/storage-blob": "12.27.0",
|
||||||
"amqplib": "0.8.0",
|
"amqplib": "0.8.0",
|
||||||
"co": "4.6.0",
|
"co": "4.6.0",
|
||||||
"config": "2.0.1",
|
"config": "2.0.1",
|
||||||
|
|||||||
207
Common/sources/storage-az.js
Normal file
207
Common/sources/storage-az.js
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
'use strict';
|
||||||
|
const fs = require('fs');
|
||||||
|
const url = require('url');
|
||||||
|
const path = require('path');
|
||||||
|
const { BlobServiceClient, StorageSharedKeyCredential, generateBlobSASQueryParameters, BlobSASPermissions } = require('@azure/storage-blob');
|
||||||
|
const mime = require('mime');
|
||||||
|
const config = require('config');
|
||||||
|
const { Readable } = require('stream');
|
||||||
|
const utils = require('./utils');
|
||||||
|
const ms = require('ms');
|
||||||
|
const commonDefines = require('./../../Common/sources/commondefines');
|
||||||
|
|
||||||
|
const cfgExpSessionAbsolute = ms(config.get('services.CoAuthoring.expire.sessionabsolute'));
|
||||||
|
const MAX_DELETE_OBJECTS = 1000;
|
||||||
|
let blobServiceClients = {};
|
||||||
|
|
||||||
|
function getBlobServiceClient(storageCfg) {
|
||||||
|
const configKey = `${storageCfg.accessKeyId}_${storageCfg.bucketName}`;
|
||||||
|
if (!blobServiceClients[configKey]) {
|
||||||
|
const credential = new StorageSharedKeyCredential(
|
||||||
|
storageCfg.accessKeyId,
|
||||||
|
storageCfg.secretAccessKey
|
||||||
|
);
|
||||||
|
blobServiceClients[configKey] = new BlobServiceClient(
|
||||||
|
`https://${storageCfg.accessKeyId}.blob.core.windows.net`,
|
||||||
|
credential
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return blobServiceClients[configKey];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getContainerClient(storageCfg) {
|
||||||
|
const blobServiceClient = getBlobServiceClient(storageCfg);
|
||||||
|
return blobServiceClient.getContainerClient(storageCfg.bucketName);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBlobClient(storageCfg, blobName) {
|
||||||
|
const containerClient = getContainerClient(storageCfg);
|
||||||
|
return containerClient.getBlockBlobClient(blobName);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFilePath(storageCfg, strPath) {
|
||||||
|
const storageFolderName = storageCfg.storageFolderName;
|
||||||
|
return `${storageFolderName}/${strPath}`
|
||||||
|
}
|
||||||
|
|
||||||
|
async function listObjectsExec(storageCfg, prefix, output = []) {
|
||||||
|
const containerClient = getContainerClient(storageCfg);
|
||||||
|
const storageFolderName = storageCfg.storageFolderName;
|
||||||
|
const prefixWithFolder = storageFolderName ? `${storageFolderName}/${prefix}` : prefix;
|
||||||
|
|
||||||
|
for await (const blob of containerClient.listBlobsFlat({ prefix: prefixWithFolder })) {
|
||||||
|
const relativePath = storageFolderName ?
|
||||||
|
blob.name.substring(storageFolderName.length + 1) : blob.name;
|
||||||
|
output.push(relativePath);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteObjectsHelp(storageCfg, aKeys) {
|
||||||
|
const containerClient = getContainerClient(storageCfg);
|
||||||
|
await Promise.all(
|
||||||
|
aKeys.map(key => containerClient.deleteBlob(key.Key))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function headObject(storageCfg, strPath) {
|
||||||
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
|
const properties = await blobClient.getProperties();
|
||||||
|
return { ContentLength: properties.contentLength };
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getObject(storageCfg, strPath) {
|
||||||
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
|
const response = await blobClient.download();
|
||||||
|
return await utils.stream2Buffer(response.readableStreamBody);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function createReadStream(storageCfg, strPath) {
|
||||||
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
|
const response = await blobClient.download();
|
||||||
|
return {
|
||||||
|
contentLength: response.contentLength,
|
||||||
|
readStream: response.readableStreamBody
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function putObject(storageCfg, strPath, buffer, contentLength) {
|
||||||
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
|
|
||||||
|
const uploadOptions = {
|
||||||
|
blobHTTPHeaders: {
|
||||||
|
contentType: mime.getType(strPath),
|
||||||
|
contentDisposition: utils.getContentDisposition(path.basename(strPath))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (buffer instanceof Buffer) {
|
||||||
|
// Handle Buffer upload
|
||||||
|
await blobClient.uploadData(buffer, uploadOptions);
|
||||||
|
} else if (typeof buffer.pipe === 'function') {
|
||||||
|
// Handle Stream upload
|
||||||
|
await blobClient.uploadStream(buffer, undefined, undefined, uploadOptions);
|
||||||
|
} else {
|
||||||
|
throw new TypeError('Input must be Buffer or Readable stream');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function uploadObject(storageCfg, strPath, filePath) {
|
||||||
|
const blockBlobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
|
const input = fs.createReadStream(filePath);
|
||||||
|
const uploadStream = input instanceof Readable ? input : new Readable({
|
||||||
|
read() {
|
||||||
|
this.push(input);
|
||||||
|
this.push(null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
uploadStream.on('error', reject);
|
||||||
|
blockBlobClient.uploadStream(
|
||||||
|
uploadStream,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
blobHTTPHeaders: {
|
||||||
|
contentType: mime.getType(strPath),
|
||||||
|
contentDisposition: utils.getContentDisposition(path.basename(strPath))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(resolve)
|
||||||
|
.catch(reject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function copyObject(storageCfgSrc, storageCfgDst, sourceKey, destinationKey) {
|
||||||
|
const sourceBlobClient = getBlobClient(storageCfgSrc, getFilePath(storageCfgSrc, sourceKey));
|
||||||
|
const destBlobClient = getBlobClient(storageCfgDst, getFilePath(storageCfgDst, destinationKey));
|
||||||
|
const sasToken = generateBlobSASQueryParameters({
|
||||||
|
containerName: storageCfgSrc.bucketName,
|
||||||
|
blobName: getFilePath(storageCfgSrc, sourceKey),
|
||||||
|
permissions: BlobSASPermissions.parse("r"),
|
||||||
|
startsOn: new Date(),
|
||||||
|
expiresOn: new Date(Date.now() + 3600 * 1000)
|
||||||
|
}, new StorageSharedKeyCredential(storageCfgSrc.accessKeyId, storageCfgSrc.secretAccessKey)).toString();
|
||||||
|
|
||||||
|
await destBlobClient.syncCopyFromURL(`${sourceBlobClient.url}?${sasToken}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function listObjects(storageCfg, strPath) {
|
||||||
|
return await listObjectsExec(storageCfg, strPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteObject(storageCfg, strPath) {
|
||||||
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
|
await blobClient.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteObjects(storageCfg, strPaths) {
|
||||||
|
let aKeys = strPaths.map(path => ({ Key: getFilePath(storageCfg, path) }));
|
||||||
|
for (let i = 0; i < aKeys.length; i += MAX_DELETE_OBJECTS) {
|
||||||
|
await deleteObjectsHelp(storageCfg, aKeys.slice(i, i + MAX_DELETE_OBJECTS));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deletePath(storageCfg, strPath) {
|
||||||
|
let list = await listObjects(storageCfg, strPath);
|
||||||
|
await deleteObjects(storageCfg, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getSignedUrlWrapper(ctx, storageCfg, baseUrl, strPath, urlType, optFilename, opt_creationDate) {
|
||||||
|
const storageUrlExpires = storageCfg.fs.urlExpires;
|
||||||
|
let expires = (commonDefines.c_oAscUrlTypes.Session === urlType ? cfgExpSessionAbsolute / 1000 : storageUrlExpires) || 31536000;
|
||||||
|
expires = Math.min(expires, 604800);
|
||||||
|
|
||||||
|
const userFriendlyName = optFilename ? optFilename.replace(/\//g, "%2f") : path.basename(strPath);
|
||||||
|
const contentDisposition = utils.getContentDisposition(userFriendlyName, null, null);
|
||||||
|
|
||||||
|
const blobClient = getBlobClient(storageCfg, getFilePath(storageCfg, strPath));
|
||||||
|
|
||||||
|
const sasOptions = {
|
||||||
|
permissions: BlobSASPermissions.parse("r"),
|
||||||
|
expiresOn: new Date(Date.now() + expires * 1000),
|
||||||
|
contentDisposition,
|
||||||
|
contentType: mime.getType(strPath)
|
||||||
|
};
|
||||||
|
|
||||||
|
return await blobClient.generateSasUrl(sasOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
function needServeStatic() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
headObject,
|
||||||
|
getObject,
|
||||||
|
createReadStream,
|
||||||
|
putObject,
|
||||||
|
uploadObject,
|
||||||
|
copyObject,
|
||||||
|
listObjects,
|
||||||
|
deleteObject,
|
||||||
|
deletePath,
|
||||||
|
getSignedUrl: getSignedUrlWrapper,
|
||||||
|
needServeStatic
|
||||||
|
};
|
||||||
@ -78,6 +78,7 @@
|
|||||||
"integration tests with server instance": "cd ./DocService && jest integration/withServerInstance --inject-globals=false --config=../tests/jest.config.js",
|
"integration tests with server instance": "cd ./DocService && jest integration/withServerInstance --inject-globals=false --config=../tests/jest.config.js",
|
||||||
"integration database tests": "cd ./DocService && jest integration/databaseTests --inject-globals=false --config=../tests/jest.config.js",
|
"integration database tests": "cd ./DocService && jest integration/databaseTests --inject-globals=false --config=../tests/jest.config.js",
|
||||||
"tests": "cd ./DocService && jest --inject-globals=false --config=../tests/jest.config.js",
|
"tests": "cd ./DocService && jest --inject-globals=false --config=../tests/jest.config.js",
|
||||||
|
"tests:dev": "cd ./DocService && jest --inject-globals=false --config=../tests/jest.config.js --watch",
|
||||||
"install:Common": "npm ci --prefix ./Common",
|
"install:Common": "npm ci --prefix ./Common",
|
||||||
"install:DocService": "npm ci --prefix ./DocService",
|
"install:DocService": "npm ci --prefix ./DocService",
|
||||||
"install:FileConverter": "npm ci --prefix ./FileConverter",
|
"install:FileConverter": "npm ci --prefix ./FileConverter",
|
||||||
|
|||||||
@ -50,6 +50,7 @@ const cfgTokenEnableRequestOutbox = config.get('services.CoAuthoring.token.enabl
|
|||||||
const cfgStorageName = config.get('storage.name');
|
const cfgStorageName = config.get('storage.name');
|
||||||
const cfgEndpoint = config.get('storage.endpoint');
|
const cfgEndpoint = config.get('storage.endpoint');
|
||||||
const cfgBucketName = config.get('storage.bucketName');
|
const cfgBucketName = config.get('storage.bucketName');
|
||||||
|
const cfgAccessKeyId = config.get('storage.accessKeyId');
|
||||||
const ctx = new operationContext.Context();
|
const ctx = new operationContext.Context();
|
||||||
|
|
||||||
const testFilesNames = {
|
const testFilesNames = {
|
||||||
@ -184,12 +185,18 @@ describe('Command service', function () {
|
|||||||
let urlPattern;
|
let urlPattern;
|
||||||
if ("storage-fs" === cfgStorageName) {
|
if ("storage-fs" === cfgStorageName) {
|
||||||
urlPattern = 'http://localhost:8000/cache/files/forgotten/--key--/output.docx/output.docx';
|
urlPattern = 'http://localhost:8000/cache/files/forgotten/--key--/output.docx/output.docx';
|
||||||
} else {
|
} else if ("storage-s3" === cfgStorageName) {
|
||||||
let host = cfgEndpoint.slice(0, "https://".length) + cfgBucketName + "." + cfgEndpoint.slice("https://".length);
|
let host = cfgEndpoint.slice(0, "https://".length) + cfgBucketName + "." + cfgEndpoint.slice("https://".length);
|
||||||
if (host[host.length - 1] === '/') {
|
if (host[host.length - 1] === '/') {
|
||||||
host = host.slice(0, -1);
|
host = host.slice(0, -1);
|
||||||
}
|
}
|
||||||
urlPattern = host + '/files/forgotten/--key--/output.docx';
|
urlPattern = host + '/files/forgotten/--key--/output.docx';
|
||||||
|
} else {
|
||||||
|
let host = cfgEndpoint.slice(0, "https://".length) + cfgAccessKeyId + "." + cfgEndpoint.slice("https://".length) + '/' + cfgBucketName;
|
||||||
|
if (host[host.length - 1] === '/') {
|
||||||
|
host = host.slice(0, -1);
|
||||||
|
}
|
||||||
|
urlPattern = host + '/files/forgotten/--key--/output.docx';
|
||||||
}
|
}
|
||||||
|
|
||||||
const expected = { key, error };
|
const expected = { key, error };
|
||||||
|
|||||||
Reference in New Issue
Block a user