@gen3/workspaces 0.12.73 → 0.12.74

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.
@@ -342,7 +342,15 @@ async function proxyServerExtension(req, res, targetUrl, getToken) {
342
342
  // Only point serverExtensionProxyBaseUrl at a network path a user's own request cannot
343
343
  // otherwise forge, or add real signature verification (e.g. against Fence's JWKS)
344
344
  // here before trusting these claims.
345
+ // --- auth header injection with diagnostic logging ---
346
+ const tokenSource = getToken ? 'getToken(injected)' : 'extractTokenFallback';
345
347
  const jwt = getToken ? getToken(req) : extractTokenFallback(req);
348
+ // Log incoming auth signals so we can diagnose missing REMOTE_USER / 502s.
349
+ const hasBearerHeader = typeof req.headers['authorization'] === 'string' && req.headers['authorization'].startsWith('Bearer ');
350
+ const cookieHeader = req.headers['cookie'] ?? '';
351
+ const hasAccessTokenCookie = /(?:^|;\s*)access_token=/.test(cookieHeader);
352
+ const cookieNames = cookieHeader.split(';').map((p)=>p.trim().split('=')[0]).filter(Boolean);
353
+ console.warn(`[workspace-assets] proxy auth-diag: tokenSource=${tokenSource} jwtFound=${!!jwt}` + ` hasBearerHeader=${hasBearerHeader} hasAccessTokenCookie=${hasAccessTokenCookie}` + ` cookieNames=[${cookieNames.join(',')}]`);
346
354
  if (jwt) {
347
355
  const claims = decodeJwtClaims(jwt);
348
356
  const rawUsername = claims?.sub ?? claims?.preferred_username ?? claims?.username;
@@ -352,8 +360,15 @@ async function proxyServerExtension(req, res, targetUrl, getToken) {
352
360
  forwardHeaders['Authorization'] = `Bearer ${safeJwt}`;
353
361
  forwardHeaders['REMOTE_USER'] = safeUsername;
354
362
  forwardHeaders['X-Gen3-User-ID'] = safeUsername;
363
+ console.warn(`[workspace-assets] proxy auth-diag: injected REMOTE_USER/X-Gen3-User-ID for sub="${safeUsername}"` + ` claimsKeys=[${Object.keys(claims ?? {}).join(',')}]`);
364
+ } else {
365
+ console.warn(`[workspace-assets] proxy auth-diag: JWT decoded but no sub/preferred_username/username claim found` + ` claimsKeys=[${Object.keys(claims ?? {}).join(',')}]` + ` (REMOTE_USER NOT injected — workspace-proxy will likely reject)`);
355
366
  }
367
+ } else {
368
+ console.warn(`[workspace-assets] proxy auth-diag: no JWT found via ${tokenSource}` + ` — REMOTE_USER/X-Gen3-User-ID NOT injected — workspace-proxy will likely 502`);
356
369
  }
370
+ // Log the set of header keys being forwarded (no values — headers can contain tokens).
371
+ console.warn(`[workspace-assets] proxy forwarding headers: [${Object.keys(forwardHeaders).join(',')}]`);
357
372
  const method = (req.method || 'GET').toUpperCase();
358
373
  let body;
359
374
  if (![
@@ -382,7 +397,10 @@ async function proxyServerExtension(req, res, targetUrl, getToken) {
382
397
  hostname: parsed.hostname,
383
398
  port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80),
384
399
  path: parsed.pathname + parsed.search,
385
- headers: forwardHeaders
400
+ headers: forwardHeaders,
401
+ // 30-second socket timeout — without this, a stalled upstream holds the
402
+ // connection open indefinitely and the client sees no response.
403
+ timeout: 30_000
386
404
  };
387
405
  const proxyReq = transport.request(reqOptions, (proxyRes)=>{
388
406
  const statusCode = proxyRes.statusCode ?? 502;
@@ -398,6 +416,11 @@ async function proxyServerExtension(req, res, targetUrl, getToken) {
398
416
  }
399
417
  const log = statusCode >= 400 ? console.error : console.warn;
400
418
  log(`[workspace-assets] ${method} ${targetUrl} -> ${statusCode} (${Date.now() - startedAt}ms)`);
419
+ if (statusCode >= 400) {
420
+ // Log upstream response headers for non-2xx to surface auth/routing rejections.
421
+ const upstreamHeaders = Object.entries(proxyRes.headers).filter(([k])=>!k.toLowerCase().includes('cookie')).map(([k, v])=>`${k}:${Array.isArray(v) ? v.join(',') : v}`).join(' | ');
422
+ console.error(`[workspace-assets] upstream response headers: ${upstreamHeaders}`);
423
+ }
401
424
  proxyRes.pipe(res, {
402
425
  end: true
403
426
  });