@keycardai/oauth 0.4.1 → 0.6.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.
@@ -0,0 +1,172 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerClient = registerClient;
4
+ const discovery_js_1 = require("./discovery.js");
5
+ const errors_js_1 = require("./errors.js");
6
+ /**
7
+ * Register a new OAuth 2.0 client with an authorization server (RFC 7591).
8
+ *
9
+ * Discovers `registration_endpoint` from the AS's
10
+ * `.well-known/oauth-authorization-server` metadata, POSTs the registration
11
+ * request as JSON, and returns the issued client credentials.
12
+ *
13
+ * Throws:
14
+ * - `Error` when the AS does not advertise `registration_endpoint`.
15
+ * - `OAuthError` when the AS returns an RFC 6749 §5.2 error response.
16
+ * - `Error` on non-OAuth HTTP failures or malformed responses.
17
+ */
18
+ async function registerClient(issuerUrl, request, options) {
19
+ const signal = options?.signal ??
20
+ (options?.timeoutMs != null ? AbortSignal.timeout(options.timeoutMs) : undefined);
21
+ const metadata = await (0, discovery_js_1.fetchAuthorizationServerMetadata)(issuerUrl, { signal });
22
+ if (!metadata.registration_endpoint) {
23
+ throw new Error(`Authorization server "${issuerUrl}" does not advertise a registration_endpoint`);
24
+ }
25
+ const response = await fetch(metadata.registration_endpoint, {
26
+ method: "POST",
27
+ headers: {
28
+ "Content-Type": "application/json",
29
+ Accept: "application/json",
30
+ },
31
+ body: JSON.stringify(serializeRequest(request)),
32
+ signal,
33
+ });
34
+ if (!response.ok) {
35
+ let errorBody = null;
36
+ try {
37
+ const json = await response.json();
38
+ if (json && typeof json === "object" && !Array.isArray(json)) {
39
+ errorBody = json;
40
+ }
41
+ }
42
+ catch {
43
+ // non-JSON error body — fall through to generic error
44
+ }
45
+ if (errorBody && typeof errorBody.error === "string") {
46
+ const description = typeof errorBody.error_description === "string"
47
+ ? errorBody.error_description
48
+ : errorBody.error;
49
+ const errorUri = typeof errorBody.error_uri === "string" ? errorBody.error_uri : undefined;
50
+ throw new errors_js_1.OAuthError(errorBody.error, description, errorUri);
51
+ }
52
+ throw new Error(`Client registration failed (HTTP ${response.status})`);
53
+ }
54
+ let json;
55
+ try {
56
+ json = await response.json();
57
+ }
58
+ catch {
59
+ throw new Error("Client registration response is not valid JSON");
60
+ }
61
+ if (!json || typeof json !== "object" || Array.isArray(json)) {
62
+ throw new Error("Client registration response is not a valid JSON object");
63
+ }
64
+ const body = json;
65
+ if (typeof body.client_id !== "string") {
66
+ throw new Error("Client registration response missing client_id");
67
+ }
68
+ return deserializeResponse(body);
69
+ }
70
+ function serializeRequest(request) {
71
+ // additionalMetadata goes in first so named fields always take precedence
72
+ // over vendor extensions — callers cannot accidentally override client_name etc.
73
+ const body = {};
74
+ if (request.additionalMetadata) {
75
+ for (const [key, value] of Object.entries(request.additionalMetadata)) {
76
+ body[key] = value;
77
+ }
78
+ }
79
+ if (request.clientName !== undefined)
80
+ body.client_name = request.clientName;
81
+ if (request.clientUri !== undefined)
82
+ body.client_uri = request.clientUri;
83
+ if (request.logoUri !== undefined)
84
+ body.logo_uri = request.logoUri;
85
+ if (request.tosUri !== undefined)
86
+ body.tos_uri = request.tosUri;
87
+ if (request.policyUri !== undefined)
88
+ body.policy_uri = request.policyUri;
89
+ if (request.softwareId !== undefined)
90
+ body.software_id = request.softwareId;
91
+ if (request.softwareVersion !== undefined)
92
+ body.software_version = request.softwareVersion;
93
+ if (request.jwksUri !== undefined)
94
+ body.jwks_uri = request.jwksUri;
95
+ if (request.jwks !== undefined)
96
+ body.jwks = request.jwks;
97
+ if (request.tokenEndpointAuthMethod !== undefined) {
98
+ body.token_endpoint_auth_method = request.tokenEndpointAuthMethod;
99
+ }
100
+ if (request.redirectUris !== undefined)
101
+ body.redirect_uris = [...request.redirectUris];
102
+ if (request.grantTypes !== undefined)
103
+ body.grant_types = [...request.grantTypes];
104
+ if (request.responseTypes !== undefined)
105
+ body.response_types = [...request.responseTypes];
106
+ if (request.scope !== undefined)
107
+ body.scope = request.scope;
108
+ return body;
109
+ }
110
+ function deserializeResponse(body) {
111
+ const response = {
112
+ clientId: body.client_id,
113
+ raw: body,
114
+ };
115
+ if (typeof body.client_secret === "string")
116
+ response.clientSecret = body.client_secret;
117
+ if (typeof body.client_id_issued_at === "number")
118
+ response.clientIdIssuedAt = body.client_id_issued_at;
119
+ if (typeof body.client_secret_expires_at === "number") {
120
+ response.clientSecretExpiresAt = body.client_secret_expires_at;
121
+ }
122
+ if (typeof body.client_name === "string")
123
+ response.clientName = body.client_name;
124
+ if (typeof body.client_uri === "string")
125
+ response.clientUri = body.client_uri;
126
+ if (typeof body.logo_uri === "string")
127
+ response.logoUri = body.logo_uri;
128
+ if (typeof body.tos_uri === "string")
129
+ response.tosUri = body.tos_uri;
130
+ if (typeof body.policy_uri === "string")
131
+ response.policyUri = body.policy_uri;
132
+ if (typeof body.software_id === "string")
133
+ response.softwareId = body.software_id;
134
+ if (typeof body.software_version === "string")
135
+ response.softwareVersion = body.software_version;
136
+ if (typeof body.jwks_uri === "string")
137
+ response.jwksUri = body.jwks_uri;
138
+ if (body.jwks && typeof body.jwks === "object") {
139
+ response.jwks = body.jwks;
140
+ }
141
+ if (typeof body.token_endpoint_auth_method === "string") {
142
+ response.tokenEndpointAuthMethod = body.token_endpoint_auth_method;
143
+ }
144
+ response.redirectUris = normalizeStringArray(body.redirect_uris);
145
+ response.grantTypes = normalizeStringArray(body.grant_types);
146
+ response.responseTypes = normalizeStringArray(body.response_types);
147
+ response.scope = normalizeScope(body.scope);
148
+ if (typeof body.registration_access_token === "string") {
149
+ response.registrationAccessToken = body.registration_access_token;
150
+ }
151
+ if (typeof body.registration_client_uri === "string") {
152
+ response.registrationClientUri = body.registration_client_uri;
153
+ }
154
+ return response;
155
+ }
156
+ function normalizeStringArray(value) {
157
+ if (typeof value === "string")
158
+ return [value];
159
+ if (Array.isArray(value)) {
160
+ const out = value.filter((v) => typeof v === "string");
161
+ return out.length > 0 ? out : undefined;
162
+ }
163
+ return undefined;
164
+ }
165
+ function normalizeScope(value) {
166
+ if (typeof value === "string") {
167
+ const parts = value.split(" ").filter(Boolean);
168
+ return parts.length > 0 ? parts : undefined;
169
+ }
170
+ return normalizeStringArray(value);
171
+ }
172
+ //# sourceMappingURL=registration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration.js","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,8 @@ export { buildSubstituteUserToken } from "./jwt/substituteUser.js";
11
11
  export { TokenExchangeClient, TokenType } from "./tokenExchange.js";
12
12
  export type { TokenExchangeRequest, TokenResponse, TokenExchangeClientOptions, ExchangeOptions, ImpersonateRequest, } from "./tokenExchange.js";
13
13
  export type { ApplicationCredential } from "./credentials.js";
14
+ export { registerClient } from "./registration.js";
15
+ export type { ClientRegistrationRequest, ClientRegistrationResponse, RegisterClientOptions, } from "./registration.js";
14
16
  export { AccessContext, TokenVerifier, ClientSecret } from "./server/index.js";
15
17
  export type { ErrorDetail, AccessContextStatus, AccessToken, TokenVerifierOptions, ClientSecretCredentials, } from "./server/index.js";
16
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC3G,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AAClE,YAAY,EAAE,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EACL,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpE,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC3G,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AAClE,YAAY,EAAE,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AACvE,OAAO,EACL,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpE,YAAY,EACV,oBAAoB,EACpB,aAAa,EACb,0BAA0B,EAC1B,eAAe,EACf,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EACV,yBAAyB,EACzB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/E,YAAY,EACV,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC"}
package/dist/esm/index.js CHANGED
@@ -6,5 +6,6 @@ export { JWTSigner } from "./jwt/signer.js";
6
6
  export { JWTVerifier } from "./jwt/verifier.js";
7
7
  export { buildSubstituteUserToken } from "./jwt/substituteUser.js";
8
8
  export { TokenExchangeClient, TokenType } from "./tokenExchange.js";
9
+ export { registerClient } from "./registration.js";
9
10
  export { AccessContext, TokenVerifier, ClientSecret } from "./server/index.js";
10
11
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AAElE,OAAO,EACL,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AASpE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AAElE,OAAO,EACL,SAAS,EACT,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,8BAA8B,GAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AASpE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMnD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,64 @@
1
+ import type { TokenResponse } from "./tokenExchange.js";
2
+ export interface Pkce {
3
+ codeVerifier: string;
4
+ codeChallenge: string;
5
+ codeChallengeMethod: "S256" | "plain";
6
+ }
7
+ /**
8
+ * Generate a cryptographically random PKCE code verifier (RFC 7636 §4.1).
9
+ *
10
+ * Returns a 43-character base64url string (32 random bytes). Runtime-agnostic:
11
+ * uses the global `crypto.getRandomValues` which is available in Node 19+,
12
+ * Cloudflare Workers, and browsers.
13
+ */
14
+ export declare function generateCodeVerifier(): string;
15
+ /**
16
+ * Derive a PKCE code challenge from a code verifier (RFC 7636 §4.2).
17
+ *
18
+ * S256 (default): `BASE64URL(SHA-256(ASCII(code_verifier)))`
19
+ * plain: returns the verifier unchanged (not recommended; use only when
20
+ * the AS does not support S256).
21
+ */
22
+ export declare function generateCodeChallenge(verifier: string, method?: "S256" | "plain"): Promise<string>;
23
+ /**
24
+ * Generate a PKCE pair (verifier + challenge) in one call.
25
+ */
26
+ export declare function generatePkcePair(method?: "S256" | "plain"): Promise<Pkce>;
27
+ export interface ExchangeAuthorizationCodeOptions {
28
+ codeVerifier: string;
29
+ redirectUri: string;
30
+ clientId?: string;
31
+ clientSecret?: string;
32
+ signal?: AbortSignal;
33
+ }
34
+ /**
35
+ * Exchange an authorization code for tokens (RFC 6749 §4.1.3 + RFC 7636).
36
+ *
37
+ * Discovers `token_endpoint` from the AS metadata, then POSTs
38
+ * `grant_type=authorization_code` with the code verifier.
39
+ */
40
+ export declare function exchangeAuthorizationCode(issuerUrl: string, code: string, options: ExchangeAuthorizationCodeOptions): Promise<TokenResponse>;
41
+ export interface AuthenticateOptions {
42
+ clientId: string;
43
+ /** Default: "http://localhost:{port}/callback" */
44
+ redirectUri?: string;
45
+ /** Default: 8080 */
46
+ port?: number;
47
+ scopes?: readonly string[];
48
+ clientSecret?: string;
49
+ /** Default: 60_000 ms */
50
+ timeoutMs?: number;
51
+ }
52
+ /**
53
+ * Full authorization-code-with-PKCE flow for local/CLI contexts.
54
+ *
55
+ * Generates a PKCE pair, builds the authorization URL, opens the user's
56
+ * browser, starts a local loopback HTTP server to receive the redirect,
57
+ * and exchanges the authorization code for tokens.
58
+ *
59
+ * **Requires Node.js.** Uses `node:http` and `node:child_process` via
60
+ * dynamic import. Importing this module is safe in any runtime; only
61
+ * *calling* `authenticate()` requires Node.js.
62
+ */
63
+ export declare function authenticate(issuerUrl: string, options: AuthenticateOptions): Promise<TokenResponse>;
64
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/pkce.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMxD,MAAM,WAAW,IAAI;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,GAAG,OAAO,CAAC;CACvC;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAM,GAAG,OAAgB,GAChC,OAAO,CAAC,MAAM,CAAC,CASjB;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,MAAM,GAAG,OAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIvF;AAMD,MAAM,WAAW,gCAAgC;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,aAAa,CAAC,CAyExB;AAMD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CAkCxB"}
@@ -0,0 +1,206 @@
1
+ import base64url from "./base64url.js";
2
+ import { fetchAuthorizationServerMetadata } from "./discovery.js";
3
+ import { OAuthError } from "./errors.js";
4
+ /**
5
+ * Generate a cryptographically random PKCE code verifier (RFC 7636 §4.1).
6
+ *
7
+ * Returns a 43-character base64url string (32 random bytes). Runtime-agnostic:
8
+ * uses the global `crypto.getRandomValues` which is available in Node 19+,
9
+ * Cloudflare Workers, and browsers.
10
+ */
11
+ export function generateCodeVerifier() {
12
+ const bytes = new Uint8Array(32);
13
+ crypto.getRandomValues(bytes);
14
+ return base64url.encode(bytes.buffer);
15
+ }
16
+ /**
17
+ * Derive a PKCE code challenge from a code verifier (RFC 7636 §4.2).
18
+ *
19
+ * S256 (default): `BASE64URL(SHA-256(ASCII(code_verifier)))`
20
+ * plain: returns the verifier unchanged (not recommended; use only when
21
+ * the AS does not support S256).
22
+ */
23
+ export async function generateCodeChallenge(verifier, method = "S256") {
24
+ if (method === "plain") {
25
+ return verifier;
26
+ }
27
+ const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
28
+ return base64url.encode(digest);
29
+ }
30
+ /**
31
+ * Generate a PKCE pair (verifier + challenge) in one call.
32
+ */
33
+ export async function generatePkcePair(method = "S256") {
34
+ const codeVerifier = generateCodeVerifier();
35
+ const codeChallenge = await generateCodeChallenge(codeVerifier, method);
36
+ return { codeVerifier, codeChallenge, codeChallengeMethod: method };
37
+ }
38
+ /**
39
+ * Exchange an authorization code for tokens (RFC 6749 §4.1.3 + RFC 7636).
40
+ *
41
+ * Discovers `token_endpoint` from the AS metadata, then POSTs
42
+ * `grant_type=authorization_code` with the code verifier.
43
+ */
44
+ export async function exchangeAuthorizationCode(issuerUrl, code, options) {
45
+ const metadata = await fetchAuthorizationServerMetadata(issuerUrl, {
46
+ signal: options.signal,
47
+ });
48
+ if (!metadata.token_endpoint) {
49
+ throw new Error(`Authorization server "${issuerUrl}" does not advertise a token_endpoint`);
50
+ }
51
+ const params = new URLSearchParams();
52
+ params.set("grant_type", "authorization_code");
53
+ params.set("code", code);
54
+ params.set("code_verifier", options.codeVerifier);
55
+ params.set("redirect_uri", options.redirectUri);
56
+ if (options.clientId)
57
+ params.set("client_id", options.clientId);
58
+ const headers = {
59
+ "Content-Type": "application/x-www-form-urlencoded",
60
+ };
61
+ if (options.clientId && options.clientSecret) {
62
+ headers["Authorization"] = `Basic ${btoa(`${options.clientId}:${options.clientSecret}`)}`;
63
+ params.delete("client_id");
64
+ }
65
+ const response = await fetch(metadata.token_endpoint, {
66
+ method: "POST",
67
+ headers,
68
+ body: params.toString(),
69
+ signal: options.signal,
70
+ });
71
+ if (!response.ok) {
72
+ let errorBody = null;
73
+ try {
74
+ const json = await response.json();
75
+ if (json && typeof json === "object" && !Array.isArray(json)) {
76
+ errorBody = json;
77
+ }
78
+ }
79
+ catch {
80
+ // non-JSON error body — fall through to generic error
81
+ }
82
+ if (errorBody && typeof errorBody.error === "string") {
83
+ const description = typeof errorBody.error_description === "string"
84
+ ? errorBody.error_description
85
+ : errorBody.error;
86
+ const errorUri = typeof errorBody.error_uri === "string" ? errorBody.error_uri : undefined;
87
+ throw new OAuthError(errorBody.error, description, errorUri);
88
+ }
89
+ throw new Error(`Authorization code exchange failed (HTTP ${response.status})`);
90
+ }
91
+ const json = await response.json();
92
+ if (!json || typeof json !== "object" || Array.isArray(json)) {
93
+ throw new Error("Token endpoint response is not a valid JSON object");
94
+ }
95
+ const body = json;
96
+ const accessToken = body.access_token;
97
+ if (typeof accessToken !== "string" || !accessToken) {
98
+ throw new Error("Token endpoint response missing access_token");
99
+ }
100
+ const tokenResponse = {
101
+ accessToken,
102
+ tokenType: typeof body.token_type === "string" ? body.token_type : "bearer",
103
+ };
104
+ if (typeof body.expires_in === "number")
105
+ tokenResponse.expiresIn = body.expires_in;
106
+ if (typeof body.refresh_token === "string")
107
+ tokenResponse.refreshToken = body.refresh_token;
108
+ if (typeof body.scope === "string") {
109
+ tokenResponse.scope = body.scope.split(" ").filter(Boolean);
110
+ }
111
+ return tokenResponse;
112
+ }
113
+ /**
114
+ * Full authorization-code-with-PKCE flow for local/CLI contexts.
115
+ *
116
+ * Generates a PKCE pair, builds the authorization URL, opens the user's
117
+ * browser, starts a local loopback HTTP server to receive the redirect,
118
+ * and exchanges the authorization code for tokens.
119
+ *
120
+ * **Requires Node.js.** Uses `node:http` and `node:child_process` via
121
+ * dynamic import. Importing this module is safe in any runtime; only
122
+ * *calling* `authenticate()` requires Node.js.
123
+ */
124
+ export async function authenticate(issuerUrl, options) {
125
+ const port = options.port ?? 8080;
126
+ const redirectUri = options.redirectUri ?? `http://localhost:${port}/callback`;
127
+ const timeoutMs = options.timeoutMs ?? 60_000;
128
+ const { codeVerifier, codeChallenge } = await generatePkcePair("S256");
129
+ const metadata = await fetchAuthorizationServerMetadata(issuerUrl);
130
+ if (!metadata.authorization_endpoint) {
131
+ throw new Error(`Authorization server "${issuerUrl}" does not advertise an authorization_endpoint`);
132
+ }
133
+ const authUrl = new URL(metadata.authorization_endpoint);
134
+ authUrl.searchParams.set("response_type", "code");
135
+ authUrl.searchParams.set("client_id", options.clientId);
136
+ authUrl.searchParams.set("redirect_uri", redirectUri);
137
+ authUrl.searchParams.set("code_challenge", codeChallenge);
138
+ authUrl.searchParams.set("code_challenge_method", "S256");
139
+ if (options.scopes && options.scopes.length > 0) {
140
+ authUrl.searchParams.set("scope", options.scopes.join(" "));
141
+ }
142
+ await openBrowser(authUrl.toString());
143
+ const code = await waitForCode(port, redirectUri, timeoutMs);
144
+ return exchangeAuthorizationCode(issuerUrl, code, {
145
+ codeVerifier,
146
+ redirectUri,
147
+ clientId: options.clientId,
148
+ clientSecret: options.clientSecret,
149
+ });
150
+ }
151
+ async function openBrowser(url) {
152
+ const { execFile } = await import("node:child_process");
153
+ if (process.platform === "darwin") {
154
+ execFile("open", [url]);
155
+ }
156
+ else if (process.platform === "win32") {
157
+ // `start` is a cmd.exe built-in, not a standalone executable.
158
+ execFile("cmd", ["/c", "start", "", url]);
159
+ }
160
+ else {
161
+ execFile("xdg-open", [url]);
162
+ }
163
+ }
164
+ async function waitForCode(port, redirectUri, timeoutMs) {
165
+ // Import before entering the Promise constructor to avoid the async-executor
166
+ // anti-pattern: if the dynamic import throws, the rejection propagates through
167
+ // this async function rather than escaping an async Promise constructor.
168
+ const { createServer } = await import("node:http");
169
+ return new Promise((resolve, reject) => {
170
+ const timer = setTimeout(() => {
171
+ server.close();
172
+ reject(new Error(`PKCE authentication timed out after ${timeoutMs}ms`));
173
+ }, timeoutMs);
174
+ const server = createServer((req, res) => {
175
+ try {
176
+ const reqUrl = new URL(req.url ?? "/", redirectUri);
177
+ const code = reqUrl.searchParams.get("code");
178
+ const error = reqUrl.searchParams.get("error");
179
+ res.writeHead(200, { "Content-Type": "text/html" });
180
+ res.end("<html><body><p>Authentication complete. You can close this tab.</p></body></html>");
181
+ server.close();
182
+ clearTimeout(timer);
183
+ if (error) {
184
+ reject(new OAuthError(error, reqUrl.searchParams.get("error_description") ?? error));
185
+ }
186
+ else if (code) {
187
+ resolve(code);
188
+ }
189
+ else {
190
+ reject(new Error("No authorization code in redirect"));
191
+ }
192
+ }
193
+ catch (e) {
194
+ server.close();
195
+ clearTimeout(timer);
196
+ reject(e);
197
+ }
198
+ });
199
+ server.listen(port, "localhost");
200
+ server.on("error", (err) => {
201
+ clearTimeout(timer);
202
+ reject(new Error(`Failed to start loopback server on port ${port}: ${err.message}`));
203
+ });
204
+ });
205
+ }
206
+ //# sourceMappingURL=pkce.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/pkce.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * RFC 7591 Dynamic Client Registration request metadata.
3
+ * Reference: https://datatracker.ietf.org/doc/html/rfc7591#section-2
4
+ */
5
+ export interface ClientRegistrationRequest {
6
+ clientName?: string;
7
+ clientUri?: string;
8
+ logoUri?: string;
9
+ tosUri?: string;
10
+ policyUri?: string;
11
+ softwareId?: string;
12
+ softwareVersion?: string;
13
+ jwksUri?: string;
14
+ jwks?: Record<string, unknown>;
15
+ tokenEndpointAuthMethod?: string;
16
+ redirectUris?: readonly string[];
17
+ grantTypes?: readonly string[];
18
+ responseTypes?: readonly string[];
19
+ scope?: string;
20
+ /**
21
+ * Vendor-extension or AS-specific fields not covered by the typed shape.
22
+ * Merged into the request body verbatim (snake_case keys preserved).
23
+ */
24
+ additionalMetadata?: Record<string, unknown>;
25
+ }
26
+ /**
27
+ * RFC 7591 Dynamic Client Registration response.
28
+ * Reference: https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.1
29
+ */
30
+ export interface ClientRegistrationResponse {
31
+ clientId: string;
32
+ clientSecret?: string;
33
+ clientIdIssuedAt?: number;
34
+ clientSecretExpiresAt?: number;
35
+ clientName?: string;
36
+ clientUri?: string;
37
+ logoUri?: string;
38
+ tosUri?: string;
39
+ policyUri?: string;
40
+ softwareId?: string;
41
+ softwareVersion?: string;
42
+ jwksUri?: string;
43
+ jwks?: Record<string, unknown>;
44
+ tokenEndpointAuthMethod?: string;
45
+ redirectUris?: string[];
46
+ grantTypes?: string[];
47
+ responseTypes?: string[];
48
+ scope?: string[];
49
+ registrationAccessToken?: string;
50
+ registrationClientUri?: string;
51
+ /**
52
+ * The full unparsed response body. Useful for AS-specific extensions
53
+ * not captured by the typed fields above.
54
+ */
55
+ raw: Record<string, unknown>;
56
+ }
57
+ export interface RegisterClientOptions {
58
+ signal?: AbortSignal;
59
+ /** Request timeout in milliseconds. Ignored if `signal` is already provided. */
60
+ timeoutMs?: number;
61
+ }
62
+ /**
63
+ * Register a new OAuth 2.0 client with an authorization server (RFC 7591).
64
+ *
65
+ * Discovers `registration_endpoint` from the AS's
66
+ * `.well-known/oauth-authorization-server` metadata, POSTs the registration
67
+ * request as JSON, and returns the issued client credentials.
68
+ *
69
+ * Throws:
70
+ * - `Error` when the AS does not advertise `registration_endpoint`.
71
+ * - `OAuthError` when the AS returns an RFC 6749 §5.2 error response.
72
+ * - `Error` on non-OAuth HTTP failures or malformed responses.
73
+ */
74
+ export declare function registerClient(issuerUrl: string, request: ClientRegistrationRequest, options?: RegisterClientOptions): Promise<ClientRegistrationResponse>;
75
+ //# sourceMappingURL=registration.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registration.d.ts","sourceRoot":"","sources":["../../src/registration.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,MAAM,WAAW,yBAAyB;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gFAAgF;IAChF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,yBAAyB,EAClC,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,0BAA0B,CAAC,CAyDrC"}