Skip to content

Commit 59c2abd

Browse files
committed
Teach the SDKs the proof surface
A server-side signature change without SDK support ships clients that lie to their users, so the proof header and endpoint land in SPECS.md, the shared commons and both vendored trees in one step.
1 parent ac8d8d4 commit 59c2abd

29 files changed

Lines changed: 153 additions & 135 deletions

clients/SPECS.md

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
- Token-based bearer authentication with an extensibility seam for future auth
2626
strategies (OAuth2, mTLS, rotating providers).
2727
- Public (unauthenticated) monitoring endpoints: `ping`, `pings`,
28-
`ping_provider` (see §9.5).
28+
`ping_provider` (see §9.6).
2929

3030
**Out of scope**
3131

@@ -445,7 +445,16 @@ brackets:
445445
client.dss.allocation_adulte_handicape_identite(prenoms: ['Jean', 'Paul'], …)
446446
```
447447

448-
### 9.5 Public (unauthenticated) endpoints — Ping
448+
### 9.5 Request-header parameters
449+
450+
Operations may declare `in: header` parameters (e.g. `X-Generate-Proof` on the
451+
EAJE identity endpoint). Generated methods MUST expose each one as an optional
452+
kwarg named after the header — lowercased, dashes to underscores, leading `x_`
453+
stripped (`X-Generate-Proof``generate_proof`) — and send the value verbatim
454+
as a request header when provided. `Cache-Control` is transport-level and MUST
455+
NOT be scaffolded.
456+
457+
### 9.6 Public (unauthenticated) endpoints — Ping
449458

450459
Both APIs expose monitoring endpoints marked `security: []` in the OpenAPI
451460
spec. These endpoints require **no token**, **no audit parameters**
@@ -748,7 +757,7 @@ A reviewer certifying a new client ticks each item.
748757
`User-Agent` set.
749758
- [ ] Immutable `Configuration` with `with()` / `copy()`; ENV vars honoured.
750759
- [ ] Public ping endpoints (`ping`, `pings`, `ping_provider`) exposed on
751-
the client; no auth header or audit params sent (§9.5).
760+
the client; no auth header or audit params sent (§9.6).
752761
- [ ] Unit tests cover every surface listed in §12.1; integration tests
753762
cover 200 / 422 / 429 / 502 on both APIs; staging conformance run
754763
from TESTING.md passes; README has a stub example.

clients/node/api-entreprise/package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

clients/node/api-entreprise/src/commons/auth/bearer-token.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: c39093e4bc410efcbe528a7b462142c8c4d7f0a6).
1+
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: 2ff43e12b36dac153c791f7bdb78eb7fe55c4e34).
22
// Regenerate via clients/node/bin/sync-commons.ts
33

44
import type { AuthStrategy } from './strategy.js';

clients/node/api-entreprise/src/commons/auth/strategy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: c39093e4bc410efcbe528a7b462142c8c4d7f0a6).
1+
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: 2ff43e12b36dac153c791f7bdb78eb7fe55c4e34).
22
// Regenerate via clients/node/bin/sync-commons.ts
33

44
export interface AuthStrategy {

clients/node/api-entreprise/src/commons/client-base.ts

Lines changed: 23 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: c39093e4bc410efcbe528a7b462142c8c4d7f0a6).
1+
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: 2ff43e12b36dac153c791f7bdb78eb7fe55c4e34).
22
// Regenerate via clients/node/bin/sync-commons.ts
33

44
import { Configuration, type Logger } from './configuration.js';
@@ -175,23 +175,7 @@ export abstract class ClientBase {
175175
const responseHeaders = headersToRecord(fetchResponse.headers);
176176
const rateLimit = RateLimit.fromHeaders(fetchResponse.headers);
177177

178-
let body: unknown;
179-
const text = await fetchResponse.text();
180-
if (text) {
181-
try {
182-
body = JSON.parse(text);
183-
} catch {
184-
if (fetchResponse.ok) {
185-
throw new TransportError(
186-
`invalid JSON body: ${text.slice(0, 200)}`,
187-
{ method, url },
188-
);
189-
}
190-
body = {};
191-
}
192-
} else {
193-
body = {};
194-
}
178+
const body: unknown = await this.parseBody(fetchResponse, method, url);
195179

196180
this.logRequest(method, url, fetchResponse.status, durationMs, rateLimit);
197181

@@ -256,23 +240,7 @@ export abstract class ClientBase {
256240
const durationMs = Date.now() - started;
257241
const responseHeaders = headersToRecord(fetchResponse.headers);
258242

259-
let body: unknown;
260-
const text = await fetchResponse.text();
261-
if (text) {
262-
try {
263-
body = JSON.parse(text);
264-
} catch {
265-
if (fetchResponse.ok) {
266-
throw new TransportError(
267-
`invalid JSON body: ${text.slice(0, 200)}`,
268-
{ method, url },
269-
);
270-
}
271-
body = {};
272-
}
273-
} else {
274-
body = {};
275-
}
243+
const body: unknown = await this.parseBody(fetchResponse, method, url);
276244

277245
this.logRequest(method, url, fetchResponse.status, durationMs, null);
278246

@@ -351,6 +319,26 @@ export abstract class ClientBase {
351319
return result;
352320
}
353321

322+
private async parseBody(
323+
fetchResponse: globalThis.Response,
324+
method: string,
325+
url: string,
326+
): Promise<unknown> {
327+
const text = await fetchResponse.text();
328+
if (!text) return {};
329+
try {
330+
return JSON.parse(text);
331+
} catch {
332+
if (fetchResponse.ok) {
333+
throw new TransportError(
334+
`invalid JSON body: ${text.slice(0, 200)}`,
335+
{ method, url },
336+
);
337+
}
338+
return {};
339+
}
340+
}
341+
354342
private throwMappedError(
355343
status: number,
356344
body: unknown,

clients/node/api-entreprise/src/commons/configuration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: c39093e4bc410efcbe528a7b462142c8c4d7f0a6).
1+
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: 2ff43e12b36dac153c791f7bdb78eb7fe55c4e34).
22
// Regenerate via clients/node/bin/sync-commons.ts
33

44
import type { AuthStrategy } from './auth/strategy.js';

clients/node/api-entreprise/src/commons/errors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: c39093e4bc410efcbe528a7b462142c8c4d7f0a6).
1+
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: 2ff43e12b36dac153c791f7bdb78eb7fe55c4e34).
22
// Regenerate via clients/node/bin/sync-commons.ts
33

44
export interface JsonApiError {

clients/node/api-entreprise/src/commons/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: c39093e4bc410efcbe528a7b462142c8c4d7f0a6).
1+
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: 2ff43e12b36dac153c791f7bdb78eb7fe55c4e34).
22
// Regenerate via clients/node/bin/sync-commons.ts
33

44
export { type AuthStrategy } from './auth/strategy.js';

clients/node/api-entreprise/src/commons/rate-limit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: c39093e4bc410efcbe528a7b462142c8c4d7f0a6).
1+
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: 2ff43e12b36dac153c791f7bdb78eb7fe55c4e34).
22
// Regenerate via clients/node/bin/sync-commons.ts
33

44
/** Parsed RateLimit-* response headers. */

clients/node/api-entreprise/src/commons/response.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: c39093e4bc410efcbe528a7b462142c8c4d7f0a6).
1+
// DO NOT EDIT — generated from clients/node/commons/src/ (source digest: 2ff43e12b36dac153c791f7bdb78eb7fe55c4e34).
22
// Regenerate via clients/node/bin/sync-commons.ts
33

44
import { RateLimit } from './rate-limit.js';

0 commit comments

Comments
 (0)