mirror of
https://github.com/whyour/qinglong.git
synced 2025-12-23 15:50:07 +08:00
Add QlBaseUrl support to backend routes
Co-authored-by: whyour <22700758+whyour@users.noreply.github.com>
This commit is contained in:
parent
2b875d634f
commit
a38b876a74
|
|
@ -64,6 +64,19 @@ if (!process.env.QL_DIR) {
|
||||||
|
|
||||||
const lastVersionFile = `https://qn.whyour.cn/version.yaml`;
|
const lastVersionFile = `https://qn.whyour.cn/version.yaml`;
|
||||||
|
|
||||||
|
// Get and normalize QlBaseUrl
|
||||||
|
let baseUrl = process.env.QlBaseUrl || '';
|
||||||
|
if (baseUrl) {
|
||||||
|
// Ensure it starts with /
|
||||||
|
if (!baseUrl.startsWith('/')) {
|
||||||
|
baseUrl = `/${baseUrl}`;
|
||||||
|
}
|
||||||
|
// Remove trailing slash for consistency in route definitions
|
||||||
|
if (baseUrl.endsWith('/')) {
|
||||||
|
baseUrl = baseUrl.slice(0, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const rootPath = process.env.QL_DIR as string;
|
const rootPath = process.env.QL_DIR as string;
|
||||||
const envFound = dotenv.config({ path: path.join(rootPath, '.env') });
|
const envFound = dotenv.config({ path: path.join(rootPath, '.env') });
|
||||||
|
|
||||||
|
|
@ -116,6 +129,7 @@ if (envFound.error) {
|
||||||
export default {
|
export default {
|
||||||
...config,
|
...config,
|
||||||
jwt: config.jwt,
|
jwt: config.jwt,
|
||||||
|
baseUrl,
|
||||||
rootPath,
|
rootPath,
|
||||||
tmpPath,
|
tmpPath,
|
||||||
dataPath,
|
dataPath,
|
||||||
|
|
|
||||||
|
|
@ -15,21 +15,30 @@ import path from 'path';
|
||||||
export default ({ app }: { app: Application }) => {
|
export default ({ app }: { app: Application }) => {
|
||||||
app.set('trust proxy', 'loopback');
|
app.set('trust proxy', 'loopback');
|
||||||
app.use(cors());
|
app.use(cors());
|
||||||
app.get(`${config.api.prefix}/env.js`, serveEnv);
|
app.get(`${config.baseUrl}${config.api.prefix}/env.js`, serveEnv);
|
||||||
app.use(`${config.api.prefix}/static`, express.static(config.uploadPath));
|
app.use(`${config.baseUrl}${config.api.prefix}/static`, express.static(config.uploadPath));
|
||||||
|
|
||||||
app.use(bodyParser.json({ limit: '50mb' }));
|
app.use(bodyParser.json({ limit: '50mb' }));
|
||||||
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
|
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
|
||||||
|
|
||||||
const frontendPath = path.join(config.rootPath, 'static/dist');
|
const frontendPath = path.join(config.rootPath, 'static/dist');
|
||||||
app.use(express.static(frontendPath));
|
if (config.baseUrl) {
|
||||||
|
app.use(config.baseUrl, express.static(frontendPath));
|
||||||
|
} else {
|
||||||
|
app.use(express.static(frontendPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create base-URL-aware whitelist for JWT
|
||||||
|
const jwtWhitelist = config.apiWhiteList.map(path => `${config.baseUrl}${path}`);
|
||||||
|
// Allow all paths that don't contain /api/ or /open/ to skip JWT
|
||||||
|
const jwtExcludeRegex = /^\/(?!.*\/(api|open)\/)/;
|
||||||
|
|
||||||
app.use(
|
app.use(
|
||||||
expressjwt({
|
expressjwt({
|
||||||
secret: config.jwt.secret,
|
secret: config.jwt.secret,
|
||||||
algorithms: ['HS384'],
|
algorithms: ['HS384'],
|
||||||
}).unless({
|
}).unless({
|
||||||
path: [...config.apiWhiteList, /^\/(?!api\/).*/],
|
path: [...jwtWhitelist, jwtExcludeRegex],
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -44,12 +53,14 @@ export default ({ app }: { app: Application }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(async (req: Request, res, next) => {
|
app.use(async (req: Request, res, next) => {
|
||||||
if (!['/open/', '/api/'].some((x) => req.path.startsWith(x))) {
|
const apiPath = `${config.baseUrl}/api/`;
|
||||||
|
const openPath = `${config.baseUrl}/open/`;
|
||||||
|
if (![openPath, apiPath].some((x) => req.path.startsWith(x))) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
const headerToken = getToken(req);
|
const headerToken = getToken(req);
|
||||||
if (req.path.startsWith('/open/')) {
|
if (req.path.startsWith(openPath)) {
|
||||||
const apps = await shareStore.getApps();
|
const apps = await shareStore.getApps();
|
||||||
const doc = apps?.filter((x) =>
|
const doc = apps?.filter((x) =>
|
||||||
x.tokens?.find((y) => y.value === headerToken),
|
x.tokens?.find((y) => y.value === headerToken),
|
||||||
|
|
@ -91,7 +102,8 @@ export default ({ app }: { app: Application }) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(async (req, res, next) => {
|
app.use(async (req, res, next) => {
|
||||||
if (!['/api/user/init', '/api/user/notification/init'].includes(req.path)) {
|
const initPaths = [`${config.baseUrl}/api/user/init`, `${config.baseUrl}/api/user/notification/init`];
|
||||||
|
if (!initPaths.includes(req.path)) {
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
const authInfo =
|
const authInfo =
|
||||||
|
|
@ -113,10 +125,10 @@ export default ({ app }: { app: Application }) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
app.use(rewrite('/open/*', '/api/$1'));
|
app.use(rewrite(`${config.baseUrl}/open/*`, `${config.baseUrl}/api/$1`));
|
||||||
app.use(config.api.prefix, routes());
|
app.use(`${config.baseUrl}${config.api.prefix}`, routes());
|
||||||
|
|
||||||
app.get('*', (_, res, next) => {
|
app.get('*', (req, res, next) => {
|
||||||
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) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user