From d8f9466b84ad755a6fd9e3247e469e4a14b0cbd3 Mon Sep 17 00:00:00 2001 From: xream Date: Thu, 31 Oct 2024 22:31:19 +0800 Subject: [PATCH] =?UTF-8?q?feat(wip):=20=E6=94=AF=E6=8C=81=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=20share=20token?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/package.json | 9 +- backend/pnpm-lock.yaml | 157 ++++------------------------ backend/src/constants.js | 1 + backend/src/restful/download.js | 3 + backend/src/restful/file.js | 2 + backend/src/restful/index.js | 42 +++----- backend/src/restful/miscs.js | 177 ++++++++++++++++++++++++++------ backend/src/utils/env.js | 4 - 8 files changed, 193 insertions(+), 202 deletions(-) diff --git a/backend/package.json b/backend/package.json index d0cc83351..2b0f79614 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.14.410", + "version": "2.14.411", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and ShadowRocket.", "main": "src/main.js", "scripts": { @@ -28,13 +28,12 @@ "http-proxy-middleware": "^2.0.6", "ip-address": "^9.0.5", "js-base64": "^3.7.2", - "jsonwebtoken": "^9.0.2", "jsrsasign": "^11.1.0", "lodash": "^4.17.21", + "ms": "^2.1.3", + "nanoid": "^3.3.3", "request": "^2.88.2", - "semver": "^7.3.7", - "static-js-yaml": "^1.0.0", - "uuid": "^8.3.2" + "static-js-yaml": "^1.0.0" }, "devDependencies": { "@babel/core": "^7.18.0", diff --git a/backend/pnpm-lock.yaml b/backend/pnpm-lock.yaml index 4c7febdc7..0332a3b3f 100644 --- a/backend/pnpm-lock.yaml +++ b/backend/pnpm-lock.yaml @@ -41,27 +41,24 @@ importers: js-base64: specifier: ^3.7.2 version: https://registry.npmmirror.com/js-base64/-/js-base64-3.7.2.tgz - jsonwebtoken: - specifier: ^9.0.2 - version: 9.0.2 jsrsasign: specifier: ^11.1.0 version: https://registry.npmmirror.com/jsrsasign/-/jsrsasign-11.1.0.tgz lodash: specifier: ^4.17.21 version: https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz + ms: + specifier: ^2.1.3 + version: 2.1.3 + nanoid: + specifier: ^3.3.3 + version: 3.3.3 request: specifier: ^2.88.2 version: https://registry.npmmirror.com/request/-/request-2.88.2.tgz - semver: - specifier: ^7.3.7 - version: https://registry.npmmirror.com/semver/-/semver-7.3.7.tgz static-js-yaml: specifier: ^1.0.0 version: https://registry.npmmirror.com/static-js-yaml/-/static-js-yaml-1.0.0.tgz - uuid: - specifier: ^8.3.2 - version: https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz devDependencies: '@babel/core': specifier: ^7.18.0 @@ -1509,9 +1506,6 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true - buffer-equal-constant-time@1.0.1: - resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==, tarball: https://registry.npmmirror.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz} - buffer-equal@https://registry.npmmirror.com/buffer-equal/-/buffer-equal-1.0.0.tgz: resolution: {integrity: sha512-tcBWO2Dl4e7Asr9hTGcpVrCe+F7DubpmqWCTbj4FHLmjqO2hIaC383acQubWtRJhdceqs5uBHs6Es+Sk//RKiQ==, tarball: https://registry.npmmirror.com/buffer-equal/-/buffer-equal-1.0.0.tgz} version: 1.0.0 @@ -2091,9 +2085,6 @@ packages: resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==, tarball: https://registry.npmmirror.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz} version: 0.1.2 - ecdsa-sig-formatter@1.0.11: - resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==, tarball: https://registry.npmmirror.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz} - ee-first@https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==, tarball: https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz} version: 1.1.1 @@ -3391,10 +3382,6 @@ packages: version: 1.3.1 engines: {'0': node >= 0.2.0} - jsonwebtoken@9.0.2: - resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==, tarball: https://registry.npmmirror.com/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz} - engines: {node: '>=12', npm: '>=6'} - jsprim@https://registry.npmmirror.com/jsprim/-/jsprim-1.4.1.tgz: resolution: {integrity: sha512-4Dj8Rf+fQ+/Pn7C5qeEX02op1WfOss3PKTE9Nsop3Dx+6UPxlm1dr/og7o2cRa5hNN07CACr4NFzRLtj/rjWog==, tarball: https://registry.npmmirror.com/jsprim/-/jsprim-1.4.1.tgz} version: 1.4.1 @@ -3413,12 +3400,6 @@ packages: resolution: {integrity: sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==, tarball: https://registry.npmmirror.com/just-debounce/-/just-debounce-1.1.0.tgz} version: 1.1.0 - jwa@1.4.1: - resolution: {integrity: sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==, tarball: https://registry.npmmirror.com/jwa/-/jwa-1.4.1.tgz} - - jws@3.2.2: - resolution: {integrity: sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==, tarball: https://registry.npmmirror.com/jws/-/jws-3.2.2.tgz} - keyv@https://registry.npmmirror.com/keyv/-/keyv-3.1.0.tgz: resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==, tarball: https://registry.npmmirror.com/keyv/-/keyv-3.1.0.tgz} version: 3.1.0 @@ -3510,24 +3491,6 @@ packages: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==, tarball: https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz} version: 4.0.8 - lodash.includes@4.3.0: - resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==, tarball: https://registry.npmmirror.com/lodash.includes/-/lodash.includes-4.3.0.tgz} - - lodash.isboolean@3.0.3: - resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==, tarball: https://registry.npmmirror.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz} - - lodash.isinteger@4.0.4: - resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==, tarball: https://registry.npmmirror.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz} - - lodash.isnumber@3.0.3: - resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==, tarball: https://registry.npmmirror.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz} - - lodash.isplainobject@4.0.6: - resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==, tarball: https://registry.npmmirror.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz} - - lodash.isstring@4.0.1: - resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==, tarball: https://registry.npmmirror.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz} - lodash.memoize@https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz: resolution: {integrity: sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==, tarball: https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz} version: 3.0.4 @@ -3536,9 +3499,6 @@ packages: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, tarball: https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz} version: 4.6.2 - lodash.once@4.1.1: - resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==, tarball: https://registry.npmmirror.com/lodash.once/-/lodash.once-4.1.1.tgz} - lodash.template@https://registry.npmmirror.com/lodash.template/-/lodash.template-4.5.0.tgz: resolution: {integrity: sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==, tarball: https://registry.npmmirror.com/lodash.template/-/lodash.template-4.5.0.tgz} version: 4.5.0 @@ -3741,24 +3701,17 @@ packages: engines: {node: '>= 0.8.0'} hasBin: true - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz} - - ms@https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz: + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==, tarball: https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz} - version: 2.0.0 - ms@https://registry.npmmirror.com/ms/-/ms-2.1.1.tgz: + ms@2.1.1: resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.1.tgz} - version: 2.1.1 - ms@https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz: + ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz} - version: 2.1.2 - ms@https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz: + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, tarball: https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz} - version: 2.1.3 multi-stage-sourcemap@https://registry.npmmirror.com/multi-stage-sourcemap/-/multi-stage-sourcemap-0.2.1.tgz: resolution: {integrity: sha512-umaOM+8BZByZIB/ciD3dQLzTv50rEkkGJV78ta/tIVc/J/rfGZY5y1R+fBD3oTaolx41mK8rRcyGtYbDXlzx8Q==, tarball: https://registry.npmmirror.com/multi-stage-sourcemap/-/multi-stage-sourcemap-0.2.1.tgz} @@ -3785,9 +3738,8 @@ packages: version: 2.1.1 hasBin: true - nanoid@https://registry.npmmirror.com/nanoid/-/nanoid-3.3.3.tgz: + nanoid@3.3.3: resolution: {integrity: sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==, tarball: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.3.tgz} - version: 3.3.3 engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -4511,9 +4463,6 @@ packages: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==, tarball: https://registry.npmmirror.com/ripemd160/-/ripemd160-2.0.2.tgz} version: 2.0.2 - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, tarball: https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz} - safe-buffer@https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==, tarball: https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz} version: 5.1.2 @@ -4552,11 +4501,6 @@ packages: resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==, tarball: https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz} hasBin: true - semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==, tarball: https://registry.npmmirror.com/semver/-/semver-7.6.3.tgz} - engines: {node: '>=10'} - hasBin: true - semver@https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz: resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==, tarball: https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz} version: 5.7.1 @@ -5235,11 +5179,6 @@ packages: deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. hasBin: true - uuid@https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz: - resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==, tarball: https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz} - version: 8.3.2 - hasBin: true - v8-compile-cache@https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz: resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==, tarball: https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz} version: 2.3.0 @@ -6824,8 +6763,6 @@ snapshots: node-releases: https://registry.npmmirror.com/node-releases/-/node-releases-2.0.4.tgz picocolors: https://registry.npmmirror.com/picocolors/-/picocolors-1.0.0.tgz - buffer-equal-constant-time@1.0.1: {} - buffer-equal@https://registry.npmmirror.com/buffer-equal/-/buffer-equal-1.0.0.tgz: {} buffer-from@https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz: {} @@ -7202,17 +7139,17 @@ snapshots: debug@https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz: dependencies: - ms: https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz + ms: 2.0.0 debug@https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz(supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz): dependencies: - ms: https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz + ms: 2.1.3 optionalDependencies: supports-color: https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz debug@https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz(supports-color@https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz): dependencies: - ms: https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz + ms: 2.1.2 optionalDependencies: supports-color: https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz @@ -7357,10 +7294,6 @@ snapshots: jsbn: https://registry.npmmirror.com/jsbn/-/jsbn-0.1.1.tgz safer-buffer: https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz - ecdsa-sig-formatter@1.0.11: - dependencies: - safe-buffer: 5.2.1 - ee-first@https://registry.npmmirror.com/ee-first/-/ee-first-1.1.1.tgz: {} electron-to-chromium@https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz: {} @@ -8561,19 +8494,6 @@ snapshots: jsonparse@https://registry.npmmirror.com/jsonparse/-/jsonparse-1.3.1.tgz: {} - jsonwebtoken@9.0.2: - dependencies: - jws: 3.2.2 - lodash.includes: 4.3.0 - lodash.isboolean: 3.0.3 - lodash.isinteger: 4.0.4 - lodash.isnumber: 3.0.3 - lodash.isplainobject: 4.0.6 - lodash.isstring: 4.0.1 - lodash.once: 4.1.1 - ms: 2.1.3 - semver: 7.6.3 - jsprim@https://registry.npmmirror.com/jsprim/-/jsprim-1.4.1.tgz: dependencies: assert-plus: https://registry.npmmirror.com/assert-plus/-/assert-plus-1.0.0.tgz @@ -8592,17 +8512,6 @@ snapshots: just-debounce@https://registry.npmmirror.com/just-debounce/-/just-debounce-1.1.0.tgz: {} - jwa@1.4.1: - dependencies: - buffer-equal-constant-time: 1.0.1 - ecdsa-sig-formatter: 1.0.11 - safe-buffer: 5.2.1 - - jws@3.2.2: - dependencies: - jwa: 1.4.1 - safe-buffer: 5.2.1 - keyv@https://registry.npmmirror.com/keyv/-/keyv-3.1.0.tgz: dependencies: json-buffer: https://registry.npmmirror.com/json-buffer/-/json-buffer-3.0.0.tgz @@ -8689,24 +8598,10 @@ snapshots: lodash.debounce@https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz: {} - lodash.includes@4.3.0: {} - - lodash.isboolean@3.0.3: {} - - lodash.isinteger@4.0.4: {} - - lodash.isnumber@3.0.3: {} - - lodash.isplainobject@4.0.6: {} - - lodash.isstring@4.0.1: {} - lodash.memoize@https://registry.npmmirror.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz: {} lodash.merge@https://registry.npmmirror.com/lodash.merge/-/lodash.merge-4.6.2.tgz: {} - lodash.once@4.1.1: {} - lodash.template@https://registry.npmmirror.com/lodash.template/-/lodash.template-4.5.0.tgz: dependencies: lodash._reinterpolate: https://registry.npmmirror.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz @@ -8881,8 +8776,8 @@ snapshots: js-yaml: https://registry.npmmirror.com/js-yaml/-/js-yaml-4.1.0.tgz log-symbols: https://registry.npmmirror.com/log-symbols/-/log-symbols-4.1.0.tgz minimatch: https://registry.npmmirror.com/minimatch/-/minimatch-5.0.1.tgz - ms: https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz - nanoid: https://registry.npmmirror.com/nanoid/-/nanoid-3.3.3.tgz + ms: 2.1.3 + nanoid: 3.3.3 serialize-javascript: https://registry.npmmirror.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz strip-json-comments: https://registry.npmmirror.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz supports-color: https://registry.npmmirror.com/supports-color/-/supports-color-8.1.1.tgz @@ -8909,15 +8804,13 @@ snapshots: through2: https://registry.npmmirror.com/through2/-/through2-2.0.5.tgz xtend: https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz - ms@2.1.3: {} - - ms@https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz: {} + ms@2.0.0: {} - ms@https://registry.npmmirror.com/ms/-/ms-2.1.1.tgz: {} + ms@2.1.1: {} - ms@https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz: {} + ms@2.1.2: {} - ms@https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz: {} + ms@2.1.3: {} multi-stage-sourcemap@https://registry.npmmirror.com/multi-stage-sourcemap/-/multi-stage-sourcemap-0.2.1.tgz: dependencies: @@ -8941,7 +8834,7 @@ snapshots: mutexify: https://registry.npmmirror.com/mutexify/-/mutexify-1.4.0.tgz pretty-hrtime: https://registry.npmmirror.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz - nanoid@https://registry.npmmirror.com/nanoid/-/nanoid-3.3.3.tgz: {} + nanoid@3.3.3: {} nanomatch@https://registry.npmmirror.com/nanomatch/-/nanomatch-1.2.13.tgz: dependencies: @@ -9553,8 +9446,6 @@ snapshots: hash-base: https://registry.npmmirror.com/hash-base/-/hash-base-3.1.0.tgz inherits: https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz - safe-buffer@5.2.1: {} - safe-buffer@https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.1.2.tgz: {} safe-buffer@https://registry.npmmirror.com/safe-buffer/-/safe-buffer-5.2.1.tgz: {} @@ -9587,8 +9478,6 @@ snapshots: semver@6.3.0: {} - semver@7.6.3: {} - semver@https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz: {} semver@https://registry.npmmirror.com/semver/-/semver-6.3.0.tgz: {} @@ -9610,7 +9499,7 @@ snapshots: fresh: https://registry.npmmirror.com/fresh/-/fresh-0.5.2.tgz http-errors: https://registry.npmmirror.com/http-errors/-/http-errors-1.7.2.tgz mime: https://registry.npmmirror.com/mime/-/mime-1.6.0.tgz - ms: https://registry.npmmirror.com/ms/-/ms-2.1.1.tgz + ms: 2.1.1 on-finished: https://registry.npmmirror.com/on-finished/-/on-finished-2.3.0.tgz range-parser: https://registry.npmmirror.com/range-parser/-/range-parser-1.2.1.tgz statuses: https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz @@ -10236,8 +10125,6 @@ snapshots: uuid@https://registry.npmmirror.com/uuid/-/uuid-3.4.0.tgz: {} - uuid@https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz: {} - v8-compile-cache@https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz: {} v8flags@https://registry.npmmirror.com/v8flags/-/v8flags-3.2.0.tgz: diff --git a/backend/src/constants.js b/backend/src/constants.js index 3a5cd9b58..d832a2567 100644 --- a/backend/src/constants.js +++ b/backend/src/constants.js @@ -6,6 +6,7 @@ export const FILES_KEY = 'files'; export const MODULES_KEY = 'modules'; export const ARTIFACTS_KEY = 'artifacts'; export const RULES_KEY = 'rules'; +export const TOKENS_KEY = 'tokens'; export const GIST_BACKUP_KEY = 'Auto Generated Sub-Store Backup'; export const GIST_BACKUP_FILE_NAME = 'Sub-Store'; export const ARTIFACT_REPOSITORY_KEY = 'Sub-Store Artifacts Repository'; diff --git a/backend/src/restful/download.js b/backend/src/restful/download.js index bf0282bca..8664170b7 100644 --- a/backend/src/restful/download.js +++ b/backend/src/restful/download.js @@ -13,6 +13,9 @@ import { getISO } from '@/utils/geo'; import env from '@/utils/env'; export default function register($app) { + $app.get('/share/col/:name', downloadCollection); + $app.get('/share/sub/:name', downloadSubscription); + $app.get('/download/collection/:name', downloadCollection); $app.get('/download/:name', downloadSubscription); $app.get( diff --git a/backend/src/restful/file.js b/backend/src/restful/file.js index bef287109..2a456a2e5 100644 --- a/backend/src/restful/file.js +++ b/backend/src/restful/file.js @@ -13,6 +13,8 @@ import { produceArtifact } from '@/restful/sync'; export default function register($app) { if (!$.read(FILES_KEY)) $.write([], FILES_KEY); + $app.get('/share/file/:name', getFile); + $app.route('/api/file/:name') .get(getFile) .patch(updateFile) diff --git a/backend/src/restful/index.js b/backend/src/restful/index.js index f56209b93..c863a9697 100644 --- a/backend/src/restful/index.js +++ b/backend/src/restful/index.js @@ -4,6 +4,7 @@ import migrate from '@/utils/migration'; import download from '@/utils/download'; import { syncArtifacts } from '@/restful/sync'; import { gistBackupAction } from '@/restful/miscs'; +import { TOKENS_KEY } from '@/constants'; import registerSubscriptionRoutes from './subscriptions'; import registerCollectionRoutes from './collections'; @@ -176,8 +177,6 @@ export default function serve() { fe_be_path === '/' ? '' : fe_be_path }${be_download}`; - const jwt = eval(`require("jsonwebtoken")`); - app.use( be_share_rewrite, createProxyMiddleware({ @@ -186,31 +185,16 @@ export default function serve() { pathRewrite: (path, req) => { if (req.method.toLowerCase() !== 'get') throw new Error('Method not allowed'); - const payload = jwt.verify( - req.query.token, - fe_be_path, + const tokens = $.read(TOKENS_KEY) || []; + const token = tokens.find( + (t) => + t.token === req.query.token && + t.type === req.params.type && + t.name === req.params.name && + (t.exp == null || t.exp > Date.now()), ); - if ( - payload.type !== req.params.type || - payload.name !== req.params.name - ) - throw new Error('Forbbiden'); - if (payload.type === 'sub') - return path.replace( - '/share/sub/', - '/download/', - ); - if (payload.type === 'col') - return path.replace( - '/share/col/', - '/download/collection/', - ); - if (payload.type === 'file') - return path.replace( - '/share/file/', - '/api/file/', - ); - throw new Error('Not Found'); + if (!token) throw new Error('Forbbiden'); + return path; }, }), ); @@ -218,11 +202,13 @@ export default function serve() { be_api_rewrite, createProxyMiddleware({ target: `http://127.0.0.1:${port}`, - changeOrigin: true, pathRewrite: (path) => { - return path.startsWith(be_api_rewrite) + const newPath = path.startsWith(be_api_rewrite) ? path.replace(be_api_rewrite, be_api) : path; + return newPath.includes('?') + ? `${newPath}&share=true` + : `${newPath}?share=true`; }, }), ); diff --git a/backend/src/restful/miscs.js b/backend/src/restful/miscs.js index 8e3e2cb87..c7cc868b4 100644 --- a/backend/src/restful/miscs.js +++ b/backend/src/restful/miscs.js @@ -9,6 +9,10 @@ import { GIST_BACKUP_FILE_NAME, GIST_BACKUP_KEY, SETTINGS_KEY, + TOKENS_KEY, + FILES_KEY, + COLLECTIONS_KEY, + SUBS_KEY, } from '@/constants'; import { InternalServerError, RequestInvalidError } from '@/restful/errors'; import Gist from '@/utils/gist'; @@ -20,36 +24,7 @@ export default function register($app) { $app.get('/api/utils/env', getEnv); // get runtime environment $app.get('/api/utils/backup', gistBackup); // gist backup actions $app.get('/api/utils/refresh', refresh); - $app.post('/api/jwt', (req, res) => { - if (!ENV().isNode) { - return failed( - res, - new RequestInvalidError( - 'INVALID_ENV', - `This endpoint is only available in Node.js environment`, - ), - ); - } - try { - const { payload, options } = req.body; - const jwt = eval(`require("jsonwebtoken")`); - const secret = eval('process.env.SUB_STORE_FRONTEND_BACKEND_PATH'); - const token = jwt.sign(payload, secret, options); - return success(res, { - token, - secret, - }); - } catch (e) { - return failed( - res, - new InternalServerError( - 'JWT_SIGN_FAILED', - `Failed to sign JWT token`, - `Reason: ${e.message ?? e}`, - ), - ); - } - }); + $app.post('/api/token', signToken); // Storage management $app.route('/api/storage') @@ -95,9 +70,151 @@ export default function register($app) { } function getEnv(req, res) { + if (req.query.share) { + env.feature.share = true; + } success(res, env); } +async function signToken(req, res) { + if (!ENV().isNode) { + return failed( + res, + new RequestInvalidError( + 'INVALID_ENV', + `This endpoint is only available in Node.js environment`, + ), + ); + } + try { + const { payload, options } = req.body; + const ms = eval(`require("ms")`); + let token = payload?.token; + if (token != null) { + if (typeof token !== 'string' || token.length < 1) { + return failed( + res, + new RequestInvalidError( + 'INVALID_CUSTOM_TOKEN', + `Invalid custom token: ${token}`, + ), + ); + } + const tokens = $.read(TOKENS_KEY) || []; + if (tokens.find((t) => t.token === token)) { + return failed( + res, + new RequestInvalidError( + 'DUPLICATE_TOKEN', + `Token ${token} already exists`, + ), + ); + } + } + const type = payload?.type; + const name = payload?.name; + if (!type || !name) + return failed( + res, + new RequestInvalidError( + 'INVALID_PAYLOAD', + `payload type and name are required`, + ), + ); + if (type === 'col') { + const collections = $.read(COLLECTIONS_KEY) || []; + const collection = collections.find((c) => c.name === name); + if (!collection) + return failed( + res, + new RequestInvalidError( + 'INVALID_COLLECTION', + `collection ${name} not found`, + ), + ); + } else if (type === 'file') { + const files = $.read(FILES_KEY) || []; + const file = files.find((f) => f.name === name); + if (!file) + return failed( + res, + new RequestInvalidError( + 'INVALID_FILE', + `file ${name} not found`, + ), + ); + } else if (type === 'sub') { + const subs = $.read(SUBS_KEY) || []; + const sub = subs.find((s) => s.name === name); + if (!sub) + return failed( + res, + new RequestInvalidError( + 'INVALID_SUB', + `sub ${name} not found`, + ), + ); + } else { + return failed( + res, + new RequestInvalidError( + 'INVALID_TYPE', + `type ${name} not supported`, + ), + ); + } + let expiresIn = options?.expiresIn; + if (options?.expiresIn != null) { + expiresIn = ms(options.expiresIn); + if (expiresIn == null || isNaN(expiresIn) || expiresIn <= 0) { + return failed( + res, + new RequestInvalidError( + 'INVALID_EXPIRES_IN', + `Invalid expiresIn option: ${options.expiresIn}`, + ), + ); + } + } + const secret = eval('process.env.SUB_STORE_FRONTEND_BACKEND_PATH'); + const nanoid = eval(`require("nanoid")`); + const tokens = $.read(TOKENS_KEY) || []; + // const now = Date.now(); + // for (const key in tokens) { + // const token = tokens[key]; + // if (token.exp != null || token.exp < now) { + // delete tokens[key]; + // } + // } + if (!token) { + do { + token = nanoid.customAlphabet(nanoid.urlAlphabet)(); + } while (tokens.find((t) => t.token === token)); + } + tokens.push({ + ...payload, + token, + createdAt: Date.now(), + expiresIn: expiresIn > 0 ? options?.expiresIn : undefined, + exp: expiresIn > 0 ? Date.now() + expiresIn : undefined, + }); + + $.write(tokens, TOKENS_KEY); + return success(res, { + token, + secret, + }); + } catch (e) { + return failed( + res, + new InternalServerError( + 'TOKEN_SIGN_FAILED', + `Failed to sign token`, + `Reason: ${e.message ?? e}`, + ), + ); + } +} async function refresh(_, res) { // 1. get GitHub avatar and artifact store await updateAvatar(); diff --git a/backend/src/utils/env.js b/backend/src/utils/env.js index 66dcdf576..d7249bd69 100644 --- a/backend/src/utils/env.js +++ b/backend/src/utils/env.js @@ -44,10 +44,6 @@ try { meta.plugin = $Plugin; } if (isNode) { - const secret = eval('process.env.SUB_STORE_FRONTEND_BACKEND_PATH'); - if (secret && eval('process.env.SUB_STORE_FRONTEND_PATH')) { - feature.share = true; - } meta.node = { version: eval('process.version'), argv: eval('process.argv'),