@idpartners/client-attestation-sdk 1.0.0 → 1.0.1

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.d.ts CHANGED
@@ -21,6 +21,6 @@ export type { AttesterMetadata, AttesterProfile, AttesterTransport, MintResult }
21
21
  export type { TransportFailure } from "./errors.js";
22
22
  export { NOOP_LOGGER } from "./logging.js";
23
23
  export type { Logger, LogAttributes, LogLevel } from "./logging.js";
24
- export declare const VERSION = "1.0.0";
24
+ export declare const VERSION = "1.0.1";
25
25
  /** draft-ietf-oauth-attestation-based-client-auth revision this SDK implements. */
26
26
  export declare const DRAFT_REVISION = "10";
package/dist/index.js CHANGED
@@ -15,6 +15,6 @@ export { EvidenceNotFound, FileTokenSvidSource, GoogleMetadataSvidSource, autoDe
15
15
  export { ClientAttestation, ClientAttestationError, TransportError, DEFAULT_EXPIRY_SKEW_SECONDS, } from "./token-source.js";
16
16
  export { MintRequest, PingFederateProfile } from "./attester.js";
17
17
  export { NOOP_LOGGER } from "./logging.js";
18
- export const VERSION = "1.0.0";
18
+ export const VERSION = "1.0.1";
19
19
  /** draft-ietf-oauth-attestation-based-client-auth revision this SDK implements. */
20
20
  export const DRAFT_REVISION = "10";
@@ -134,6 +134,7 @@ export declare class ClientAttestation {
134
134
  * as global `fetch`. For a DPoP-bound token it adds a fresh proof and, when the resource answers with
135
135
  * a `use_dpop_nonce` challenge and a `DPoP-Nonce`, resends ONCE with a proof carrying that nonce —
136
136
  * unless the body is a one-shot stream, which cannot be resent (the challenge response is returned).
137
+ * Redirects are returned without following them, even if the input or init requests redirect following.
137
138
  */
138
139
  fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
139
140
  /**
@@ -140,6 +140,7 @@ export class ClientAttestation {
140
140
  * as global `fetch`. For a DPoP-bound token it adds a fresh proof and, when the resource answers with
141
141
  * a `use_dpop_nonce` challenge and a `DPoP-Nonce`, resends ONCE with a proof carrying that nonce —
142
142
  * unless the body is a one-shot stream, which cannot be resent (the challenge response is returned).
143
+ * Redirects are returned without following them, even if the input or init requests redirect following.
143
144
  */
144
145
  async fetch(input, init = {}) {
145
146
  const isRequest = typeof Request !== "undefined" && input instanceof Request;
@@ -154,7 +155,7 @@ export class ClientAttestation {
154
155
  dpopBound = DPOP_HEADER in auth;
155
156
  for (const [name, value] of Object.entries(auth))
156
157
  headers.set(name, value);
157
- return fetch(nextInput(), { ...init, headers });
158
+ return fetch(nextInput(), { ...init, headers, redirect: "manual" });
158
159
  };
159
160
  const first = await send();
160
161
  if (!dpopBound)
@@ -16,4 +16,4 @@ export type { ValidationError } from "./errors.js";
16
16
  export * as errors from "./errors.js";
17
17
  export { ProtectedResource, bearerToken } from "./resource.js";
18
18
  export type { ProtectedResourceMetadata, AuthDecision } from "./resource.js";
19
- export declare const VALIDATOR_VERSION = "1.0.0";
19
+ export declare const VALIDATOR_VERSION = "1.0.1";
@@ -9,4 +9,4 @@ export { AccessTokenValidator } from "./validator.js";
9
9
  export { DEFAULT_ALGORITHMS, DEFAULT_TOKEN_TYPES } from "./config.js";
10
10
  export * as errors from "./errors.js";
11
11
  export { ProtectedResource, bearerToken } from "./resource.js";
12
- export const VALIDATOR_VERSION = "1.0.0";
12
+ export const VALIDATOR_VERSION = "1.0.1";
@@ -1,4 +1,4 @@
1
- import type { ValidationResult } from "./result.js";
1
+ import { type ValidationResult } from "./result.js";
2
2
  import type { AccessTokenValidator } from "./validator.js";
3
3
  /** Extract the token from an `Authorization: Bearer <token>` header value, or null. */
4
4
  export declare function bearerToken(authorizationHeader?: string | null): string | null;
@@ -8,6 +8,7 @@
8
8
  * a request guard that binds the token audience to this resource (RFC 8707). Protocol-neutral — not MCP-only.
9
9
  */
10
10
  import * as errors from "./errors.js";
11
+ import { failure } from "./result.js";
11
12
  const WELL_KNOWN = "/.well-known/oauth-protected-resource";
12
13
  /** Extract the token from an `Authorization: Bearer <token>` header value, or null. */
13
14
  export function bearerToken(authorizationHeader) {
@@ -68,7 +69,13 @@ export class ProtectedResource {
68
69
  if (token == null) {
69
70
  return { authorized: false, status: 401, wwwAuthenticate: this.challenge(), errorDescription: "authentication required" };
70
71
  }
71
- const result = await this.#validator.validate(token, requiredScopes);
72
+ let result = await this.#validator.validate(token, requiredScopes);
73
+ if (result.valid && !result.audience.includes(this.resource)) {
74
+ result = failure(errors.INVALID_AUDIENCE, "token audience is not this resource");
75
+ }
76
+ if (result.valid && result.claims.cnf != null) {
77
+ result = failure(errors.INVALID_TOKEN, "sender-constrained token requires proof verification");
78
+ }
72
79
  if (result.valid) {
73
80
  return { authorized: true, result, status: 200 };
74
81
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@idpartners/client-attestation-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Client-side builder SDK for OAuth Attestation-Based Client Authentication",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",