3.6 KiB
3.6 KiB
Contract: Proxy HTTP Responses
Feature: 001-oidc-proxy-script
File: src/proxyScripts/proxy.js
Endpoint: Any path handled by the adapter (all requests delegated to proxy.js by server.js)
Date: 2025-07-17
Overview
proxy.js responds to every inbound HTTP request with exactly one of two outcomes:
a success response (authentication succeeded) or an error response (authentication failed for
any reason). The contract defines the exact shape of both outcomes.
Success Response
Trigger: OIDC token successfully obtained (fresh fetch or valid cached token).
HTTP/1.1 200 OK
Content-Type: text/plain
Authorized
| Property | Value |
|---|---|
| Status code | 200 |
| Status text | OK |
Content-Type header |
text/plain |
| Body | Literal string Authorized (no trailing newline) |
Acceptance test (FR-007, SC-001, SC-002):
assert.strictEqual(res.statusCode, 200);
assert.strictEqual(res.body, 'Authorized');
Error Response
Trigger: Any of the following (FR-008, SC-004):
- Token service returns HTTP 4xx or 5xx
- Token service is unreachable (network error)
- Token request times out after 5 seconds (FR-014)
- Token service response is missing
id_tokenorexpires_in adapter_settingsis missing a required field
HTTP/1.1 401 Unauthorized
Content-Type: text/plain
Unauthorized: <descriptive message>
| Property | Value |
|---|---|
| Status code | 401 |
| Status text | Unauthorized |
Content-Type header |
text/plain |
| Body prefix | Unauthorized: (literal, followed by the error message) |
| Body | Never empty; always includes a human-readable description |
Example bodies by error cause:
| Cause | Example body |
|---|---|
| Invalid credentials (401 from token service) | Unauthorized: HTTP 401 |
| Token service unavailable | Unauthorized: connect ECONNREFUSED 127.0.0.1:443 |
| 5-second timeout | Unauthorized: token service timeout |
Response missing id_token |
Unauthorized: id_token missing from response |
Response missing expires_in |
Unauthorized: expires_in missing from response |
Missing tokenUrl in settings |
Unauthorized: missing required field: tokenUrl |
Acceptance test (FR-008):
assert.strictEqual(res.statusCode, 401);
assert.match(res.body, /^Unauthorized: .+/);
Invariants
These MUST hold for every request, regardless of outcome:
- One response per request:
res.writeHead()MUST be called exactly once;res.end()MUST be called exactly once. - Never 500:
proxy.jsMUST NOT emit a 500 or leave the connection open. All errors, including unexpected runtime errors, MUST result in a401(not a crash or hang). - No imports/exports (FR-009): The script MUST contain zero
importorexportstatements — verified by static analysis. - No forbidden globals (FR-010): No
config,global.config, orprocess.envreferences — verified by static analysis. - Response within 5 seconds (SC-001, FR-014): The HTTP timeout on the token POST is 5 000 ms. Combined with synchronous error handling, every request resolves within 5 seconds under normal network conditions.
Out of Scope
- The proxy script does NOT validate the inbound request (method, path, headers, body). Its sole responsibility is OIDC authentication.
- The response does NOT include the OIDC token in the body. The
200 OK / Authorizedbody is sufficient to confirm authentication succeeded (spec assumption, line 106). - No
Authorizationresponse header is set. The adapter's caller does not require it.