@pymthouse/builder-sdk 0.0.8
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/LICENSE +21 -0
- package/README.md +144 -0
- package/dist/device.cjs +246 -0
- package/dist/device.cjs.map +1 -0
- package/dist/device.d.cts +27 -0
- package/dist/device.d.ts +27 -0
- package/dist/device.js +244 -0
- package/dist/device.js.map +1 -0
- package/dist/env-4YmzarGJ.d.ts +68 -0
- package/dist/env-CZczUMzR.d.cts +68 -0
- package/dist/env.cjs +615 -0
- package/dist/env.cjs.map +1 -0
- package/dist/env.d.cts +2 -0
- package/dist/env.d.ts +2 -0
- package/dist/env.js +612 -0
- package/dist/env.js.map +1 -0
- package/dist/format.cjs +27 -0
- package/dist/format.cjs.map +1 -0
- package/dist/format.d.cts +4 -0
- package/dist/format.d.ts +4 -0
- package/dist/format.js +24 -0
- package/dist/format.js.map +1 -0
- package/dist/index.cjs +685 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +47 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.js +670 -0
- package/dist/index.js.map +1 -0
- package/dist/types-W9PJAspR.d.cts +136 -0
- package/dist/types-W9PJAspR.d.ts +136 -0
- package/dist/verify.cjs +181 -0
- package/dist/verify.cjs.map +1 -0
- package/dist/verify.d.cts +18 -0
- package/dist/verify.d.ts +18 -0
- package/dist/verify.js +179 -0
- package/dist/verify.js.map +1 -0
- package/package.json +86 -0
package/dist/device.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { deviceAuthorizationRequest, None, processDeviceAuthorizationResponse, deviceCodeGrantRequest, processDeviceCodeResponse, ResponseBodyError, customFetch, allowInsecureRequests, discoveryRequest, processDiscoveryResponse, OperationProcessingError } from 'oauth4webapi';
|
|
2
|
+
|
|
3
|
+
// src/device.ts
|
|
4
|
+
|
|
5
|
+
// src/errors.ts
|
|
6
|
+
var PmtHouseError = class extends Error {
|
|
7
|
+
status;
|
|
8
|
+
code;
|
|
9
|
+
details;
|
|
10
|
+
constructor(message, {
|
|
11
|
+
status = 500,
|
|
12
|
+
code = "pymthouse_error",
|
|
13
|
+
details
|
|
14
|
+
} = {}) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = "PmtHouseError";
|
|
17
|
+
this.status = status;
|
|
18
|
+
this.code = code;
|
|
19
|
+
this.details = details;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
// src/string-utils.ts
|
|
24
|
+
function stripTrailingSlashes(value) {
|
|
25
|
+
let end = value.length;
|
|
26
|
+
while (end > 0 && value.charCodeAt(end - 1) === 47) {
|
|
27
|
+
end--;
|
|
28
|
+
}
|
|
29
|
+
return value.slice(0, end);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// src/discovery.ts
|
|
33
|
+
var CACHE_TTL_MS = 5 * 60 * 1e3;
|
|
34
|
+
var discoveryCache = /* @__PURE__ */ new Map();
|
|
35
|
+
function normalizedIssuerKey(issuerUrl) {
|
|
36
|
+
return stripTrailingSlashes(issuerUrl);
|
|
37
|
+
}
|
|
38
|
+
async function loadAuthorizationServer(issuerUrl, fetchImpl, options = {}) {
|
|
39
|
+
const key = normalizedIssuerKey(issuerUrl);
|
|
40
|
+
const now = Date.now();
|
|
41
|
+
const cached = discoveryCache.get(key);
|
|
42
|
+
if (!options.force && cached && now - cached.fetchedAt < CACHE_TTL_MS) {
|
|
43
|
+
return cached.as;
|
|
44
|
+
}
|
|
45
|
+
const issuerIdentifier = new URL(key);
|
|
46
|
+
const discoveryOpts = {
|
|
47
|
+
algorithm: "oidc",
|
|
48
|
+
[customFetch]: fetchImpl
|
|
49
|
+
};
|
|
50
|
+
if (options.allowInsecureHttp) {
|
|
51
|
+
discoveryOpts[allowInsecureRequests] = true;
|
|
52
|
+
}
|
|
53
|
+
let response;
|
|
54
|
+
try {
|
|
55
|
+
response = await discoveryRequest(issuerIdentifier, discoveryOpts);
|
|
56
|
+
} catch (e) {
|
|
57
|
+
throw mapDiscoveryNetworkError(e);
|
|
58
|
+
}
|
|
59
|
+
let as;
|
|
60
|
+
try {
|
|
61
|
+
as = await processDiscoveryResponse(issuerIdentifier, response);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
throw mapOAuthDiscoveryError(e);
|
|
64
|
+
}
|
|
65
|
+
discoveryCache.set(key, { as, fetchedAt: now });
|
|
66
|
+
return as;
|
|
67
|
+
}
|
|
68
|
+
function mapOAuthDiscoveryError(error) {
|
|
69
|
+
if (error instanceof PmtHouseError) {
|
|
70
|
+
return error;
|
|
71
|
+
}
|
|
72
|
+
if (error instanceof Error) {
|
|
73
|
+
return new PmtHouseError(error.message, {
|
|
74
|
+
status: 500,
|
|
75
|
+
code: "oidc_discovery_invalid",
|
|
76
|
+
details: { cause: error.cause }
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
return new PmtHouseError("OIDC discovery failed", {
|
|
80
|
+
status: 500,
|
|
81
|
+
code: "oidc_discovery_invalid"
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function mapDiscoveryNetworkError(error) {
|
|
85
|
+
if (error instanceof PmtHouseError) {
|
|
86
|
+
return error;
|
|
87
|
+
}
|
|
88
|
+
if (error instanceof Error) {
|
|
89
|
+
return new PmtHouseError(`Failed to load OIDC discovery: ${error.message}`, {
|
|
90
|
+
status: 502,
|
|
91
|
+
code: "oidc_discovery_failed"
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return new PmtHouseError("Failed to load OIDC discovery", {
|
|
95
|
+
status: 502,
|
|
96
|
+
code: "oidc_discovery_failed"
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function mapOAuthError(error) {
|
|
100
|
+
if (error instanceof PmtHouseError) {
|
|
101
|
+
return error;
|
|
102
|
+
}
|
|
103
|
+
if (error instanceof ResponseBodyError) {
|
|
104
|
+
const cause = error.cause;
|
|
105
|
+
const description = typeof error.error_description === "string" ? error.error_description : error.message;
|
|
106
|
+
const details = { ...cause };
|
|
107
|
+
if (typeof cause.error_uri === "string") {
|
|
108
|
+
details.error_uri = cause.error_uri;
|
|
109
|
+
}
|
|
110
|
+
return new PmtHouseError(description, {
|
|
111
|
+
status: error.status,
|
|
112
|
+
code: error.error,
|
|
113
|
+
details
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (error instanceof OperationProcessingError) {
|
|
117
|
+
return new PmtHouseError(error.message, {
|
|
118
|
+
status: 502,
|
|
119
|
+
code: error.code ?? "oauth_processing_error",
|
|
120
|
+
details: { cause: error.cause }
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
if (error instanceof Error) {
|
|
124
|
+
return new PmtHouseError(error.message, {
|
|
125
|
+
status: 500,
|
|
126
|
+
code: "unexpected_error"
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
return new PmtHouseError("Unexpected error", {
|
|
130
|
+
status: 500,
|
|
131
|
+
code: "unexpected_error"
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// src/device.ts
|
|
136
|
+
function sleep(ms, signal) {
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
const t = setTimeout(resolve, ms);
|
|
139
|
+
signal?.addEventListener(
|
|
140
|
+
"abort",
|
|
141
|
+
() => {
|
|
142
|
+
clearTimeout(t);
|
|
143
|
+
reject(
|
|
144
|
+
signal.reason instanceof Error ? signal.reason : new Error(typeof signal.reason === "string" ? signal.reason : "Aborted")
|
|
145
|
+
);
|
|
146
|
+
},
|
|
147
|
+
{ once: true }
|
|
148
|
+
);
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
async function pollDeviceToken(options) {
|
|
152
|
+
const fetchImpl = options.fetch ?? fetch;
|
|
153
|
+
const as = await loadAuthorizationServer(options.issuerUrl, fetchImpl, {
|
|
154
|
+
allowInsecureHttp: options.allowInsecureHttp
|
|
155
|
+
});
|
|
156
|
+
if (!as.device_authorization_endpoint) {
|
|
157
|
+
throw new PmtHouseError(
|
|
158
|
+
"Authorization server metadata has no device_authorization_endpoint",
|
|
159
|
+
{ status: 400, code: "unsupported_grant" }
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
const client = { client_id: options.clientId };
|
|
163
|
+
const params = new URLSearchParams();
|
|
164
|
+
if (options.scope) {
|
|
165
|
+
params.set("scope", options.scope);
|
|
166
|
+
}
|
|
167
|
+
const httpOpts = {
|
|
168
|
+
[customFetch]: fetchImpl
|
|
169
|
+
};
|
|
170
|
+
if (options.allowInsecureHttp) {
|
|
171
|
+
httpOpts[allowInsecureRequests] = true;
|
|
172
|
+
}
|
|
173
|
+
let deviceResponse;
|
|
174
|
+
try {
|
|
175
|
+
deviceResponse = await deviceAuthorizationRequest(
|
|
176
|
+
as,
|
|
177
|
+
client,
|
|
178
|
+
None(),
|
|
179
|
+
params,
|
|
180
|
+
httpOpts
|
|
181
|
+
);
|
|
182
|
+
} catch (e) {
|
|
183
|
+
throw mapOAuthError(e);
|
|
184
|
+
}
|
|
185
|
+
let dar;
|
|
186
|
+
try {
|
|
187
|
+
dar = await processDeviceAuthorizationResponse(as, client, deviceResponse);
|
|
188
|
+
} catch (e) {
|
|
189
|
+
throw mapOAuthError(e);
|
|
190
|
+
}
|
|
191
|
+
options.onUserCode?.({
|
|
192
|
+
userCode: dar.user_code,
|
|
193
|
+
verificationUri: dar.verification_uri,
|
|
194
|
+
verificationUriComplete: dar.verification_uri_complete,
|
|
195
|
+
expiresIn: dar.expires_in,
|
|
196
|
+
intervalSeconds: dar.interval
|
|
197
|
+
});
|
|
198
|
+
let pollIntervalMs = (dar.interval ?? 5) * 1e3;
|
|
199
|
+
const deadline = Date.now() + dar.expires_in * 1e3;
|
|
200
|
+
let firstPoll = true;
|
|
201
|
+
while (Date.now() < deadline) {
|
|
202
|
+
if (options.signal?.aborted) {
|
|
203
|
+
throw options.signal.reason instanceof Error ? options.signal.reason : new Error("Aborted");
|
|
204
|
+
}
|
|
205
|
+
if (!firstPoll) {
|
|
206
|
+
await sleep(pollIntervalMs, options.signal);
|
|
207
|
+
}
|
|
208
|
+
firstPoll = false;
|
|
209
|
+
let tokenResponse;
|
|
210
|
+
try {
|
|
211
|
+
tokenResponse = await deviceCodeGrantRequest(
|
|
212
|
+
as,
|
|
213
|
+
client,
|
|
214
|
+
None(),
|
|
215
|
+
dar.device_code,
|
|
216
|
+
httpOpts
|
|
217
|
+
);
|
|
218
|
+
} catch (e) {
|
|
219
|
+
throw mapOAuthError(e);
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
return await processDeviceCodeResponse(as, client, tokenResponse);
|
|
223
|
+
} catch (e) {
|
|
224
|
+
if (e instanceof ResponseBodyError) {
|
|
225
|
+
if (e.error === "authorization_pending") {
|
|
226
|
+
continue;
|
|
227
|
+
}
|
|
228
|
+
if (e.error === "slow_down") {
|
|
229
|
+
pollIntervalMs += 5e3;
|
|
230
|
+
continue;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
throw mapOAuthError(e);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
throw new PmtHouseError("Device authorization expired before completion", {
|
|
237
|
+
status: 408,
|
|
238
|
+
code: "device_flow_expired"
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export { pollDeviceToken };
|
|
243
|
+
//# sourceMappingURL=device.js.map
|
|
244
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/string-utils.ts","../src/discovery.ts","../src/oauth-map.ts","../src/device.ts"],"names":["customFetch","allowInsecureRequests","ResponseBodyError"],"mappings":"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","file":"device.js","sourcesContent":["export class PmtHouseError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(\n message: string,\n {\n status = 500,\n code = \"pymthouse_error\",\n details,\n }: {\n status?: number;\n code?: string;\n details?: unknown;\n } = {},\n ) {\n super(message);\n this.name = \"PmtHouseError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\nexport function toPmtHouseError(\n error: unknown,\n fallbackMessage: string,\n): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message || fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n }\n\n return new PmtHouseError(fallbackMessage, {\n code: \"unexpected_error\",\n status: 500,\n });\n}\n","/** Removes trailing `/` without regex (linear time). */\nexport function stripTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 47) {\n end--;\n }\n return value.slice(0, end);\n}\n","import {\n allowInsecureRequests,\n customFetch,\n discoveryRequest,\n processDiscoveryResponse,\n type AuthorizationServer,\n} from \"oauth4webapi\";\nimport { PmtHouseError } from \"./errors.js\";\nimport { stripTrailingSlashes } from \"./string-utils.js\";\nimport type { FetchLike, OidcDiscoveryDocument } from \"./types.js\";\n\nexport function authorizationServerToOidcDocument(as: AuthorizationServer): OidcDiscoveryDocument {\n const tokenEndpoint = as.token_endpoint;\n const jwksUri = as.jwks_uri;\n if (!tokenEndpoint || !jwksUri) {\n throw new PmtHouseError(\"OIDC discovery document is missing token_endpoint or jwks_uri\", {\n status: 500,\n code: \"oidc_discovery_invalid\",\n });\n }\n return {\n issuer: as.issuer,\n authorization_endpoint: as.authorization_endpoint ?? \"\",\n token_endpoint: tokenEndpoint,\n jwks_uri: jwksUri,\n userinfo_endpoint: as.userinfo_endpoint,\n device_authorization_endpoint: as.device_authorization_endpoint,\n };\n}\n\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\ntype CacheEntry = {\n as: AuthorizationServer;\n fetchedAt: number;\n};\n\nconst discoveryCache = new Map<string, CacheEntry>();\n\nfunction normalizedIssuerKey(issuerUrl: string): string {\n return stripTrailingSlashes(issuerUrl);\n}\n\nexport interface LoadAuthorizationServerOptions {\n force?: boolean;\n allowInsecureHttp?: boolean;\n}\n\n/**\n * Loads OIDC discovery metadata via oauth4webapi (RFC 8414 / OIDC Discovery), with a 5-minute cache.\n */\nexport async function loadAuthorizationServer(\n issuerUrl: string,\n fetchImpl: FetchLike,\n options: LoadAuthorizationServerOptions = {},\n): Promise<AuthorizationServer> {\n const key = normalizedIssuerKey(issuerUrl);\n const now = Date.now();\n const cached = discoveryCache.get(key);\n\n if (!options.force && cached && now - cached.fetchedAt < CACHE_TTL_MS) {\n return cached.as;\n }\n\n const issuerIdentifier = new URL(key);\n const discoveryOpts: Parameters<typeof discoveryRequest>[1] = {\n algorithm: \"oidc\",\n [customFetch]: fetchImpl,\n };\n if (options.allowInsecureHttp) {\n discoveryOpts[allowInsecureRequests] = true;\n }\n\n let response: Response;\n try {\n response = await discoveryRequest(issuerIdentifier, discoveryOpts);\n } catch (e) {\n throw mapDiscoveryNetworkError(e);\n }\n\n let as: AuthorizationServer;\n try {\n as = await processDiscoveryResponse(issuerIdentifier, response);\n } catch (e) {\n throw mapOAuthDiscoveryError(e);\n }\n\n discoveryCache.set(key, { as, fetchedAt: now });\n return as;\n}\n\nexport async function fetchDiscoveryDocument(\n issuerUrl: string,\n fetchImpl: FetchLike,\n options: LoadAuthorizationServerOptions = {},\n): Promise<OidcDiscoveryDocument> {\n const as = await loadAuthorizationServer(issuerUrl, fetchImpl, options);\n return authorizationServerToOidcDocument(as);\n}\n\nexport function clearDiscoveryCache(issuerUrl?: string): void {\n if (!issuerUrl) {\n discoveryCache.clear();\n return;\n }\n discoveryCache.delete(normalizedIssuerKey(issuerUrl));\n}\n\nfunction mapOAuthDiscoveryError(error: unknown): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n if (error instanceof Error) {\n return new PmtHouseError(error.message, {\n status: 500,\n code: \"oidc_discovery_invalid\",\n details: { cause: error.cause },\n });\n }\n return new PmtHouseError(\"OIDC discovery failed\", {\n status: 500,\n code: \"oidc_discovery_invalid\",\n });\n}\n\nfunction mapDiscoveryNetworkError(error: unknown): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n if (error instanceof Error) {\n return new PmtHouseError(`Failed to load OIDC discovery: ${error.message}`, {\n status: 502,\n code: \"oidc_discovery_failed\",\n });\n }\n return new PmtHouseError(\"Failed to load OIDC discovery\", {\n status: 502,\n code: \"oidc_discovery_failed\",\n });\n}\n","import { type Client, OperationProcessingError, ResponseBodyError } from \"oauth4webapi\";\nimport { PmtHouseError } from \"./errors.js\";\nimport type { ClientCredentialsTokenResponse, TokenExchangeResponse } from \"./types.js\";\n\nconst ACCEPTED_ISSUED_TOKEN_TYPES = new Set([\n \"urn:ietf:params:oauth:token-type:access_token\",\n \"urn:pmth:token-type:remote-signer-session\",\n]);\n\nexport function mapOAuthError(error: unknown): PmtHouseError {\n if (error instanceof PmtHouseError) {\n return error;\n }\n\n if (error instanceof ResponseBodyError) {\n const cause = error.cause as Record<string, unknown>;\n const description =\n typeof error.error_description === \"string\"\n ? error.error_description\n : error.message;\n const details: Record<string, unknown> = { ...cause };\n if (typeof cause.error_uri === \"string\") {\n details.error_uri = cause.error_uri;\n }\n return new PmtHouseError(description, {\n status: error.status,\n code: error.error,\n details,\n });\n }\n\n if (error instanceof OperationProcessingError) {\n return new PmtHouseError(error.message, {\n status: 502,\n code: error.code ?? \"oauth_processing_error\",\n details: { cause: error.cause },\n });\n }\n\n if (error instanceof Error) {\n return new PmtHouseError(error.message, {\n status: 500,\n code: \"unexpected_error\",\n });\n }\n\n return new PmtHouseError(\"Unexpected error\", {\n status: 500,\n code: \"unexpected_error\",\n });\n}\n\nexport function tokenEndpointResponseToExchange(\n tr: import(\"oauth4webapi\").TokenEndpointResponse,\n): TokenExchangeResponse {\n const issued = tr.issued_token_type;\n if (typeof issued !== \"string\" || !ACCEPTED_ISSUED_TOKEN_TYPES.has(issued)) {\n throw new PmtHouseError(\"Token exchange returned an unexpected issued_token_type\", {\n status: 502,\n code: \"invalid_token_response\",\n details: { issued_token_type: issued },\n });\n }\n\n const tt = tr.token_type;\n if (typeof tt !== \"string\" || tt.toLowerCase() !== \"bearer\") {\n throw new PmtHouseError(\"Token endpoint returned a non-Bearer token_type\", {\n status: 502,\n code: \"invalid_token_response\",\n details: { token_type: tt },\n });\n }\n\n const expiresIn = tr.expires_in;\n if (typeof expiresIn !== \"number\") {\n throw new PmtHouseError(\"Token response missing expires_in\", {\n status: 502,\n code: \"invalid_token_response\",\n });\n }\n\n const scope = typeof tr.scope === \"string\" ? tr.scope : \"\";\n\n return {\n access_token: tr.access_token,\n token_type: \"Bearer\",\n expires_in: expiresIn,\n scope,\n issued_token_type: issued,\n };\n}\n\nexport function tokenEndpointResponseToClientCredentials(\n tr: import(\"oauth4webapi\").TokenEndpointResponse,\n): ClientCredentialsTokenResponse {\n const tt = tr.token_type;\n if (typeof tt !== \"string\" || tt.toLowerCase() !== \"bearer\") {\n throw new PmtHouseError(\"Token endpoint returned a non-Bearer token_type\", {\n status: 502,\n code: \"invalid_token_response\",\n details: { token_type: tt },\n });\n }\n\n return {\n access_token: tr.access_token,\n token_type: \"Bearer\",\n expires_in: tr.expires_in,\n scope: typeof tr.scope === \"string\" ? tr.scope : undefined,\n };\n}\n\nexport function m2mClient(clientId: string): Client {\n return { client_id: clientId };\n}\n","import {\n allowInsecureRequests,\n customFetch,\n deviceAuthorizationRequest,\n deviceCodeGrantRequest,\n None,\n processDeviceAuthorizationResponse,\n processDeviceCodeResponse,\n ResponseBodyError,\n type Client,\n} from \"oauth4webapi\";\nimport { loadAuthorizationServer } from \"./discovery.js\";\nimport { PmtHouseError } from \"./errors.js\";\nimport { mapOAuthError } from \"./oauth-map.js\";\nimport type { FetchLike } from \"./types.js\";\n\nexport interface PollDeviceTokenOptions {\n issuerUrl: string;\n /** Public OAuth `client_id` (RFC 8628). */\n clientId: string;\n /** Space-separated scopes for the device authorization request. */\n scope?: string;\n fetch?: FetchLike;\n allowInsecureHttp?: boolean;\n signal?: AbortSignal;\n onUserCode?: (info: {\n userCode: string;\n verificationUri: string;\n verificationUriComplete?: string;\n expiresIn: number;\n intervalSeconds?: number;\n }) => void;\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n const t = setTimeout(resolve, ms);\n signal?.addEventListener(\n \"abort\",\n () => {\n clearTimeout(t);\n reject(\n signal.reason instanceof Error\n ? signal.reason\n : new Error(typeof signal.reason === \"string\" ? signal.reason : \"Aborted\"),\n );\n },\n { once: true },\n );\n });\n}\n\n/**\n * RFC 8628 device authorization grant: request a device code, then poll the token endpoint until\n * tokens are issued (handles `authorization_pending` and `slow_down`).\n */\nexport async function pollDeviceToken(\n options: PollDeviceTokenOptions,\n): Promise<import(\"oauth4webapi\").TokenEndpointResponse> {\n const fetchImpl = options.fetch ?? fetch;\n const as = await loadAuthorizationServer(options.issuerUrl, fetchImpl, {\n allowInsecureHttp: options.allowInsecureHttp,\n });\n\n if (!as.device_authorization_endpoint) {\n throw new PmtHouseError(\n \"Authorization server metadata has no device_authorization_endpoint\",\n { status: 400, code: \"unsupported_grant\" },\n );\n }\n\n const client: Client = { client_id: options.clientId };\n const params = new URLSearchParams();\n if (options.scope) {\n params.set(\"scope\", options.scope);\n }\n\n const httpOpts: Record<symbol, unknown> = {\n [customFetch]: fetchImpl,\n };\n if (options.allowInsecureHttp) {\n httpOpts[allowInsecureRequests] = true;\n }\n\n let deviceResponse: Response;\n try {\n deviceResponse = await deviceAuthorizationRequest(\n as,\n client,\n None(),\n params,\n httpOpts as import(\"oauth4webapi\").DeviceAuthorizationRequestOptions,\n );\n } catch (e) {\n throw mapOAuthError(e);\n }\n\n let dar: import(\"oauth4webapi\").DeviceAuthorizationResponse;\n try {\n dar = await processDeviceAuthorizationResponse(as, client, deviceResponse);\n } catch (e) {\n throw mapOAuthError(e);\n }\n\n options.onUserCode?.({\n userCode: dar.user_code,\n verificationUri: dar.verification_uri,\n verificationUriComplete: dar.verification_uri_complete,\n expiresIn: dar.expires_in,\n intervalSeconds: dar.interval,\n });\n\n let pollIntervalMs = (dar.interval ?? 5) * 1000;\n const deadline = Date.now() + dar.expires_in * 1000;\n let firstPoll = true;\n\n while (Date.now() < deadline) {\n if (options.signal?.aborted) {\n throw options.signal.reason instanceof Error\n ? options.signal.reason\n : new Error(\"Aborted\");\n }\n\n if (!firstPoll) {\n await sleep(pollIntervalMs, options.signal);\n }\n firstPoll = false;\n\n let tokenResponse: Response;\n try {\n tokenResponse = await deviceCodeGrantRequest(\n as,\n client,\n None(),\n dar.device_code,\n httpOpts as import(\"oauth4webapi\").TokenEndpointRequestOptions,\n );\n } catch (e) {\n throw mapOAuthError(e);\n }\n\n try {\n return await processDeviceCodeResponse(as, client, tokenResponse);\n } catch (e) {\n if (e instanceof ResponseBodyError) {\n if (e.error === \"authorization_pending\") {\n continue;\n }\n if (e.error === \"slow_down\") {\n pollIntervalMs += 5000;\n continue;\n }\n }\n throw mapOAuthError(e);\n }\n }\n\n throw new PmtHouseError(\"Device authorization expired before completion\", {\n status: 408,\n code: \"device_flow_expired\",\n });\n}\n"]}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { f as PmtHouseClientOptions, G as GetDiscoveryOptions, O as OidcDiscoveryDocument, P as ParsedDeviceApprovalRedirect, A as AppUserRecord, g as UpsertAppUserInput, M as MintUserAccessTokenInput, d as MintUserAccessTokenResponse, D as DeviceApprovalInput, T as TokenExchangeResponse, C as ClientCredentialsTokenResponse, e as MintUserSignerSessionTokenInput, h as UsageQueryInput, b as UsageApiResponse } from './types-W9PJAspR.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalize RFC 8628 user codes for comparison and resource URIs (uppercase, strip separators).
|
|
5
|
+
*/
|
|
6
|
+
declare function normalizeUserCode(value: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* RFC 8707 resource indicator for NaaP Option B device approval (`urn:pmth:device_code:<normalized>`).
|
|
9
|
+
*/
|
|
10
|
+
declare function buildDeviceCodeResource(userCode: string): string;
|
|
11
|
+
declare class PmtHouseClient {
|
|
12
|
+
private readonly issuerUrl;
|
|
13
|
+
private readonly publicClientId;
|
|
14
|
+
private readonly m2mClientId;
|
|
15
|
+
private readonly m2mClientSecret;
|
|
16
|
+
private readonly fetchImpl;
|
|
17
|
+
private readonly logger?;
|
|
18
|
+
private readonly allowInsecureHttp;
|
|
19
|
+
constructor(options: PmtHouseClientOptions);
|
|
20
|
+
getDiscovery(options?: GetDiscoveryOptions): Promise<OidcDiscoveryDocument>;
|
|
21
|
+
verifyIssuer(iss: string): boolean;
|
|
22
|
+
parseDeviceApprovalRedirect(searchParams: URLSearchParams): ParsedDeviceApprovalRedirect;
|
|
23
|
+
listAppUsers(): Promise<{
|
|
24
|
+
users: AppUserRecord[];
|
|
25
|
+
}>;
|
|
26
|
+
upsertAppUser(input: UpsertAppUserInput): Promise<AppUserRecord>;
|
|
27
|
+
deleteAppUser(params: {
|
|
28
|
+
externalUserId: string;
|
|
29
|
+
}): Promise<{
|
|
30
|
+
success: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
mintUserAccessToken(input: MintUserAccessTokenInput): Promise<MintUserAccessTokenResponse>;
|
|
33
|
+
completeDeviceApproval(input: DeviceApprovalInput): Promise<TokenExchangeResponse>;
|
|
34
|
+
issueMachineAccessToken(scope?: string): Promise<ClientCredentialsTokenResponse>;
|
|
35
|
+
exchangeForSignerSession(input: {
|
|
36
|
+
userJwt: string;
|
|
37
|
+
resource?: string;
|
|
38
|
+
}): Promise<TokenExchangeResponse>;
|
|
39
|
+
/**
|
|
40
|
+
* Mint a short-lived per-user JWT with the Builder API, then exchange it for
|
|
41
|
+
* a long-lived opaque signer session token at the PymtHouse OIDC token endpoint.
|
|
42
|
+
*/
|
|
43
|
+
mintUserSignerSessionToken(input: MintUserSignerSessionTokenInput): Promise<TokenExchangeResponse>;
|
|
44
|
+
createSignerSessionToken(params: {
|
|
45
|
+
userJwt?: string;
|
|
46
|
+
}): Promise<TokenExchangeResponse>;
|
|
47
|
+
getUsage(input?: UsageQueryInput): Promise<UsageApiResponse>;
|
|
48
|
+
private tokenEndpointFetchOptions;
|
|
49
|
+
private getAppsBaseUrl;
|
|
50
|
+
private getIssuerOrigin;
|
|
51
|
+
private builderHeaders;
|
|
52
|
+
private m2mClientAuth;
|
|
53
|
+
private requestJson;
|
|
54
|
+
private safeParseJson;
|
|
55
|
+
private asError;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Site origin for the PymtHouse deployment (e.g. https://pymthouse.com), derived
|
|
60
|
+
* from `PYMTHOUSE_ISSUER_URL`.
|
|
61
|
+
*/
|
|
62
|
+
declare function getPymthouseBaseUrl(): string;
|
|
63
|
+
/**
|
|
64
|
+
* Singleton `PmtHouseClient` from `PYMTHOUSE_*` environment variables (server-side).
|
|
65
|
+
*/
|
|
66
|
+
declare function createPmtHouseClientFromEnv(): PmtHouseClient;
|
|
67
|
+
|
|
68
|
+
export { PmtHouseClient as P, buildDeviceCodeResource as b, createPmtHouseClientFromEnv as c, getPymthouseBaseUrl as g, normalizeUserCode as n };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { f as PmtHouseClientOptions, G as GetDiscoveryOptions, O as OidcDiscoveryDocument, P as ParsedDeviceApprovalRedirect, A as AppUserRecord, g as UpsertAppUserInput, M as MintUserAccessTokenInput, d as MintUserAccessTokenResponse, D as DeviceApprovalInput, T as TokenExchangeResponse, C as ClientCredentialsTokenResponse, e as MintUserSignerSessionTokenInput, h as UsageQueryInput, b as UsageApiResponse } from './types-W9PJAspR.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalize RFC 8628 user codes for comparison and resource URIs (uppercase, strip separators).
|
|
5
|
+
*/
|
|
6
|
+
declare function normalizeUserCode(value: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* RFC 8707 resource indicator for NaaP Option B device approval (`urn:pmth:device_code:<normalized>`).
|
|
9
|
+
*/
|
|
10
|
+
declare function buildDeviceCodeResource(userCode: string): string;
|
|
11
|
+
declare class PmtHouseClient {
|
|
12
|
+
private readonly issuerUrl;
|
|
13
|
+
private readonly publicClientId;
|
|
14
|
+
private readonly m2mClientId;
|
|
15
|
+
private readonly m2mClientSecret;
|
|
16
|
+
private readonly fetchImpl;
|
|
17
|
+
private readonly logger?;
|
|
18
|
+
private readonly allowInsecureHttp;
|
|
19
|
+
constructor(options: PmtHouseClientOptions);
|
|
20
|
+
getDiscovery(options?: GetDiscoveryOptions): Promise<OidcDiscoveryDocument>;
|
|
21
|
+
verifyIssuer(iss: string): boolean;
|
|
22
|
+
parseDeviceApprovalRedirect(searchParams: URLSearchParams): ParsedDeviceApprovalRedirect;
|
|
23
|
+
listAppUsers(): Promise<{
|
|
24
|
+
users: AppUserRecord[];
|
|
25
|
+
}>;
|
|
26
|
+
upsertAppUser(input: UpsertAppUserInput): Promise<AppUserRecord>;
|
|
27
|
+
deleteAppUser(params: {
|
|
28
|
+
externalUserId: string;
|
|
29
|
+
}): Promise<{
|
|
30
|
+
success: boolean;
|
|
31
|
+
}>;
|
|
32
|
+
mintUserAccessToken(input: MintUserAccessTokenInput): Promise<MintUserAccessTokenResponse>;
|
|
33
|
+
completeDeviceApproval(input: DeviceApprovalInput): Promise<TokenExchangeResponse>;
|
|
34
|
+
issueMachineAccessToken(scope?: string): Promise<ClientCredentialsTokenResponse>;
|
|
35
|
+
exchangeForSignerSession(input: {
|
|
36
|
+
userJwt: string;
|
|
37
|
+
resource?: string;
|
|
38
|
+
}): Promise<TokenExchangeResponse>;
|
|
39
|
+
/**
|
|
40
|
+
* Mint a short-lived per-user JWT with the Builder API, then exchange it for
|
|
41
|
+
* a long-lived opaque signer session token at the PymtHouse OIDC token endpoint.
|
|
42
|
+
*/
|
|
43
|
+
mintUserSignerSessionToken(input: MintUserSignerSessionTokenInput): Promise<TokenExchangeResponse>;
|
|
44
|
+
createSignerSessionToken(params: {
|
|
45
|
+
userJwt?: string;
|
|
46
|
+
}): Promise<TokenExchangeResponse>;
|
|
47
|
+
getUsage(input?: UsageQueryInput): Promise<UsageApiResponse>;
|
|
48
|
+
private tokenEndpointFetchOptions;
|
|
49
|
+
private getAppsBaseUrl;
|
|
50
|
+
private getIssuerOrigin;
|
|
51
|
+
private builderHeaders;
|
|
52
|
+
private m2mClientAuth;
|
|
53
|
+
private requestJson;
|
|
54
|
+
private safeParseJson;
|
|
55
|
+
private asError;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Site origin for the PymtHouse deployment (e.g. https://pymthouse.com), derived
|
|
60
|
+
* from `PYMTHOUSE_ISSUER_URL`.
|
|
61
|
+
*/
|
|
62
|
+
declare function getPymthouseBaseUrl(): string;
|
|
63
|
+
/**
|
|
64
|
+
* Singleton `PmtHouseClient` from `PYMTHOUSE_*` environment variables (server-side).
|
|
65
|
+
*/
|
|
66
|
+
declare function createPmtHouseClientFromEnv(): PmtHouseClient;
|
|
67
|
+
|
|
68
|
+
export { PmtHouseClient as P, buildDeviceCodeResource as b, createPmtHouseClientFromEnv as c, getPymthouseBaseUrl as g, normalizeUserCode as n };
|