@keycardai/oauth 0.5.0 → 0.7.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.
Files changed (51) hide show
  1. package/LICENSE +5 -17
  2. package/README.md +45 -0
  3. package/dist/cjs/index.d.ts +2 -0
  4. package/dist/cjs/index.d.ts.map +1 -1
  5. package/dist/cjs/index.js +7 -1
  6. package/dist/cjs/index.js.map +1 -1
  7. package/dist/cjs/pkce.d.ts +64 -0
  8. package/dist/cjs/pkce.d.ts.map +1 -0
  9. package/dist/cjs/pkce.js +249 -0
  10. package/dist/cjs/pkce.js.map +1 -0
  11. package/dist/cjs/server/eksWorkloadIdentity.d.ts +22 -0
  12. package/dist/cjs/server/eksWorkloadIdentity.d.ts.map +1 -0
  13. package/dist/cjs/server/eksWorkloadIdentity.js +117 -0
  14. package/dist/cjs/server/eksWorkloadIdentity.js.map +1 -0
  15. package/dist/cjs/server/index.d.ts +6 -0
  16. package/dist/cjs/server/index.d.ts.map +1 -1
  17. package/dist/cjs/server/index.js +8 -1
  18. package/dist/cjs/server/index.js.map +1 -1
  19. package/dist/cjs/server/privateKey.d.ts +47 -0
  20. package/dist/cjs/server/privateKey.d.ts.map +1 -0
  21. package/dist/cjs/server/privateKey.js +233 -0
  22. package/dist/cjs/server/privateKey.js.map +1 -0
  23. package/dist/cjs/server/webIdentity.d.ts +37 -0
  24. package/dist/cjs/server/webIdentity.d.ts.map +1 -0
  25. package/dist/cjs/server/webIdentity.js +75 -0
  26. package/dist/cjs/server/webIdentity.js.map +1 -0
  27. package/dist/esm/index.d.ts +2 -0
  28. package/dist/esm/index.d.ts.map +1 -1
  29. package/dist/esm/index.js +1 -0
  30. package/dist/esm/index.js.map +1 -1
  31. package/dist/esm/pkce.d.ts +64 -0
  32. package/dist/esm/pkce.d.ts.map +1 -0
  33. package/dist/esm/pkce.js +206 -0
  34. package/dist/esm/pkce.js.map +1 -0
  35. package/dist/esm/server/eksWorkloadIdentity.d.ts +22 -0
  36. package/dist/esm/server/eksWorkloadIdentity.d.ts.map +1 -0
  37. package/dist/esm/server/eksWorkloadIdentity.js +80 -0
  38. package/dist/esm/server/eksWorkloadIdentity.js.map +1 -0
  39. package/dist/esm/server/index.d.ts +6 -0
  40. package/dist/esm/server/index.d.ts.map +1 -1
  41. package/dist/esm/server/index.js +3 -0
  42. package/dist/esm/server/index.js.map +1 -1
  43. package/dist/esm/server/privateKey.d.ts +47 -0
  44. package/dist/esm/server/privateKey.d.ts.map +1 -0
  45. package/dist/esm/server/privateKey.js +195 -0
  46. package/dist/esm/server/privateKey.js.map +1 -0
  47. package/dist/esm/server/webIdentity.d.ts +37 -0
  48. package/dist/esm/server/webIdentity.d.ts.map +1 -0
  49. package/dist/esm/server/webIdentity.js +71 -0
  50. package/dist/esm/server/webIdentity.js.map +1 -0
  51. package/package.json +7 -1
@@ -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,22 @@
1
+ import type { ApplicationCredential } from "../credentials.js";
2
+ import type { TokenExchangeRequest } from "../tokenExchange.js";
3
+ export interface EKSWorkloadIdentityOptions {
4
+ tokenFilePath?: string;
5
+ envVarName?: string;
6
+ }
7
+ /**
8
+ * EKS pod identity credential provider. Reads the workload identity token
9
+ * from the mounted file path (resolved from the standard EKS environment
10
+ * variables or the explicit `tokenFilePath` option) and uses it as a
11
+ * client assertion in RFC 8693 token exchange requests.
12
+ *
13
+ * **Requires Node.js.** Reads the token file synchronously from the
14
+ * filesystem at construction and exchange time.
15
+ */
16
+ export declare class EKSWorkloadIdentity implements ApplicationCredential {
17
+ #private;
18
+ constructor(options?: EKSWorkloadIdentityOptions);
19
+ getAuth(): null;
20
+ prepareTokenExchangeRequest(subjectToken: string, resource: string): Promise<TokenExchangeRequest>;
21
+ }
22
+ //# sourceMappingURL=eksWorkloadIdentity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eksWorkloadIdentity.d.ts","sourceRoot":"","sources":["../../../src/server/eksWorkloadIdentity.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAQhE,MAAM,WAAW,0BAA0B;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,qBAAa,mBAAoB,YAAW,qBAAqB;;gBAGnD,OAAO,CAAC,EAAE,0BAA0B;IAmBhD,OAAO,IAAI,IAAI;IAIT,2BAA2B,CAC/B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,oBAAoB,CAAC;CA+BjC"}
@@ -0,0 +1,80 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _EKSWorkloadIdentity_instances, _EKSWorkloadIdentity_tokenFilePath, _EKSWorkloadIdentity_validateTokenFile, _EKSWorkloadIdentity_readToken;
13
+ import * as fs from "node:fs";
14
+ const DEFAULT_EKS_ENV_VARS = [
15
+ "KEYCARD_EKS_WORKLOAD_IDENTITY_TOKEN_FILE",
16
+ "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE",
17
+ "AWS_WEB_IDENTITY_TOKEN_FILE",
18
+ ];
19
+ /**
20
+ * EKS pod identity credential provider. Reads the workload identity token
21
+ * from the mounted file path (resolved from the standard EKS environment
22
+ * variables or the explicit `tokenFilePath` option) and uses it as a
23
+ * client assertion in RFC 8693 token exchange requests.
24
+ *
25
+ * **Requires Node.js.** Reads the token file synchronously from the
26
+ * filesystem at construction and exchange time.
27
+ */
28
+ export class EKSWorkloadIdentity {
29
+ constructor(options) {
30
+ _EKSWorkloadIdentity_instances.add(this);
31
+ _EKSWorkloadIdentity_tokenFilePath.set(this, void 0);
32
+ if (options?.tokenFilePath) {
33
+ __classPrivateFieldSet(this, _EKSWorkloadIdentity_tokenFilePath, options.tokenFilePath, "f");
34
+ }
35
+ else {
36
+ const envNames = options?.envVarName
37
+ ? [options.envVarName, ...DEFAULT_EKS_ENV_VARS]
38
+ : DEFAULT_EKS_ENV_VARS;
39
+ const found = envNames.find((name) => process.env[name]);
40
+ if (!found || !process.env[found]) {
41
+ throw new Error(`EKSWorkloadIdentity: could not find token file path in environment variables. ` +
42
+ `Checked: ${envNames.join(", ")}`);
43
+ }
44
+ __classPrivateFieldSet(this, _EKSWorkloadIdentity_tokenFilePath, process.env[found], "f");
45
+ }
46
+ __classPrivateFieldGet(this, _EKSWorkloadIdentity_instances, "m", _EKSWorkloadIdentity_validateTokenFile).call(this);
47
+ }
48
+ getAuth() {
49
+ return null;
50
+ }
51
+ async prepareTokenExchangeRequest(subjectToken, resource) {
52
+ return {
53
+ subjectToken,
54
+ resource,
55
+ subjectTokenType: "urn:ietf:params:oauth:token-type:access_token",
56
+ clientAssertionType: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
57
+ clientAssertion: __classPrivateFieldGet(this, _EKSWorkloadIdentity_instances, "m", _EKSWorkloadIdentity_readToken).call(this),
58
+ };
59
+ }
60
+ }
61
+ _EKSWorkloadIdentity_tokenFilePath = new WeakMap(), _EKSWorkloadIdentity_instances = new WeakSet(), _EKSWorkloadIdentity_validateTokenFile = function _EKSWorkloadIdentity_validateTokenFile() {
62
+ try {
63
+ const token = fs.readFileSync(__classPrivateFieldGet(this, _EKSWorkloadIdentity_tokenFilePath, "f"), "utf-8").trim();
64
+ if (!token) {
65
+ throw new Error(`EKSWorkloadIdentity: token file is empty: ${__classPrivateFieldGet(this, _EKSWorkloadIdentity_tokenFilePath, "f")}`);
66
+ }
67
+ }
68
+ catch (error) {
69
+ if (error instanceof Error && error.message.startsWith("EKSWorkloadIdentity:"))
70
+ throw error;
71
+ throw new Error(`EKSWorkloadIdentity: error reading token file "${__classPrivateFieldGet(this, _EKSWorkloadIdentity_tokenFilePath, "f")}": ${error}`);
72
+ }
73
+ }, _EKSWorkloadIdentity_readToken = function _EKSWorkloadIdentity_readToken() {
74
+ const token = fs.readFileSync(__classPrivateFieldGet(this, _EKSWorkloadIdentity_tokenFilePath, "f"), "utf-8").trim();
75
+ if (!token) {
76
+ throw new Error(`EKSWorkloadIdentity: token file is empty: ${__classPrivateFieldGet(this, _EKSWorkloadIdentity_tokenFilePath, "f")}`);
77
+ }
78
+ return token;
79
+ };
80
+ //# sourceMappingURL=eksWorkloadIdentity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eksWorkloadIdentity.js","sourceRoot":"","sources":["../../../src/server/eksWorkloadIdentity.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAI9B,MAAM,oBAAoB,GAAG;IAC3B,0CAA0C;IAC1C,wCAAwC;IACxC,6BAA6B;CAC9B,CAAC;AAOF;;;;;;;;GAQG;AACH,MAAM,OAAO,mBAAmB;IAG9B,YAAY,OAAoC;;QAFhD,qDAAuB;QAGrB,IAAI,OAAO,EAAE,aAAa,EAAE,CAAC;YAC3B,uBAAA,IAAI,sCAAkB,OAAO,CAAC,aAAa,MAAA,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,MAAM,QAAQ,GAAG,OAAO,EAAE,UAAU;gBAClC,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,GAAG,oBAAoB,CAAC;gBAC/C,CAAC,CAAC,oBAAoB,CAAC;YACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YACzD,IAAI,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;gBAClC,MAAM,IAAI,KAAK,CACb,gFAAgF;oBAChF,YAAY,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAClC,CAAC;YACJ,CAAC;YACD,uBAAA,IAAI,sCAAkB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAE,MAAA,CAAC;QAC5C,CAAC;QACD,uBAAA,IAAI,8EAAmB,MAAvB,IAAI,CAAqB,CAAC;IAC5B,CAAC;IAED,OAAO;QACL,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,2BAA2B,CAC/B,YAAoB,EACpB,QAAgB;QAEhB,OAAO;YACL,YAAY;YACZ,QAAQ;YACR,gBAAgB,EAAE,+CAA+C;YACjE,mBAAmB,EAAE,wDAAwD;YAC7E,eAAe,EAAE,uBAAA,IAAI,sEAAW,MAAf,IAAI,CAAa;SACnC,CAAC;IACJ,CAAC;CAuBF;;IApBG,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,uBAAA,IAAI,0CAAe,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACnE,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,6CAA6C,uBAAA,IAAI,0CAAe,EAAE,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,sBAAsB,CAAC;YAAE,MAAM,KAAK,CAAC;QAC5F,MAAM,IAAI,KAAK,CACb,kDAAkD,uBAAA,IAAI,0CAAe,MAAM,KAAK,EAAE,CACnF,CAAC;IACJ,CAAC;AACH,CAAC;IAGC,MAAM,KAAK,GAAG,EAAE,CAAC,YAAY,CAAC,uBAAA,IAAI,0CAAe,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACnE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,6CAA6C,uBAAA,IAAI,0CAAe,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -5,4 +5,10 @@ export { TokenVerifier } from "./tokenVerifier.js";
5
5
  export type { TokenVerifierOptions } from "./tokenVerifier.js";
6
6
  export { ClientSecret } from "./clientSecret.js";
7
7
  export type { ClientSecretCredentials } from "./clientSecret.js";
8
+ export { FilePrivateKeyStorage, PrivateKeyManager } from "./privateKey.js";
9
+ export type { PrivateKeyStorage, JsonWebKey } from "./privateKey.js";
10
+ export { WebIdentity } from "./webIdentity.js";
11
+ export type { WebIdentityOptions } from "./webIdentity.js";
12
+ export { EKSWorkloadIdentity } from "./eksWorkloadIdentity.js";
13
+ export type { EKSWorkloadIdentityOptions } from "./eksWorkloadIdentity.js";
8
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,YAAY,EAAE,0BAA0B,EAAE,MAAM,0BAA0B,CAAC"}
@@ -1,4 +1,7 @@
1
1
  export { AccessContext } from "./accessContext.js";
2
2
  export { TokenVerifier } from "./tokenVerifier.js";
3
3
  export { ClientSecret } from "./clientSecret.js";
4
+ export { FilePrivateKeyStorage, PrivateKeyManager } from "./privateKey.js";
5
+ export { WebIdentity } from "./webIdentity.js";
6
+ export { EKSWorkloadIdentity } from "./eksWorkloadIdentity.js";
4
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEjD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAE3E,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,47 @@
1
+ export interface JsonWebKey {
2
+ kty: string;
3
+ alg?: string;
4
+ use?: string;
5
+ kid?: string;
6
+ n?: string;
7
+ e?: string;
8
+ [key: string]: unknown;
9
+ }
10
+ export interface PrivateKeyStorage {
11
+ exists(keyId: string): Promise<boolean>;
12
+ storeKeyPair(keyId: string, privateKeyPem: string, publicKeyJwk: JsonWebKey): Promise<void>;
13
+ loadKeyPair(keyId: string): Promise<{
14
+ privateKeyPem: string;
15
+ publicKeyJwk: JsonWebKey;
16
+ }>;
17
+ deleteKeyPair(keyId: string): Promise<boolean>;
18
+ listKeyIds(): Promise<string[]>;
19
+ }
20
+ export declare class FilePrivateKeyStorage implements PrivateKeyStorage {
21
+ #private;
22
+ constructor(storageDir: string);
23
+ exists(keyId: string): Promise<boolean>;
24
+ storeKeyPair(keyId: string, privateKeyPem: string, publicKeyJwk: JsonWebKey): Promise<void>;
25
+ loadKeyPair(keyId: string): Promise<{
26
+ privateKeyPem: string;
27
+ publicKeyJwk: JsonWebKey;
28
+ }>;
29
+ deleteKeyPair(keyId: string): Promise<boolean>;
30
+ listKeyIds(): Promise<string[]>;
31
+ }
32
+ export declare class PrivateKeyManager {
33
+ #private;
34
+ constructor(options: {
35
+ storage: PrivateKeyStorage;
36
+ keyId?: string;
37
+ audienceConfig?: string | Record<string, string>;
38
+ });
39
+ bootstrapIdentity(): Promise<void>;
40
+ createClientAssertion(issuer: string, audience: string, expirySeconds?: number): Promise<string>;
41
+ getPublicJwks(): {
42
+ keys: JsonWebKey[];
43
+ };
44
+ getClientId(): string;
45
+ getClientJwksUrl(resourceServerUrl: string): string;
46
+ }
47
+ //# sourceMappingURL=privateKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"privateKey.d.ts","sourceRoot":"","sources":["../../../src/server/privateKey.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5F,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;IACzF,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;CACjC;AAMD,qBAAa,qBAAsB,YAAW,iBAAiB;;gBAGjD,UAAU,EAAE,MAAM;IAIxB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAUvC,YAAY,CAChB,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,UAAU,GACvB,OAAO,CAAC,IAAI,CAAC;IAeV,WAAW,CACf,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,UAAU,CAAA;KAAE,CAAC;IASzD,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAO9C,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAqBtC;AAMD,qBAAa,iBAAiB;;gBAOhB,OAAO,EAAE;QACnB,OAAO,EAAE,iBAAiB,CAAC;QAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAClD;IAMK,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAUlC,qBAAqB,CACzB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,aAAa,SAAM,GAClB,OAAO,CAAC,MAAM,CAAC;IAiBlB,aAAa,IAAI;QAAE,IAAI,EAAE,UAAU,EAAE,CAAA;KAAE;IAOvC,WAAW,IAAI,MAAM;IAIrB,gBAAgB,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM;CA0BpD"}
@@ -0,0 +1,195 @@
1
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
+ if (kind === "m") throw new TypeError("Private method is not writable");
3
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
+ };
7
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
+ };
12
+ var _FilePrivateKeyStorage_instances, _FilePrivateKeyStorage_storageDir, _FilePrivateKeyStorage_keyPath, _FilePrivateKeyStorage_metadataPath, _PrivateKeyManager_instances, _PrivateKeyManager_storage, _PrivateKeyManager_keyId, _PrivateKeyManager_audienceConfig, _PrivateKeyManager_privateKeyPem, _PrivateKeyManager_publicKeyJwk, _PrivateKeyManager_generateAndStoreKeyPair, _PemPrivateKeyring_pem, _PemPrivateKeyring_kid, _PemPrivateKeyring_issuer;
13
+ import * as crypto from "node:crypto";
14
+ import * as fs from "node:fs/promises";
15
+ import * as path from "node:path";
16
+ import { JWTSigner } from "../jwt/signer.js";
17
+ // =============================================================================
18
+ // File-Based Storage
19
+ // =============================================================================
20
+ export class FilePrivateKeyStorage {
21
+ constructor(storageDir) {
22
+ _FilePrivateKeyStorage_instances.add(this);
23
+ _FilePrivateKeyStorage_storageDir.set(this, void 0);
24
+ __classPrivateFieldSet(this, _FilePrivateKeyStorage_storageDir, storageDir, "f");
25
+ }
26
+ async exists(keyId) {
27
+ try {
28
+ await fs.access(__classPrivateFieldGet(this, _FilePrivateKeyStorage_instances, "m", _FilePrivateKeyStorage_keyPath).call(this, keyId));
29
+ await fs.access(__classPrivateFieldGet(this, _FilePrivateKeyStorage_instances, "m", _FilePrivateKeyStorage_metadataPath).call(this, keyId));
30
+ return true;
31
+ }
32
+ catch {
33
+ return false;
34
+ }
35
+ }
36
+ async storeKeyPair(keyId, privateKeyPem, publicKeyJwk) {
37
+ await fs.mkdir(__classPrivateFieldGet(this, _FilePrivateKeyStorage_storageDir, "f"), { recursive: true });
38
+ const metadata = {
39
+ key_id: keyId,
40
+ public_key_jwk: publicKeyJwk,
41
+ created_at: Date.now() / 1000,
42
+ algorithm: "RS256",
43
+ };
44
+ await fs.writeFile(__classPrivateFieldGet(this, _FilePrivateKeyStorage_instances, "m", _FilePrivateKeyStorage_keyPath).call(this, keyId), privateKeyPem, { encoding: "utf-8", mode: 0o600 });
45
+ await fs.writeFile(__classPrivateFieldGet(this, _FilePrivateKeyStorage_instances, "m", _FilePrivateKeyStorage_metadataPath).call(this, keyId), JSON.stringify(metadata, null, 2), {
46
+ encoding: "utf-8",
47
+ mode: 0o644,
48
+ });
49
+ }
50
+ async loadKeyPair(keyId) {
51
+ const [privateKeyPem, metadataRaw] = await Promise.all([
52
+ fs.readFile(__classPrivateFieldGet(this, _FilePrivateKeyStorage_instances, "m", _FilePrivateKeyStorage_keyPath).call(this, keyId), "utf-8"),
53
+ fs.readFile(__classPrivateFieldGet(this, _FilePrivateKeyStorage_instances, "m", _FilePrivateKeyStorage_metadataPath).call(this, keyId), "utf-8"),
54
+ ]);
55
+ const metadata = JSON.parse(metadataRaw);
56
+ return { privateKeyPem, publicKeyJwk: metadata.public_key_jwk };
57
+ }
58
+ async deleteKeyPair(keyId) {
59
+ let deleted = false;
60
+ try {
61
+ await fs.unlink(__classPrivateFieldGet(this, _FilePrivateKeyStorage_instances, "m", _FilePrivateKeyStorage_keyPath).call(this, keyId));
62
+ deleted = true;
63
+ }
64
+ catch { /* ignore */ }
65
+ try {
66
+ await fs.unlink(__classPrivateFieldGet(this, _FilePrivateKeyStorage_instances, "m", _FilePrivateKeyStorage_metadataPath).call(this, keyId));
67
+ deleted = true;
68
+ }
69
+ catch { /* ignore */ }
70
+ return deleted;
71
+ }
72
+ async listKeyIds() {
73
+ try {
74
+ const files = await fs.readdir(__classPrivateFieldGet(this, _FilePrivateKeyStorage_storageDir, "f"));
75
+ const keyIds = [];
76
+ for (const file of files.filter((f) => f.endsWith(".json"))) {
77
+ const keyId = file.replace(/\.json$/, "");
78
+ if (await this.exists(keyId))
79
+ keyIds.push(keyId);
80
+ }
81
+ return keyIds.sort();
82
+ }
83
+ catch {
84
+ return [];
85
+ }
86
+ }
87
+ }
88
+ _FilePrivateKeyStorage_storageDir = new WeakMap(), _FilePrivateKeyStorage_instances = new WeakSet(), _FilePrivateKeyStorage_keyPath = function _FilePrivateKeyStorage_keyPath(keyId) {
89
+ return path.join(__classPrivateFieldGet(this, _FilePrivateKeyStorage_storageDir, "f"), `${keyId}.pem`);
90
+ }, _FilePrivateKeyStorage_metadataPath = function _FilePrivateKeyStorage_metadataPath(keyId) {
91
+ return path.join(__classPrivateFieldGet(this, _FilePrivateKeyStorage_storageDir, "f"), `${keyId}.json`);
92
+ };
93
+ // =============================================================================
94
+ // Private Key Manager
95
+ // =============================================================================
96
+ export class PrivateKeyManager {
97
+ constructor(options) {
98
+ _PrivateKeyManager_instances.add(this);
99
+ _PrivateKeyManager_storage.set(this, void 0);
100
+ _PrivateKeyManager_keyId.set(this, void 0);
101
+ _PrivateKeyManager_audienceConfig.set(this, void 0);
102
+ _PrivateKeyManager_privateKeyPem.set(this, void 0);
103
+ _PrivateKeyManager_publicKeyJwk.set(this, void 0);
104
+ __classPrivateFieldSet(this, _PrivateKeyManager_storage, options.storage, "f");
105
+ __classPrivateFieldSet(this, _PrivateKeyManager_keyId, options.keyId ?? crypto.randomUUID(), "f");
106
+ __classPrivateFieldSet(this, _PrivateKeyManager_audienceConfig, options.audienceConfig, "f");
107
+ }
108
+ async bootstrapIdentity() {
109
+ if (await __classPrivateFieldGet(this, _PrivateKeyManager_storage, "f").exists(__classPrivateFieldGet(this, _PrivateKeyManager_keyId, "f"))) {
110
+ const { privateKeyPem, publicKeyJwk } = await __classPrivateFieldGet(this, _PrivateKeyManager_storage, "f").loadKeyPair(__classPrivateFieldGet(this, _PrivateKeyManager_keyId, "f"));
111
+ __classPrivateFieldSet(this, _PrivateKeyManager_privateKeyPem, privateKeyPem, "f");
112
+ __classPrivateFieldSet(this, _PrivateKeyManager_publicKeyJwk, publicKeyJwk, "f");
113
+ }
114
+ else {
115
+ await __classPrivateFieldGet(this, _PrivateKeyManager_instances, "m", _PrivateKeyManager_generateAndStoreKeyPair).call(this);
116
+ }
117
+ }
118
+ async createClientAssertion(issuer, audience, expirySeconds = 300) {
119
+ if (!__classPrivateFieldGet(this, _PrivateKeyManager_privateKeyPem, "f") || !__classPrivateFieldGet(this, _PrivateKeyManager_publicKeyJwk, "f")) {
120
+ throw new Error("Identity not bootstrapped. Call bootstrapIdentity() first.");
121
+ }
122
+ const keyring = new PemPrivateKeyring(__classPrivateFieldGet(this, _PrivateKeyManager_privateKeyPem, "f"), __classPrivateFieldGet(this, _PrivateKeyManager_keyId, "f"), issuer);
123
+ const signer = new JWTSigner(keyring);
124
+ const now = Math.floor(Date.now() / 1000);
125
+ return signer.sign({
126
+ iss: issuer,
127
+ sub: issuer,
128
+ aud: audience,
129
+ jti: crypto.randomUUID(),
130
+ iat: now,
131
+ exp: now + expirySeconds,
132
+ });
133
+ }
134
+ getPublicJwks() {
135
+ if (!__classPrivateFieldGet(this, _PrivateKeyManager_publicKeyJwk, "f")) {
136
+ throw new Error("Identity not bootstrapped. Call bootstrapIdentity() first.");
137
+ }
138
+ return { keys: [__classPrivateFieldGet(this, _PrivateKeyManager_publicKeyJwk, "f")] };
139
+ }
140
+ getClientId() {
141
+ return __classPrivateFieldGet(this, _PrivateKeyManager_keyId, "f");
142
+ }
143
+ getClientJwksUrl(resourceServerUrl) {
144
+ const url = new URL(resourceServerUrl);
145
+ return `${url.protocol}//${url.host}/.well-known/jwks.json`;
146
+ }
147
+ }
148
+ _PrivateKeyManager_storage = new WeakMap(), _PrivateKeyManager_keyId = new WeakMap(), _PrivateKeyManager_audienceConfig = new WeakMap(), _PrivateKeyManager_privateKeyPem = new WeakMap(), _PrivateKeyManager_publicKeyJwk = new WeakMap(), _PrivateKeyManager_instances = new WeakSet(), _PrivateKeyManager_generateAndStoreKeyPair = async function _PrivateKeyManager_generateAndStoreKeyPair() {
149
+ const keyPair = crypto.generateKeyPairSync("rsa", {
150
+ modulusLength: 2048,
151
+ publicKeyEncoding: { type: "spki", format: "pem" },
152
+ privateKeyEncoding: { type: "pkcs8", format: "pem" },
153
+ });
154
+ const privateKeyPem = String(keyPair.privateKey);
155
+ const publicKeyObj = crypto.createPublicKey(String(keyPair.publicKey));
156
+ const jwk = publicKeyObj.export({ format: "jwk" });
157
+ const publicKeyJwk = {
158
+ kty: jwk.kty,
159
+ n: jwk.n,
160
+ e: jwk.e,
161
+ kid: __classPrivateFieldGet(this, _PrivateKeyManager_keyId, "f"),
162
+ alg: "RS256",
163
+ use: "sig",
164
+ };
165
+ await __classPrivateFieldGet(this, _PrivateKeyManager_storage, "f").storeKeyPair(__classPrivateFieldGet(this, _PrivateKeyManager_keyId, "f"), privateKeyPem, publicKeyJwk);
166
+ __classPrivateFieldSet(this, _PrivateKeyManager_privateKeyPem, privateKeyPem, "f");
167
+ __classPrivateFieldSet(this, _PrivateKeyManager_publicKeyJwk, publicKeyJwk, "f");
168
+ };
169
+ // =============================================================================
170
+ // PEM-based PrivateKeyring adapter (implements PrivateKeyring from @keycardai/oauth)
171
+ // =============================================================================
172
+ class PemPrivateKeyring {
173
+ constructor(pem, kid, issuer) {
174
+ _PemPrivateKeyring_pem.set(this, void 0);
175
+ _PemPrivateKeyring_kid.set(this, void 0);
176
+ _PemPrivateKeyring_issuer.set(this, void 0);
177
+ __classPrivateFieldSet(this, _PemPrivateKeyring_pem, pem, "f");
178
+ __classPrivateFieldSet(this, _PemPrivateKeyring_kid, kid, "f");
179
+ __classPrivateFieldSet(this, _PemPrivateKeyring_issuer, issuer, "f");
180
+ }
181
+ async key(_usage) {
182
+ const keyObj = crypto.createPrivateKey(__classPrivateFieldGet(this, _PemPrivateKeyring_pem, "f"));
183
+ const jwk = keyObj.export({ format: "jwk" });
184
+ const cryptoKey = await crypto.subtle.importKey("jwk", jwk, { name: "RSASSA-PKCS1-v1_5", hash: { name: "SHA-256" } }, false, ["sign"]);
185
+ return {
186
+ // node:crypto.webcrypto.CryptoKey and global CryptoKey are identical at
187
+ // runtime; the declaration split is a TypeScript-only artefact.
188
+ key: cryptoKey,
189
+ kid: __classPrivateFieldGet(this, _PemPrivateKeyring_kid, "f"),
190
+ issuer: __classPrivateFieldGet(this, _PemPrivateKeyring_issuer, "f"),
191
+ };
192
+ }
193
+ }
194
+ _PemPrivateKeyring_pem = new WeakMap(), _PemPrivateKeyring_kid = new WeakMap(), _PemPrivateKeyring_issuer = new WeakMap();
195
+ //# sourceMappingURL=privateKey.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"privateKey.js","sourceRoot":"","sources":["../../../src/server/privateKey.ts"],"names":[],"mappings":"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"}