mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-09 02:12:59 +00:00
fix: proxy forwards browser cookie to remote causing 401; fix nodeContextMiddleware loop
Two backend fixes: 1. proxyReq was forwarding the browser's sencho_token cookie to the remote Sencho. The remote's authMiddleware uses cookieToken || bearerToken, so the invalid local-signed cookie was verified before the valid Bearer token, returning 401 on every proxied API call. Strip the cookie header in proxyReq so remote auth uses only the Bearer token. 2. nodeContextMiddleware blocked /api/nodes when x-node-id referenced a deleted node, trapping the frontend in an unrecoverable 404 loop (it could not fetch the nodes list to discover the node was gone). Exempt /api/nodes alongside /api/auth/ so the app can always self-heal.
This commit is contained in:
+15
-3
@@ -82,8 +82,15 @@ const nodeContextMiddleware = (req: Request, res: Response, next: NextFunction)
|
||||
req.nodeId = NodeRegistry.getInstance().getDefaultNodeId();
|
||||
}
|
||||
|
||||
// Intercept requests to deleted nodes to prevent downstream errors
|
||||
if (req.path.startsWith('/api/') && !req.path.startsWith('/api/auth/')) {
|
||||
// Intercept requests to deleted nodes to prevent downstream errors.
|
||||
// /api/nodes is intentionally exempt: it must always be reachable so the
|
||||
// frontend can re-sync after a node is deleted (otherwise a stale x-node-id
|
||||
// in localStorage causes an unrecoverable 404 loop).
|
||||
if (
|
||||
req.path.startsWith('/api/') &&
|
||||
!req.path.startsWith('/api/auth/') &&
|
||||
!req.path.startsWith('/api/nodes')
|
||||
) {
|
||||
const node = DatabaseService.getInstance().getNode(req.nodeId);
|
||||
if (!node) {
|
||||
res.status(404).json({ error: `Node with id ${req.nodeId} not found or was deleted.` });
|
||||
@@ -338,8 +345,13 @@ const remoteNodeProxy = createProxyMiddleware<Request, Response>({
|
||||
on: {
|
||||
proxyReq: (proxyReq, req) => {
|
||||
const node = NodeRegistry.getInstance().getNode(req.nodeId);
|
||||
// Remote Sencho sees itself as local - strip node context and inject bearer auth
|
||||
// Strip headers that must not reach the remote instance:
|
||||
// - x-node-id: remote Sencho treats all requests as local
|
||||
// - cookie: the browser's sencho_token is signed with THIS instance's JWT secret;
|
||||
// the remote would try to verify it with its own secret and return 401.
|
||||
// Authentication is handled exclusively via the Bearer token below.
|
||||
proxyReq.removeHeader('x-node-id');
|
||||
proxyReq.removeHeader('cookie');
|
||||
if (node?.api_token) {
|
||||
proxyReq.setHeader('Authorization', `Bearer ${node.api_token}`);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user