diff --git a/backend/package.json b/backend/package.json index 6f4a5f7..94a6117 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "sub-store", - "version": "2.18.7", + "version": "2.18.8", "description": "Advanced Subscription Manager for QX, Loon, Surge, Stash and Shadowrocket.", "main": "src/main.js", "scripts": { @@ -32,6 +32,7 @@ "cron": "^3.1.6", "dns-packet": "^5.6.1", "express": "^4.17.1", + "mime-types": "^2.1.35", "http-proxy-middleware": "^3.0.3", "ip-address": "^9.0.5", "js-base64": "^3.7.2", @@ -71,4 +72,4 @@ "prettier-plugin-sort-imports": "^1.6.1", "tinyify": "^3.0.0" } -} \ No newline at end of file +} diff --git a/backend/src/restful/index.js b/backend/src/restful/index.js index 762e9d5..47a0ec6 100644 --- a/backend/src/restful/index.js +++ b/backend/src/restful/index.js @@ -30,10 +30,12 @@ export default function serve() { } const $app = express({ substore: $, port, host }); if ($.env.isNode) { + const be_merge = eval('process.env.SUB_STORE_BACKEND_MERGE'); const be_prefix = eval('process.env.SUB_STORE_BACKEND_PREFIX'); const fe_be_path = eval('process.env.SUB_STORE_FRONTEND_BACKEND_PATH'); - if (be_prefix) { - if (!fe_be_path.startsWith('/')) { + const fe_path = eval('process.env.SUB_STORE_FRONTEND_PATH'); + if (be_prefix || be_merge) { + if(!fe_be_path.startsWith('/')){ throw new Error( 'SUB_STORE_FRONTEND_BACKEND_PATH should start with /', ); @@ -43,12 +45,50 @@ export default function serve() { ); $app.use((req, res, next) => { if (req.path.startsWith(fe_be_path)) { - const newPath = req.url.replace(fe_be_path, '') || '/'; - req.url = newPath; + req.url = req.url.replace(fe_be_path, '') || '/'; + if(be_merge && req.url.startsWith('/api/')){ + req.query['share'] = 'true'; + } next(); - } else { - res.status(403).send(); + return; } + const pathname = req._parsedUrl.pathname || '/'; + if(be_merge && req.path.startsWith('/share/') && req.query.token){ + if (req.method.toLowerCase() !== 'get'){ + res.status(405).send('Method not allowed'); + return; + } + const tokens = $.read(TOKENS_KEY) || []; + const token = tokens.find( + (t) => + t.token === req.query.token && + `/share/${t.type}/${t.name}` === pathname && + (t.exp == null || t.exp > Date.now()), + ); + if (token){ + next(); + return; + } + } + if (be_merge && fe_path && req.path.indexOf('/',1) == -1) { + if (req.path.indexOf('.') == -1){ + req.url = "/index.html" + } + const express_ = eval(`require("express")`); + const mime_ = eval(`require("mime-types")`); + const staticFileMiddleware = express_.static(fe_path, { + setHeaders: (res, path) => { + const type = mime_.contentType(path); + if (type) { + res.set('Content-Type', type); + } + } + }); + staticFileMiddleware(req, res, next); + return; + } + res.status(403).end('Forbbiden'); + return; }); } } @@ -198,7 +238,8 @@ export default function serve() { const fe_abs_path = path.resolve( fe_path || path.join(__dirname, 'frontend'), ); - if (fe_path) { + const be_merge = eval('process.env.SUB_STORE_BACKEND_MERGE'); + if (fe_path && !be_merge) { try { fs.accessSync(path.join(fe_abs_path, 'index.html')); } catch (e) {