mirror of
https://github.com/whyour/qinglong.git
synced 2026-10-16 22:35:32 +08:00
Fix catch-all route serving HTML for API requests (#2885)
* Initial plan * Fix env.js loading error by preventing catch-all from matching API routes Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> Co-authored-by: whyour <imwhyour@gmail.com>
This commit is contained in:
co-authored by
whyour
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
whyour
parent
3c61e933a1
commit
fdeffebba8
@@ -179,7 +179,14 @@ export default ({ app }: { app: Application }) => {
|
|||||||
app.use(rewrite('/open/*', '/api/$1'));
|
app.use(rewrite('/open/*', '/api/$1'));
|
||||||
app.use(config.api.prefix, routes());
|
app.use(config.api.prefix, routes());
|
||||||
|
|
||||||
app.get('*', (_, res, next) => {
|
app.get('*', (req, res, next) => {
|
||||||
|
// Don't serve index.html for API routes
|
||||||
|
if (
|
||||||
|
req.path === config.api.prefix ||
|
||||||
|
req.path.startsWith(`${config.api.prefix}/`)
|
||||||
|
) {
|
||||||
|
return res.status(404).json({ code: 404, message: 'Not Found' });
|
||||||
|
}
|
||||||
const indexPath = path.join(frontendPath, 'index.html');
|
const indexPath = path.join(frontendPath, 'index.html');
|
||||||
res.sendFile(indexPath, (err) => {
|
res.sendFile(indexPath, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
const test = require('node:test'),
|
||||||
|
assert = require('node:assert/strict'),
|
||||||
|
fs = require('node:fs'),
|
||||||
|
os = require('node:os'),
|
||||||
|
path = require('node:path'),
|
||||||
|
express = require('express');
|
||||||
|
const load = require('../helpers/load-security-module.cjs');
|
||||||
|
test('unknown API requests return JSON 404 while env.js and SPA deep links work', async (t) => {
|
||||||
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ql-fallback-'));
|
||||||
|
t.after(() => fs.rmSync(dir, { recursive: true, force: true }));
|
||||||
|
fs.mkdirSync(path.join(dir, 'static/dist'), { recursive: true });
|
||||||
|
fs.writeFileSync(path.join(dir, 'static/dist/index.html'), 'SPA');
|
||||||
|
const app = express();
|
||||||
|
load('back/loaders/express.ts', {
|
||||||
|
'../api': () => express.Router(),
|
||||||
|
'../config': {
|
||||||
|
rootPath: dir,
|
||||||
|
uploadPath: dir,
|
||||||
|
api: { prefix: '/api' },
|
||||||
|
apiWhiteList: ['/api/env.js'],
|
||||||
|
jwt: { secret: 'test' },
|
||||||
|
},
|
||||||
|
'express-jwt': {
|
||||||
|
expressjwt: () => ({ unless: () => (_q, _r, next) => next() }),
|
||||||
|
UnauthorizedError: class extends Error {},
|
||||||
|
},
|
||||||
|
'../config/util': {
|
||||||
|
getPlatform: () => 'desktop',
|
||||||
|
getToken: () => 'stored',
|
||||||
|
},
|
||||||
|
'../config/serverEnv': {
|
||||||
|
serveEnv: (_q, r) => r.type('js').send('window.QL_CONFIG={};'),
|
||||||
|
},
|
||||||
|
'../shared/store': {
|
||||||
|
shareStore: { getAuthInfo: async () => ({}), getApps: async () => [] },
|
||||||
|
},
|
||||||
|
'../shared/auth': {
|
||||||
|
isValidToken: () => true,
|
||||||
|
isDefaultAuthInfo: () => false,
|
||||||
|
},
|
||||||
|
'../shared/i18n': { t: (s) => s },
|
||||||
|
'../middlewares/uniqueConstraintError': (_q, _r, next) => next(),
|
||||||
|
'../middlewares/protectedPathCase': (_q, _r, next) => next(),
|
||||||
|
'../data/system': {},
|
||||||
|
'../data/open': {},
|
||||||
|
}).default({ app });
|
||||||
|
const server = await new Promise((r) => {
|
||||||
|
const s = app.listen(0, '127.0.0.1', () => r(s));
|
||||||
|
});
|
||||||
|
t.after(() => new Promise((r) => server.close(r)));
|
||||||
|
const url = `http://127.0.0.1:${server.address().port}`;
|
||||||
|
for (const p of ['/api', '/api/missing', '/open/missing']) {
|
||||||
|
const res = await fetch(url + p);
|
||||||
|
assert.equal(res.status, 404, p);
|
||||||
|
assert.match(res.headers.get('content-type'), /json/);
|
||||||
|
assert.equal((await res.json()).code, 404);
|
||||||
|
}
|
||||||
|
const env = await fetch(url + '/api/env.js');
|
||||||
|
assert.match(await env.text(), /QL_CONFIG/);
|
||||||
|
assert.equal(await (await fetch(url + '/script')).text(), 'SPA');
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user