Files
2026-10-23 10:35:28 +08:00

66 lines
1.8 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
/**
* 公网网关:只把 WhatsApp webhook 和帮助中心暴露给 Cloudflare Tunnel,
* 其余路径(尤其 /api/v1/* 管理接口、admin UI)一律 404,避免整站公网裸奔。
*
* cloudflared (quick tunnel) -> public-gateway:9001 -> libredesk:9000
*/
const http = require('http');
const PORT = Number(process.env.PORT || 9001);
const UPSTREAM = new URL(process.env.UPSTREAM || 'http://libredesk:9000');
// 公网允许的路径前缀
const ALLOW = [
'/webhooks/whatsapp/', // Meta 回调
'/hc/', // 帮助中心(AI 引用链接)
'/widget.js',
'/widget', // widget iframe 页面
'/static/public/', // widget 静态资源
];
function allowed(pathname) {
return ALLOW.some((p) => pathname === p || pathname.startsWith(p));
}
const server = http.createServer((req, res) => {
const pathname = (req.url || '/').split('?')[0];
if (!allowed(pathname)) {
res.writeHead(404, { 'content-type': 'text/plain; charset=utf-8' });
res.end('not found');
return;
}
const headers = { ...req.headers };
delete headers.host;
headers.host = UPSTREAM.host;
const proxy = http.request(
{
protocol: UPSTREAM.protocol,
hostname: UPSTREAM.hostname,
port: UPSTREAM.port || 80,
method: req.method,
path: req.url,
headers,
},
(upRes) => {
res.writeHead(upRes.statusCode || 502, upRes.headers);
upRes.pipe(res);
}
);
proxy.on('error', (err) => {
console.error('[public-gateway] upstream error', pathname, err.message);
if (!res.headersSent) res.writeHead(502, { 'content-type': 'text/plain; charset=utf-8' });
res.end('bad gateway');
});
req.pipe(proxy);
});
server.listen(PORT, '0.0.0.0', () => {
console.log(`[public-gateway] listening :${PORT} -> ${UPSTREAM.origin} (allow: ${ALLOW.join(', ')})`);
});