From dcb07a709d0e8addca9b033c7708a4cf6d4eed92 Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+samtv12345@users.noreply.github.com> Date: Mon, 19 Aug 2024 20:17:22 +0200 Subject: [PATCH] Added post install script --- .github/workflows/backend-tests.yml | 27 +-- .github/workflows/frontend-admin-tests.yml | 4 - package.json | 6 +- pnpm-lock.yaml | 201 ++------------------- postinstall.js | 23 +++ src/node/hooks/express.ts | 1 - src/node/hooks/express/admin.ts | 76 +++----- src/node/utils/Minify.ts | 2 +- src/package.json | 3 +- src/static/js/ace.ts | 3 +- 10 files changed, 65 insertions(+), 281 deletions(-) create mode 100644 postinstall.js diff --git a/.github/workflows/backend-tests.yml b/.github/workflows/backend-tests.yml index 485cb5eed..7c598b466 100644 --- a/.github/workflows/backend-tests.yml +++ b/.github/workflows/backend-tests.yml @@ -57,15 +57,8 @@ jobs: with: packages: libreoffice libreoffice-pdfimport version: 1.0 - - - name: Install all dependencies and symlink for ep_etherpad-lite - run: bin/installDeps.sh - name: Install admin ui - working-directory: admin run: pnpm install - - name: Build admin ui - working-directory: admin - run: pnpm build - name: Run the backend tests run: pnpm test @@ -118,14 +111,8 @@ jobs: packages: libreoffice libreoffice-pdfimport version: 1.0 - - name: Install all dependencies and symlink for ep_etherpad-lite - run: bin/installDeps.sh - - name: Install admin ui - working-directory: admin + name: Install Etherpad run: pnpm install - - name: Build admin ui - working-directory: admin - run: pnpm build - name: Install Etherpad plugins run: > @@ -185,13 +172,7 @@ jobs: run: pnpm config set auto-install-peers false - name: Install all dependencies and symlink for ep_etherpad-lite - run: bin/installOnWindows.bat - - name: Install admin ui - working-directory: admin run: pnpm install - - name: Build admin ui - working-directory: admin - run: pnpm build - name: Fix up the settings.json run: | @@ -240,12 +221,8 @@ jobs: ${{ runner.os }}-pnpm-store- - name: Only install direct dependencies run: pnpm config set auto-install-peers false - - name: Install admin ui - working-directory: admin + - name: Build Etherpad run: pnpm install - - name: Build admin ui - working-directory: admin - run: pnpm build - name: Install Etherpad plugins # The --legacy-peer-deps flag is required to work around a bug in npm diff --git a/.github/workflows/frontend-admin-tests.yml b/.github/workflows/frontend-admin-tests.yml index 9231cb6ff..b68b747aa 100644 --- a/.github/workflows/frontend-admin-tests.yml +++ b/.github/workflows/frontend-admin-tests.yml @@ -96,10 +96,6 @@ jobs: name: Disable import/export rate limiting run: | sed -e '/^ *"importExportRateLimiting":/,/^ *\}/ s/"max":.*/"max": 100000000/' -i settings.json - - name: Build admin frontend - working-directory: admin - run: | - pnpm run build # name: Run the frontend admin tests # shell: bash # env: diff --git a/package.json b/package.json index 149d3e60b..601dfd631 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,12 @@ "remove-plugins": "pnpm --filter bin run remove-plugins", "list-plugins": "pnpm --filter bin run list-plugins", "build:etherpad": "pnpm --filter admin run build-copy && pnpm --filter ui run build-copy", - "build:ui": "pnpm --filter ui run build-copy && pnpm --filter admin run build-copy" + "build:ui": "pnpm --filter ui run build-copy && pnpm --filter admin run build-copy", + "postinstall": "node ./postinstall.js" }, "dependencies": { - "ep_etherpad-lite": "workspace:./src" + "ep_etherpad-lite": "workspace:./src", + "cross-env": "^7.0.3" }, "devDependencies": { "admin": "workspace:./admin", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1f1b93941..867e0e0ac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,9 @@ importers: .: dependencies: + cross-env: + specifier: ^7.0.3 + version: 7.0.3 ep_etherpad-lite: specifier: workspace:./src version: link:src @@ -141,8 +144,8 @@ importers: src: dependencies: '@etherpad/express-session': - specifier: ^1.18.2 - version: 1.18.2 + specifier: ^1.18.4 + version: 1.18.4 async: specifier: ^3.2.5 version: 3.2.5 @@ -164,12 +167,9 @@ importers: esbuild: specifier: ^0.23.0 version: 0.23.0 - express: - specifier: 4.19.2 - version: 4.19.2 express-rate-limit: specifier: ^7.4.0 - version: 7.4.0(express@4.19.2) + version: 7.4.0 fast-deep-equal: specifier: ^3.1.3 version: 3.1.3 @@ -886,8 +886,8 @@ packages: resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@etherpad/express-session@1.18.2': - resolution: {integrity: sha512-5S+mdCxqSR5AX9jj1G3Qzxv/EX4jyWr9ikHzwtv+uV9fPu7EPFF6oNkhrUCZ19RJ5975KulPyrBB35hUK5x7LA==} + '@etherpad/express-session@1.18.4': + resolution: {integrity: sha512-uiUtcfv0hyEA+Lur00V6yINaa/qe09HiFqmc+DzSXYChILFLgOV3G4p4XJkIRrUOGmqaJRiliB1BoQIiY3Tnjw==} engines: {node: '>= 0.8.0'} '@humanwhocodes/module-importer@1.0.1': @@ -1932,9 +1932,6 @@ packages: resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} engines: {node: '>= 0.4'} - array-flatten@1.1.1: - resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} - array-includes@3.1.8: resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} engines: {node: '>= 0.4'} @@ -2010,10 +2007,6 @@ packages: birpc@0.2.17: resolution: {integrity: sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==} - body-parser@1.20.2: - resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} - engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - brace-expansion@1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -2181,10 +2174,6 @@ packages: resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} engines: {node: '>= 0.6'} - cookie@0.6.0: - resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==} - engines: {node: '>= 0.6'} - cookiejar@2.1.4: resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} @@ -2249,14 +2238,6 @@ packages: resolution: {integrity: sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==} engines: {node: '>=4.0'} - debug@2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -2634,10 +2615,6 @@ packages: resolution: {integrity: sha512-tCsc7WXTjrTx4ZjYLplcqrI3o4mYJ+Z6YspeuGL8tbt/hHoMchwBwtKfwM09svEY86iRapY93vUqQttcNuIO5Q==} engines: {node: '>=6.0.0'} - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - etherpad-cli-client@3.0.2: resolution: {integrity: sha512-3uJxz8cx1WSVAPe7haqfwQj4N4wWDrei5BXBjH+e1BLPiEpqWtnMX29Qo9jWhqO9ctyPPHO0nZ1x/ZCNxMVCqA==} engines: {node: '>=18.0.0'} @@ -2653,10 +2630,6 @@ packages: peerDependencies: express: 4 || 5 || ^5.0.0-beta.1 - express@4.19.2: - resolution: {integrity: sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==} - engines: {node: '>= 0.10.0'} - extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} @@ -2701,10 +2674,6 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} - finalhandler@1.2.0: - resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} - engines: {node: '>= 0.8'} - find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} @@ -3401,9 +3370,6 @@ packages: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} - merge-descriptors@1.0.1: - resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} - merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -3442,11 +3408,6 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime@1.6.0: - resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} - engines: {node: '>=4'} - hasBin: true - mime@2.6.0: resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} engines: {node: '>=4.0.0'} @@ -3516,9 +3477,6 @@ packages: mock-json-schema@1.1.1: resolution: {integrity: sha512-YV23vlsLP1EEOy0EviUvZTluXjLR+rhMzeayP2rcDiezj3RW01MhOSQkbQskdtg0K2fnGas5LKbSXgNjAOSX4A==} - ms@2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} @@ -3708,9 +3666,6 @@ packages: path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - path-to-regexp@0.1.7: - resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} - path-to-regexp@6.2.2: resolution: {integrity: sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==} @@ -3784,10 +3739,6 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - qs@6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - qs@6.12.3: resolution: {integrity: sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==} engines: {node: '>=0.6'} @@ -4007,17 +3958,9 @@ packages: engines: {node: '>=10'} hasBin: true - send@0.18.0: - resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} - engines: {node: '>= 0.8.0'} - serialize-javascript@6.0.2: resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - serve-static@1.15.0: - resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} - engines: {node: '>= 0.8.0'} - set-cookie-parser@2.7.0: resolution: {integrity: sha512-lXLOiqpkUumhRdFF3k1osNXCy9akgx/dyPZ5p8qAg9seJzXr5ZrlqZuWIMuY6ejOsVLE6flJ5/h3lsn57fQ/PQ==} @@ -4435,10 +4378,6 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 - utils-merge@1.0.1: - resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} - engines: {node: '>= 0.4.0'} - vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -5161,11 +5100,11 @@ snapshots: '@eslint/object-schema@2.1.4': {} - '@etherpad/express-session@1.18.2': + '@etherpad/express-session@1.18.4': dependencies: cookie: 0.4.2 cookie-signature: 1.0.6 - debug: 2.6.9 + debug: 4.3.5(supports-color@8.1.1) depd: 2.0.0 on-headers: 1.0.2 parseurl: 1.3.3 @@ -6252,8 +6191,6 @@ snapshots: call-bind: 1.0.7 is-array-buffer: 3.0.4 - array-flatten@1.1.1: {} - array-includes@3.1.8: dependencies: call-bind: 1.0.7 @@ -6339,23 +6276,6 @@ snapshots: birpc@0.2.17: {} - body-parser@1.20.2: - dependencies: - bytes: 3.1.2 - content-type: 1.0.5 - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - http-errors: 2.0.0 - iconv-lite: 0.4.24 - on-finished: 2.4.1 - qs: 6.11.0 - raw-body: 2.5.2 - type-is: 1.6.18 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - brace-expansion@1.1.11: dependencies: balanced-match: 1.0.2 @@ -6519,8 +6439,6 @@ snapshots: cookie@0.5.0: {} - cookie@0.6.0: {} - cookiejar@2.1.4: {} cookies@0.9.1: @@ -6589,10 +6507,6 @@ snapshots: date-format@4.0.14: {} - debug@2.6.9: - dependencies: - ms: 2.0.0 - debug@3.2.7: dependencies: ms: 2.1.3 @@ -7111,8 +7025,6 @@ snapshots: eta@3.4.0: {} - etag@1.8.1: {} - etherpad-cli-client@3.0.2: dependencies: async: 3.2.5 @@ -7135,45 +7047,7 @@ snapshots: signal-exit: 4.1.0 strip-final-newline: 3.0.0 - express-rate-limit@7.4.0(express@4.19.2): - dependencies: - express: 4.19.2 - - express@4.19.2: - dependencies: - accepts: 1.3.8 - array-flatten: 1.1.1 - body-parser: 1.20.2 - content-disposition: 0.5.4 - content-type: 1.0.5 - cookie: 0.6.0 - cookie-signature: 1.0.6 - debug: 2.6.9 - depd: 2.0.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - finalhandler: 1.2.0 - fresh: 0.5.2 - http-errors: 2.0.0 - merge-descriptors: 1.0.1 - methods: 1.1.2 - on-finished: 2.4.1 - parseurl: 1.3.3 - path-to-regexp: 0.1.7 - proxy-addr: 2.0.7 - qs: 6.11.0 - range-parser: 1.2.1 - safe-buffer: 5.2.1 - send: 0.18.0 - serve-static: 1.15.0 - setprototypeof: 1.2.0 - statuses: 2.0.1 - type-is: 1.6.18 - utils-merge: 1.0.1 - vary: 1.1.2 - transitivePeerDependencies: - - supports-color + express-rate-limit@7.4.0: {} extend@3.0.2: {} @@ -7220,18 +7094,6 @@ snapshots: dependencies: to-regex-range: 5.0.1 - finalhandler@1.2.0: - dependencies: - debug: 2.6.9 - encodeurl: 1.0.2 - escape-html: 1.0.3 - on-finished: 2.4.1 - parseurl: 1.3.3 - statuses: 2.0.1 - unpipe: 1.0.0 - transitivePeerDependencies: - - supports-color - find-root@1.1.0: {} find-up@5.0.0: @@ -8044,8 +7906,6 @@ snapshots: media-typer@0.3.0: {} - merge-descriptors@1.0.1: {} - merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -8080,8 +7940,6 @@ snapshots: dependencies: mime-db: 1.52.0 - mime@1.6.0: {} - mime@2.6.0: {} mimic-fn@4.0.0: {} @@ -8152,8 +8010,6 @@ snapshots: dependencies: lodash: 4.17.21 - ms@2.0.0: {} - ms@2.1.2: {} ms@2.1.3: {} @@ -8367,8 +8223,6 @@ snapshots: path-parse@1.0.7: {} - path-to-regexp@0.1.7: {} - path-to-regexp@6.2.2: {} path-type@4.0.0: {} @@ -8433,10 +8287,6 @@ snapshots: punycode@2.3.1: {} - qs@6.11.0: - dependencies: - side-channel: 1.0.6 - qs@6.12.3: dependencies: side-channel: 1.0.6 @@ -8663,37 +8513,10 @@ snapshots: semver@7.6.3: {} - send@0.18.0: - dependencies: - debug: 2.6.9 - depd: 2.0.0 - destroy: 1.2.0 - encodeurl: 1.0.2 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 0.5.2 - http-errors: 2.0.0 - mime: 1.6.0 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.1 - transitivePeerDependencies: - - supports-color - serialize-javascript@6.0.2: dependencies: randombytes: 2.1.0 - serve-static@1.15.0: - dependencies: - encodeurl: 1.0.2 - escape-html: 1.0.3 - parseurl: 1.3.3 - send: 0.18.0 - transitivePeerDependencies: - - supports-color - set-cookie-parser@2.7.0: {} set-function-length@1.2.2: @@ -9174,8 +8997,6 @@ snapshots: dependencies: react: 18.3.1 - utils-merge@1.0.1: {} - vary@1.1.2: {} vfile-location@5.0.3: diff --git a/postinstall.js b/postinstall.js new file mode 100644 index 000000000..01855354f --- /dev/null +++ b/postinstall.js @@ -0,0 +1,23 @@ +import { execSync } from 'child_process'; +import fs from 'fs'; +import path from 'path'; + +const packageJsonPath = path.resolve('./package.json'); +const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + +const devDependencies = packageJson.devDependencies || {}; +let allDevDependenciesInstalled = true; + +for (const dep in devDependencies) { + try { + console.log(dep) + fs.statSync('node_modules/' + dep); + } catch (error) { + allDevDependenciesInstalled = false; + console.error(`DevDependency ${dep} is not installed.`); + } +} + +if (allDevDependenciesInstalled) { + execSync('pnpm run build:etherpad', { stdio: 'inherit' }); +} diff --git a/src/node/hooks/express.ts b/src/node/hooks/express.ts index 950de28de..404d6ecd9 100644 --- a/src/node/hooks/express.ts +++ b/src/node/hooks/express.ts @@ -7,7 +7,6 @@ import _ from 'underscore'; // @ts-ignore import cookieParser from 'cookie-parser'; import events from 'events'; -import express from 'express'; // @ts-ignore import expressSession from '@etherpad/express-session'; import fs from 'fs'; diff --git a/src/node/hooks/express/admin.ts b/src/node/hooks/express/admin.ts index e802750f2..591396f21 100644 --- a/src/node/hooks/express/admin.ts +++ b/src/node/hooks/express/admin.ts @@ -6,8 +6,9 @@ import * as url from "node:url"; import {MapArrayType} from "../../types/MapType"; const settings = require('ep_etherpad-lite/node/utils/Settings'); +import LiveDirectory from "live-directory"; -const ADMIN_PATH = path.join(settings.root, 'src', 'templates'); +const ADMIN_PATH = path.join(settings.root, 'src', 'templates', 'admin'); const PROXY_HEADER = "x-proxy-path" /** * Add the admin navigation link @@ -22,63 +23,28 @@ exports.expressCreateServer = (hookName: string, args: ArgsExpressType, cb: Func console.error('admin template not found, skipping admin interface. You need to rebuild it in /admin with pnpm run build-copy') return cb(); } - args.app.get('/admin/*', (req: any, res: any) => { - // parse URL - const parsedUrl = url.parse(req.url); - // extract URL path - let pathname = ADMIN_PATH + `${parsedUrl.pathname}`; - // based on the URL path, extract the file extension. e.g. .js, .doc, ... - let ext = path.parse(pathname).ext; - // maps file extension to MIME typere - const map: MapArrayType = { - '.ico': 'image/x-icon', - '.html': 'text/html', - '.js': 'text/javascript', - '.json': 'application/json', - '.css': 'text/css', - '.png': 'image/png', - '.jpg': 'image/jpeg', - '.wav': 'audio/wav', - '.mp3': 'audio/mpeg', - '.svg': 'image/svg+xml', - '.pdf': 'application/pdf', - '.doc': 'application/msword' - }; - fs.exists(pathname, function (exist) { - if (!exist) { - // if the file is not found, return 404 - res.statusCode = 200; - pathname = ADMIN_PATH + "/admin/index.html" - ext = path.parse(pathname).ext; - } + const livedir = new LiveDirectory(ADMIN_PATH) - // if is a directory search for index file matching the extension - if (fs.statSync(pathname).isDirectory()) { - pathname = pathname + '/index.html'; - ext = path.parse(pathname).ext; - } - // read file from file system - fs.readFile(pathname, function (err, data) { - if (err) { - res.statusCode = 500; - res.end(`Error getting the file: ${err}.`); - } else { - let dataToSend:Buffer|string = data - // if the file is found, set Content-type and send data - res.setHeader('Content-type', map[ext] || 'text/plain'); - if (ext === ".html" || ext === ".js" || ext === ".css") { - if (req.header(PROXY_HEADER)) { - let string = data.toString() - dataToSend = string.replaceAll("/admin", req.header(PROXY_HEADER) + "/admin") - dataToSend = dataToSend.replaceAll("/socket.io", req.header(PROXY_HEADER) + "/socket.io") - } - } - res.end(dataToSend); - } - }); - }) + args.app.get('/admin/*', (req, res) => { + const path = req.path.replace('/admin', ''); + const file = livedir.get(path)||livedir.get('/index.html'); + + // Return a 404 if no asset/file exists on the derived path + if (file === undefined) return res.status(404).send(); + + const fileParts = file.path.split("."); + const ext = fileParts[fileParts.length - 1]; + // Retrieve the file content and serve it depending on the type of content available for this file + const content = file.content; + if (content instanceof Buffer) { + // Set appropriate mime-type and serve file content Buffer as response body (This means that the file content was cached in memory) + return res.type(ext).send(content); + } else { + // Set the type and stream the content as the response body (This means that the file content was NOT cached in memory) + return res.type(ext).stream(content); + } }); args.app.get('/admin', (req: any, res: any, next: Function) => { if ('/' !== req.path[req.path.length - 1]) return res.redirect('./admin/'); diff --git a/src/node/utils/Minify.ts b/src/node/utils/Minify.ts index 37c7e226f..8694d61cc 100644 --- a/src/node/utils/Minify.ts +++ b/src/node/utils/Minify.ts @@ -147,7 +147,7 @@ const compatPaths = { */ const _minify = async (req:any, res:any) => { - let filename = req.path.split('/static/')[1] + let filename = req.path.replace('/static/', ''); try { filename = sanitizePathname(filename); } catch (err) { diff --git a/src/package.json b/src/package.json index 434e10d1a..89226afd2 100644 --- a/src/package.json +++ b/src/package.json @@ -30,7 +30,7 @@ } ], "dependencies": { - "@etherpad/express-session": "^1.18.2", + "@etherpad/express-session": "^1.18.4", "async": "^3.2.5", "axios": "^1.7.4", "cookie-parser": "^1.4.6", @@ -38,7 +38,6 @@ "cross-spawn": "^7.0.3", "ejs": "^3.1.10", "esbuild": "^0.23.0", - "express": "4.19.2", "express-rate-limit": "^7.4.0", "fast-deep-equal": "^3.1.3", "find-root": "1.1.0", diff --git a/src/static/js/ace.ts b/src/static/js/ace.ts index 4c062584c..4d176cf00 100644 --- a/src/static/js/ace.ts +++ b/src/static/js/ace.ts @@ -152,10 +152,11 @@ const Ace2Editor = function () { this.prepareUserChangeset = () => loaded ? info.ace_prepareUserChangeset() : null; const addStyleTagsFor = (doc, files) => { - for (const file of files) { + for (let file of files) { const link = doc.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; + file = file.replaceAll('//', '/') link.href = absUrl(encodeURI(file)); doc.head.appendChild(link); }