@kb-labs/gateway-app 2.89.0 → 2.94.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -121,7 +121,8 @@ function registerAuthRoutes(app, authService) {
121
121
  if (!parsed.success) {
122
122
  return reply.code(400).send({ error: "Bad Request", issues: parsed.error.issues });
123
123
  }
124
- const result = await authService.register(parsed.data);
124
+ const { name, capabilities, publicKey } = parsed.data;
125
+ const result = await authService.register({ name, capabilities, publicKey });
125
126
  return reply.code(201).send(result);
126
127
  });
127
128
  app.post("/auth/token", { schema: { tags: ["Auth"], summary: "Issue JWT token pair" } }, async (request, reply) => {
@@ -2116,6 +2117,9 @@ function mergeTopOperations(httpOperations, domainOperations, limit = 5) {
2116
2117
  }
2117
2118
  return [...sliced.slice(0, Math.max(0, limit - 1)), firstDomainOperation];
2118
2119
  }
2120
+ function redactQueryToken(url) {
2121
+ return url.replace(/([?&]access_token=)[^&]*/gi, "$1[REDACTED]");
2122
+ }
2119
2123
  async function createServer(config, cache, logger, jwtConfig, registry) {
2120
2124
  const gatewayLogger = createCorrelatedLogger(logger, {
2121
2125
  serviceId: "gateway",
@@ -2135,7 +2139,7 @@ async function createServer(config, cache, logger, jwtConfig, registry) {
2135
2139
  servers: [{ url: "http://localhost:4000", description: "Local dev" }],
2136
2140
  ui: !isProduction
2137
2141
  });
2138
- await app.register(fastifyCors, { origin: true });
2142
+ await app.register(fastifyCors, { origin: false });
2139
2143
  const observability = new GatewayObservabilityCollector(config);
2140
2144
  observability.register(app);
2141
2145
  app.addHook("onRequest", async (request, reply) => {
@@ -2144,6 +2148,7 @@ async function createServer(config, cache, logger, jwtConfig, registry) {
2144
2148
  request.id = requestId;
2145
2149
  reply.header("X-Request-Id", requestId);
2146
2150
  reply.header("X-Trace-Id", traceId);
2151
+ const safeUrl = redactQueryToken(request.url);
2147
2152
  request.kbLogger = createCorrelatedLogger(logger, {
2148
2153
  serviceId: "gateway",
2149
2154
  logsSource: "gateway",
@@ -2152,17 +2157,18 @@ async function createServer(config, cache, logger, jwtConfig, registry) {
2152
2157
  requestId,
2153
2158
  traceId,
2154
2159
  method: request.method,
2155
- url: request.url,
2160
+ url: safeUrl,
2156
2161
  operation: "http.request"
2157
2162
  });
2158
- request.kbLogger.info(`\u2192 ${request.method.toUpperCase()} ${request.url}`);
2163
+ request.kbLogger.info(`\u2192 ${request.method.toUpperCase()} ${safeUrl}`);
2159
2164
  });
2160
2165
  app.addHook("onResponse", async (request, reply) => {
2161
2166
  const requestLogger = request.kbLogger;
2162
2167
  if (!requestLogger) {
2163
2168
  return;
2164
2169
  }
2165
- requestLogger.info(`\u2713 ${request.method.toUpperCase()} ${request.url} ${reply.statusCode}`, {
2170
+ const safeUrl = redactQueryToken(request.url);
2171
+ requestLogger.info(`\u2713 ${request.method.toUpperCase()} ${safeUrl} ${reply.statusCode}`, {
2166
2172
  statusCode: reply.statusCode
2167
2173
  });
2168
2174
  });
@@ -2200,7 +2206,8 @@ async function createServer(config, cache, logger, jwtConfig, registry) {
2200
2206
  await observability.observeOperation(`gateway.adapter.${name}`, async () => {
2201
2207
  const probeStart = Date.now();
2202
2208
  try {
2203
- const adapter = platform[name];
2209
+ const pf = platform;
2210
+ const adapter = pf[name] ?? pf.getAdapter?.(name);
2204
2211
  adapters[name] = { available: !!adapter, latencyMs: Date.now() - probeStart };
2205
2212
  } catch {
2206
2213
  adapters[name] = { available: false, latencyMs: Date.now() - probeStart };
@@ -2486,11 +2493,18 @@ async function bootstrap(repoRoot = process.cwd()) {
2486
2493
  await platform.cache.set(`host:token:${token}`, entry);
2487
2494
  logger.info("Static token seeded", { hostId: entry.hostId, namespaceId: entry.namespaceId });
2488
2495
  }
2496
+ const DEV_JWT_SECRET = "dev-insecure-secret-change-me";
2489
2497
  const jwtSecret = process.env.GATEWAY_JWT_SECRET;
2498
+ const isProduction = process.env.NODE_ENV === "production";
2499
+ if (!jwtSecret && isProduction) {
2500
+ throw new Error(
2501
+ `GATEWAY_JWT_SECRET must be set in production. Generate one with: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"`
2502
+ );
2503
+ }
2490
2504
  if (!jwtSecret) {
2491
- logger.warn("GATEWAY_JWT_SECRET not set \u2014 using insecure default (dev only!)");
2505
+ logger.warn("GATEWAY_JWT_SECRET not set \u2014 using insecure default (dev only, never use in production!)");
2492
2506
  }
2493
- const jwtConfig = { secret: jwtSecret ?? "dev-insecure-secret-change-me" };
2507
+ const jwtConfig = { secret: jwtSecret ?? DEV_JWT_SECRET };
2494
2508
  const server = await createServer(config, platform.cache, platform.logger, jwtConfig, registry);
2495
2509
  const address = await server.listen({ port: config.port, host: "0.0.0.0" });
2496
2510
  logger.info("Gateway listening", { address });