mirror of
https://github.com/ether/etherpad-lite.git
synced 2025-01-19 14:13:34 +01:00
Live plugin manager (#6018)
* Added plugin live view. * Implemented PoC for managing plugins with live-plugin-manager * Add migration for plugins installed in node_modules and load plugins on start * Create installed_plugins.json even if no plugin is installed * Reload plugins and hooks after all (un)installs are done * Add installed_plugins.json to gitignore * Only write plugins to json file in Dockerfile * Install live-plugin-manager * Also persist plugin version * Do not call hooks during migration of plugins * Fix install of plugins in Dockerfile * Revert Dockerfile changes * Fixed package-lock.json --------- Co-authored-by: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Co-authored-by: Hossein M <marzban98@gmail.com>
This commit is contained in:
parent
6a2ffe6aaf
commit
9c14a4f7db
8 changed files with 357 additions and 77 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -21,3 +21,4 @@ out/
|
|||
/src/bin/convertSettings.json
|
||||
/src/bin/etherpad-1.deb
|
||||
/src/bin/node.exe
|
||||
plugin_packages
|
|
@ -76,6 +76,7 @@ exports.require = (name, args, mod) => {
|
|||
basedir = path.dirname(mod.filename);
|
||||
paths = mod.paths;
|
||||
}
|
||||
paths.push(settings.root + '/plugin_packages')
|
||||
|
||||
const ejspath = resolve.sync(name, {paths, basedir, extensions: ['.html', '.ejs']});
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ const express = require('./hooks/express');
|
|||
const hooks = require('../static/js/pluginfw/hooks');
|
||||
const pluginDefs = require('../static/js/pluginfw/plugin_defs');
|
||||
const plugins = require('../static/js/pluginfw/plugins');
|
||||
const installer = require('../static/js/pluginfw/installer');
|
||||
const {Gate} = require('./utils/promises');
|
||||
const stats = require('./stats');
|
||||
|
||||
|
@ -139,6 +140,7 @@ exports.start = async () => {
|
|||
}
|
||||
|
||||
await db.init();
|
||||
await installer.checkForMigration();
|
||||
await plugins.update();
|
||||
const installedPlugins = Object.values(pluginDefs.plugins)
|
||||
.filter((plugin) => plugin.package.name !== 'ep_etherpad-lite')
|
||||
|
|
287
src/package-lock.json
generated
287
src/package-lock.json
generated
|
@ -23,9 +23,9 @@
|
|||
}
|
||||
},
|
||||
"@asamuzakjp/dom-selector": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-2.0.1.tgz",
|
||||
"integrity": "sha512-QJAJffmCiymkv6YyQ7voyQb5caCth6jzZsQncYCpHXrJ7RqdYG5y43+is8mnFcYubdOkr7cn1+na9BdFMxqw7w==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-2.0.2.tgz",
|
||||
"integrity": "sha512-x1KXOatwofR6ZAYzXRBL5wrdV0vwNxlTCK9NCuLqAzQYARqGcvFwiJA6A1ERuh+dgeA4Dxm3JBYictIes+SqUQ==",
|
||||
"requires": {
|
||||
"bidi-js": "^1.0.3",
|
||||
"css-tree": "^2.3.1",
|
||||
|
@ -271,6 +271,22 @@
|
|||
"integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/debug": {
|
||||
"version": "4.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
|
||||
"integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
|
||||
"requires": {
|
||||
"@types/ms": "*"
|
||||
}
|
||||
},
|
||||
"@types/fs-extra": {
|
||||
"version": "9.0.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
|
||||
"integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/hast": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.1.tgz",
|
||||
|
@ -290,6 +306,11 @@
|
|||
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/lockfile": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/lockfile/-/lockfile-1.0.4.tgz",
|
||||
"integrity": "sha512-Q8oFIHJHr+htLrTXN2FuZfg+WXVHQRwU/hC2GpUu+Q8e3FUM9EDkS2pE3R2AO1ZGu56f479ybdMCNF1DAu8cAQ=="
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.199",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.199.tgz",
|
||||
|
@ -311,17 +332,52 @@
|
|||
"@types/unist": "*"
|
||||
}
|
||||
},
|
||||
"@types/ms": {
|
||||
"version": "0.7.34",
|
||||
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz",
|
||||
"integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.10.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.6.tgz",
|
||||
"integrity": "sha512-Vac8H+NlRNNlAmDfGUP7b5h/KA+AtWIzuXy0E6OyP8f1tCLYAtPvKRRDJjAPqhpCb0t6U2j7/xqAuLEebW2kiw==",
|
||||
"requires": {
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"@types/node-fetch": {
|
||||
"version": "2.6.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.10.tgz",
|
||||
"integrity": "sha512-PPpPK6F9ALFTn59Ka3BaL+qGuipRfxNE8qVgkp0bVixeiR2c2/L+IVOiBdu9JhhT22sWnQEp6YyHGI2b2+CMcA==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"form-data": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@types/semver": {
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.3.tgz",
|
||||
"integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw=="
|
||||
},
|
||||
"@types/tar": {
|
||||
"version": "6.1.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.10.tgz",
|
||||
"integrity": "sha512-60ZO+W0tRKJ3ggdzJKp75xKVlNogKYMqGvr2bMH/+k3T0BagfYTnbmVDFMJB1BFttz6yRgP5MDGP27eh7brrqw==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"minipass": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@types/unist": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.0.tgz",
|
||||
"integrity": "sha512-MFETx3tbTjE7Uk6vvnWINA/1iJ7LuMdO4fcq8UfF0pRbj01aGLduVvQcRyswuACJdpnHgg8E3rQLhaRdNEJS0w=="
|
||||
},
|
||||
"@types/url-join": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/url-join/-/url-join-4.0.1.tgz",
|
||||
"integrity": "sha512-wDXw9LEEUHyV+7UWy7U315nrJGJ7p1BzaCxDpEoLr789Dk1WDVMMlf3iBfbG2F8NdWnYyFbtTxUn2ZNbm1Q4LQ=="
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin": {
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
|
||||
|
@ -585,11 +641,6 @@
|
|||
"integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
|
||||
"integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw=="
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||
|
@ -921,6 +972,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"chownr": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
|
||||
"integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
|
||||
},
|
||||
"clean-css": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
|
||||
|
@ -2132,9 +2188,9 @@
|
|||
"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.15.4",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz",
|
||||
"integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw=="
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.5.tgz",
|
||||
"integrity": "sha512-vSFWUON1B+yAw1VN4xMfxgn5fTUiaOzAJCKBwIIgT/+7CuGy9+r+5gITvP62j3RmaD5Ph65UaERdOSRGUzZtgw=="
|
||||
},
|
||||
"for-each": {
|
||||
"version": "0.3.3",
|
||||
|
@ -2192,6 +2248,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"fs-minipass": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||
"requires": {
|
||||
"minipass": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
|
@ -3058,6 +3132,66 @@
|
|||
"immediate": "~3.0.5"
|
||||
}
|
||||
},
|
||||
"live-plugin-manager": {
|
||||
"version": "0.18.1",
|
||||
"resolved": "https://registry.npmjs.org/live-plugin-manager/-/live-plugin-manager-0.18.1.tgz",
|
||||
"integrity": "sha512-GvLMSaZ1Cc18o91NiHLRuPXm1z7xDiUXUGgQ6jAwGM/x0FY8vXXHa/+LMNb2zrkAV2bWULCs0FEwX9yRsmFZmw==",
|
||||
"requires": {
|
||||
"@types/debug": "^4.1.7",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
"@types/lockfile": "^1.0.2",
|
||||
"@types/node-fetch": "^2.5.12",
|
||||
"@types/semver": "^7.3.9",
|
||||
"@types/tar": "^6.1.1",
|
||||
"@types/url-join": "4.0.1",
|
||||
"debug": "^4.3.3",
|
||||
"fs-extra": "^10.0.0",
|
||||
"lockfile": "^1.0.4",
|
||||
"node-fetch": "^2.6.6",
|
||||
"semver": "^7.3.5",
|
||||
"tar": "^6.1.11",
|
||||
"url-join": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
|
||||
"integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
|
||||
"requires": {
|
||||
"ms": "2.1.2"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"jsonfile": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
|
||||
"integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
|
||||
"requires": {
|
||||
"graceful-fs": "^4.1.6",
|
||||
"universalify": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||
},
|
||||
"universalify": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
|
||||
"integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"locate-path": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
|
@ -3067,6 +3201,14 @@
|
|||
"p-locate": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"lockfile": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz",
|
||||
"integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==",
|
||||
"requires": {
|
||||
"signal-exit": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
|
@ -3270,6 +3412,35 @@
|
|||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
|
||||
"dev": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
|
||||
"integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ=="
|
||||
},
|
||||
"minizlib": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
|
||||
"integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
|
||||
"requires": {
|
||||
"minipass": "^3.0.0",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
|
||||
"integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
|
||||
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
|
||||
},
|
||||
"mocha": {
|
||||
"version": "10.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-10.2.0.tgz",
|
||||
|
@ -3483,6 +3654,35 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
|
||||
"requires": {
|
||||
"whatwg-url": "^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"tr46": {
|
||||
"version": "0.0.3",
|
||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
|
||||
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||
"integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
|
||||
},
|
||||
"whatwg-url": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
|
||||
"integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
|
||||
"requires": {
|
||||
"tr46": "~0.0.3",
|
||||
"webidl-conversions": "^3.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"nodeify": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/nodeify/-/nodeify-1.0.1.tgz",
|
||||
|
@ -3670,6 +3870,10 @@
|
|||
"string-width": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"bundled": true,
|
||||
|
@ -3919,8 +4123,7 @@
|
|||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
|
||||
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="
|
||||
"bundled": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
|
@ -6221,6 +6424,10 @@
|
|||
"strip-ansi": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "3.0.0",
|
||||
"bundled": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
"bundled": true
|
||||
|
@ -6256,13 +6463,6 @@
|
|||
"bundled": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"strip-eof": {
|
||||
|
@ -6582,8 +6782,7 @@
|
|||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
|
||||
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="
|
||||
"bundled": true
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "2.0.0",
|
||||
|
@ -6654,9 +6853,8 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"ansi-regex": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
|
||||
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="
|
||||
"version": "4.1.0",
|
||||
"bundled": true
|
||||
},
|
||||
"find-up": {
|
||||
"version": "3.0.0",
|
||||
|
@ -7422,6 +7620,11 @@
|
|||
"object-inspect": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
|
||||
},
|
||||
"sinon": {
|
||||
"version": "17.0.1",
|
||||
"resolved": "https://registry.npmjs.org/sinon/-/sinon-17.0.1.tgz",
|
||||
|
@ -7808,6 +8011,26 @@
|
|||
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
|
||||
"dev": true
|
||||
},
|
||||
"tar": {
|
||||
"version": "6.2.0",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz",
|
||||
"integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==",
|
||||
"requires": {
|
||||
"chownr": "^2.0.0",
|
||||
"fs-minipass": "^2.0.0",
|
||||
"minipass": "^5.0.0",
|
||||
"minizlib": "^2.1.1",
|
||||
"mkdirp": "^1.0.3",
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"minipass": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
|
||||
"integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "5.26.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.26.0.tgz",
|
||||
|
@ -8070,6 +8293,11 @@
|
|||
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz",
|
||||
"integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
|
||||
},
|
||||
"undici-types": {
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"unified": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/unified/-/unified-11.0.3.tgz",
|
||||
|
@ -8150,6 +8378,11 @@
|
|||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"url-join": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
|
||||
"integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
"jsdom": "^23.2.0",
|
||||
"jsonminify": "0.4.2",
|
||||
"languages4translatewiki": "0.1.3",
|
||||
"live-plugin-manager": "^0.18.1",
|
||||
"lodash.clonedeep": "4.5.0",
|
||||
"log4js": "^6.9.1",
|
||||
"measured-core": "^2.0.0",
|
||||
|
|
|
@ -6,10 +6,18 @@ const hooks = require('./hooks');
|
|||
const runCmd = require('../../../node/utils/run_cmd');
|
||||
const settings = require('../../../node/utils/Settings');
|
||||
const axios = require('axios');
|
||||
|
||||
const {PluginManager} = require("live-plugin-manager");
|
||||
const {promises: fs} = require("fs");
|
||||
const path = require("path");
|
||||
const logger = log4js.getLogger('plugins');
|
||||
|
||||
exports.manager = new PluginManager();
|
||||
|
||||
const installedPluginsPath = path.join(settings.root, 'var/installed_plugins.json');
|
||||
|
||||
const onAllTasksFinished = async () => {
|
||||
await plugins.update();
|
||||
await persistInstalledPlugins();
|
||||
settings.reloadSettings();
|
||||
await hooks.aCallAll('loadSettings', {settings});
|
||||
await hooks.aCallAll('restartServer');
|
||||
|
@ -31,41 +39,69 @@ const wrapTaskCb = (cb) => {
|
|||
};
|
||||
};
|
||||
|
||||
const migratePluginsFromNodeModules = async () => {
|
||||
logger.info('start migration of plugins in node_modules')
|
||||
// Notes:
|
||||
// * Do not pass `--prod` otherwise `npm ls` will fail if there is no `package.json`.
|
||||
// * The `--no-production` flag is required (or the `NODE_ENV` environment variable must be
|
||||
// unset or set to `development`) because otherwise `npm ls` will not mention any packages
|
||||
// that are not included in `package.json` (which is expected to not exist).
|
||||
const cmd = ['npm', 'ls', '--long', '--json', '--depth=0', '--no-production'];
|
||||
const {dependencies = {}} = JSON.parse(await runCmd(cmd, {stdio: [null, 'string']}));
|
||||
await Promise.all(Object.entries(dependencies).map(async ([pkg, info]) => {
|
||||
if (pkg.startsWith(plugins.prefix) && pkg !== 'ep_etherpad-lite') {
|
||||
await exports.manager.install(pkg)
|
||||
}
|
||||
}));
|
||||
await persistInstalledPlugins();
|
||||
}
|
||||
|
||||
exports.checkForMigration = async () => {
|
||||
logger.info('check installed plugins for migration')
|
||||
|
||||
try {
|
||||
await fs.access(installedPluginsPath, fs.constants.F_OK)
|
||||
} catch (err) {
|
||||
await migratePluginsFromNodeModules();
|
||||
}
|
||||
|
||||
const fileContent = await fs.readFile(installedPluginsPath);
|
||||
const installedPlugins = JSON.parse(fileContent.toString());
|
||||
|
||||
for (const plugin of installedPlugins.plugins) {
|
||||
if (plugin.name.startsWith(plugins.prefix) && plugin.name !== 'ep_etherpad-lite') {
|
||||
await exports.manager.install(plugin.name, plugin.version)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const persistInstalledPlugins = async () => {
|
||||
let installedPlugins = { plugins: []};
|
||||
for (const pkg of Object.values(await plugins.getPackages())) {
|
||||
installedPlugins.plugins.push({
|
||||
name: pkg.name,
|
||||
version: pkg.version,
|
||||
})
|
||||
}
|
||||
installedPlugins.plugins = [...new Set(installedPlugins.plugins)];
|
||||
await fs.writeFile(installedPluginsPath, JSON.stringify(installedPlugins));
|
||||
}
|
||||
|
||||
exports.uninstall = async (pluginName, cb = null) => {
|
||||
cb = wrapTaskCb(cb);
|
||||
logger.info(`Uninstalling plugin ${pluginName}...`);
|
||||
try {
|
||||
// The --no-save flag prevents npm from creating package.json or package-lock.json.
|
||||
// The --legacy-peer-deps flag is required to work around a bug in npm v7:
|
||||
// https://github.com/npm/cli/issues/2199
|
||||
await runCmd(['npm', 'uninstall', '--no-save', '--legacy-peer-deps', pluginName]);
|
||||
} catch (err) {
|
||||
logger.error(`Failed to uninstall plugin ${pluginName}`);
|
||||
cb(err || new Error(err));
|
||||
throw err;
|
||||
}
|
||||
await exports.manager.uninstall(pluginName);
|
||||
logger.info(`Successfully uninstalled plugin ${pluginName}`);
|
||||
await hooks.aCallAll('pluginUninstall', {pluginName});
|
||||
await plugins.update();
|
||||
cb(null);
|
||||
};
|
||||
|
||||
exports.install = async (pluginName, cb = null) => {
|
||||
cb = wrapTaskCb(cb);
|
||||
logger.info(`Installing plugin ${pluginName}...`);
|
||||
try {
|
||||
// The --no-save flag prevents npm from creating package.json or package-lock.json.
|
||||
// The --legacy-peer-deps flag is required to work around a bug in npm v7:
|
||||
// https://github.com/npm/cli/issues/2199
|
||||
await runCmd(['npm', 'install', '--no-save', '--legacy-peer-deps', pluginName]);
|
||||
} catch (err) {
|
||||
logger.error(`Failed to install plugin ${pluginName}`);
|
||||
cb(err || new Error(err));
|
||||
throw err;
|
||||
}
|
||||
await exports.manager.install(pluginName);
|
||||
logger.info(`Successfully installed plugin ${pluginName}`);
|
||||
await hooks.aCallAll('pluginInstall', {pluginName});
|
||||
await plugins.update();
|
||||
cb(null);
|
||||
};
|
||||
|
||||
|
@ -76,22 +112,21 @@ exports.getAvailablePlugins = (maxCacheAge) => {
|
|||
const nowTimestamp = Math.round(Date.now() / 1000);
|
||||
|
||||
return new Promise(async (resolve, reject) => {
|
||||
// check cache age before making any request
|
||||
if (exports.availablePlugins && maxCacheAge && (nowTimestamp - cacheTimestamp) <= maxCacheAge) {
|
||||
return resolve(exports.availablePlugins);
|
||||
}
|
||||
// check cache age before making any request
|
||||
if (exports.availablePlugins && maxCacheAge && (nowTimestamp - cacheTimestamp) <= maxCacheAge) {
|
||||
return resolve(exports.availablePlugins);
|
||||
}
|
||||
|
||||
await axios.get('https://static.etherpad.org/plugins.json', {headers: headers})
|
||||
.then(pluginsLoaded => {
|
||||
exports.availablePlugins = pluginsLoaded.data;
|
||||
cacheTimestamp = nowTimestamp;
|
||||
resolve(exports.availablePlugins);
|
||||
})
|
||||
await axios.get('https://static.etherpad.org/plugins.json', {headers: headers})
|
||||
.then((pluginsLoaded) => {
|
||||
exports.availablePlugins = pluginsLoaded.data;
|
||||
cacheTimestamp = nowTimestamp;
|
||||
resolve(exports.availablePlugins);})
|
||||
.catch(async err => {
|
||||
return reject(err);
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
exports.search = (searchTerm, maxCacheAge) => exports.getAvailablePlugins(maxCacheAge).then(
|
||||
|
|
|
@ -8,6 +8,8 @@ const runCmd = require('../../../node/utils/run_cmd');
|
|||
const tsort = require('./tsort');
|
||||
const pluginUtils = require('./shared');
|
||||
const defs = require('./plugin_defs');
|
||||
const {manager} = require('./installer');
|
||||
const settings = require("../../../node/utils/Settings");
|
||||
|
||||
const logger = log4js.getLogger('plugins');
|
||||
|
||||
|
@ -105,22 +107,26 @@ exports.update = async () => {
|
|||
};
|
||||
|
||||
exports.getPackages = async () => {
|
||||
logger.info('Running npm to get a list of installed plugins...');
|
||||
// Notes:
|
||||
// * Do not pass `--prod` otherwise `npm ls` will fail if there is no `package.json`.
|
||||
// * The `--no-production` flag is required (or the `NODE_ENV` environment variable must be
|
||||
// unset or set to `development`) because otherwise `npm ls` will not mention any packages
|
||||
// that are not included in `package.json` (which is expected to not exist).
|
||||
const cmd = ['npm', 'ls', '--long', '--json', '--depth=0', '--no-production'];
|
||||
const {dependencies = {}} = JSON.parse(await runCmd(cmd, {stdio: [null, 'string']}));
|
||||
await Promise.all(Object.entries(dependencies).map(async ([pkg, info]) => {
|
||||
if (!pkg.startsWith(exports.prefix)) {
|
||||
delete dependencies[pkg];
|
||||
return;
|
||||
let plugins = manager.list()
|
||||
let newDependencies = {}
|
||||
|
||||
for (const plugin of plugins) {
|
||||
if (!plugin.name.startsWith(exports.prefix)) {
|
||||
continue;
|
||||
}
|
||||
info.realPath = await fs.realpath(info.path);
|
||||
}));
|
||||
return dependencies;
|
||||
plugin.realPath = await fs.realpath(plugin.location);
|
||||
plugin.path = plugin.realPath;
|
||||
newDependencies[plugin.name] = plugin
|
||||
}
|
||||
|
||||
newDependencies['ep_etherpad-lite'] = {
|
||||
name: 'ep_etherpad-lite',
|
||||
version: settings.getEpVersion(),
|
||||
path: path.join(settings.root, 'node_modules/ep_etherpad-lite'),
|
||||
realPath: path.join(settings.root, 'src'),
|
||||
}
|
||||
|
||||
return newDependencies;
|
||||
};
|
||||
|
||||
const loadPlugin = async (packages, pluginName, plugins, parts) => {
|
||||
|
|
1
var/.gitignore
vendored
1
var/.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
sqlite.db
|
||||
minified*
|
||||
installed_plugins.json
|
Loading…
Reference in a new issue