Farhan Beg commited on
Commit
b0371e0
·
1 Parent(s): bf86338

feat: route /api/sessions to gateway for Android app compat

Browse files

The Hermes Android app (rusty4444/hermes-android) calls the gateway's
session API at /api/sessions and /api/sessions/{id}/messages directly
(not through /v1/). Without this route, those requests hit the WebUI
catch-all, which uses a different auth scheme (cookie/session, not
Bearer) → 401 'invalid api key', even when the correct GATEWAY_TOKEN
is provided.

Fix: route /api/sessions and /api/sessions/* to the gateway (port 8642)
with the same Bearer auth as /v1/*. The WebUI's own /api/* calls use
cookie auth and don't hit /api/sessions, so there's no conflict.

This also benefits any other OpenAI-compatible client that calls the
gateway's /api/sessions endpoint directly instead of through /v1/.

Files changed (1) hide show
  1. health-server.js +29 -0
health-server.js CHANGED
@@ -1099,6 +1099,35 @@ const server = http.createServer(async (req, res) => {
1099
  return;
1100
  }
1101
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1102
  // 6. /hm — HuggingMes status page.
1103
  if (path === HM_PREFIX || path === `${HM_PREFIX}/`) {
1104
  if (!requireAuth(req, res)) return;
 
1099
  return;
1100
  }
1101
 
1102
+ // 5b. /api/sessions and /api/sessions/* — Hermes gateway session API.
1103
+ // The Android app (rusty4444/hermes-android) and other OpenAI-compatible
1104
+ // clients call these directly on the gateway (port 8642), not through
1105
+ // /v1/. Without this route they hit the WebUI catch-all, which uses a
1106
+ // different auth scheme → 401 "invalid api key".
1107
+ // Gate on Bearer token (same as /v1/*). The WebUI's own /api/* calls use
1108
+ // cookie auth and don't hit /api/sessions, so there's no conflict.
1109
+ if (path === "/api/sessions" || path.startsWith("/api/sessions/")) {
1110
+ if (!isAuthorized(req)) {
1111
+ res.writeHead(401, {
1112
+ "content-type": "application/json",
1113
+ "cache-control": "no-store",
1114
+ });
1115
+ res.end(
1116
+ JSON.stringify({
1117
+ error: "unauthorized",
1118
+ message: "Use Authorization: Bearer <GATEWAY_TOKEN>.",
1119
+ }),
1120
+ );
1121
+ return;
1122
+ }
1123
+ const upstreamHeaders =
1124
+ getBearerToken(req) || !API_SERVER_KEY
1125
+ ? {}
1126
+ : { authorization: `Bearer ${API_SERVER_KEY}` };
1127
+ proxyRequest(req, res, GATEWAY_PORT, (p) => p, upstreamHeaders);
1128
+ return;
1129
+ }
1130
+
1131
  // 6. /hm — HuggingMes status page.
1132
  if (path === HM_PREFIX || path === `${HM_PREFIX}/`) {
1133
  if (!requireAuth(req, res)) return;