@slashfi/agents-sdk 0.24.2 → 0.24.4

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 (66) hide show
  1. package/dist/cjs/agent-definitions/auth.js +678 -0
  2. package/dist/cjs/agent-definitions/auth.js.map +1 -0
  3. package/dist/cjs/agent-definitions/integrations.js +1173 -0
  4. package/dist/cjs/agent-definitions/integrations.js.map +1 -0
  5. package/dist/cjs/agent-definitions/remote-registry.js +469 -0
  6. package/dist/cjs/agent-definitions/remote-registry.js.map +1 -0
  7. package/dist/cjs/agent-definitions/secrets.js +193 -0
  8. package/dist/cjs/agent-definitions/secrets.js.map +1 -0
  9. package/dist/cjs/agent-definitions/users.js +440 -0
  10. package/dist/cjs/agent-definitions/users.js.map +1 -0
  11. package/dist/cjs/build.js +162 -0
  12. package/dist/cjs/build.js.map +1 -0
  13. package/dist/cjs/callback/index.js +74 -0
  14. package/dist/cjs/callback/index.js.map +1 -0
  15. package/dist/cjs/client.js +193 -0
  16. package/dist/cjs/client.js.map +1 -0
  17. package/dist/cjs/codegen.js +1027 -0
  18. package/dist/cjs/codegen.js.map +1 -0
  19. package/dist/cjs/crypto.js +44 -0
  20. package/dist/cjs/crypto.js.map +1 -0
  21. package/dist/cjs/define-config.js +81 -0
  22. package/dist/cjs/define-config.js.map +1 -0
  23. package/dist/cjs/define.js +186 -0
  24. package/dist/cjs/define.js.map +1 -0
  25. package/dist/cjs/events.js +60 -0
  26. package/dist/cjs/events.js.map +1 -0
  27. package/dist/cjs/index.js +195 -0
  28. package/dist/cjs/index.js.map +1 -0
  29. package/dist/cjs/integration-interface.js +105 -0
  30. package/dist/cjs/integration-interface.js.map +1 -0
  31. package/dist/cjs/integrations-store.js +53 -0
  32. package/dist/cjs/integrations-store.js.map +1 -0
  33. package/dist/cjs/introspect.js +136 -0
  34. package/dist/cjs/introspect.js.map +1 -0
  35. package/dist/cjs/jsonc.js +74 -0
  36. package/dist/cjs/jsonc.js.map +1 -0
  37. package/dist/cjs/jwt.js +207 -0
  38. package/dist/cjs/jwt.js.map +1 -0
  39. package/dist/cjs/key-manager.js +161 -0
  40. package/dist/cjs/key-manager.js.map +1 -0
  41. package/dist/cjs/oidc-signin.js +141 -0
  42. package/dist/cjs/oidc-signin.js.map +1 -0
  43. package/dist/cjs/pack.js +256 -0
  44. package/dist/cjs/pack.js.map +1 -0
  45. package/dist/cjs/package.json +1 -0
  46. package/dist/cjs/registry-consumer.js +233 -0
  47. package/dist/cjs/registry-consumer.js.map +1 -0
  48. package/dist/cjs/registry.js +512 -0
  49. package/dist/cjs/registry.js.map +1 -0
  50. package/dist/cjs/secret-collection.js +42 -0
  51. package/dist/cjs/secret-collection.js.map +1 -0
  52. package/dist/cjs/serialized.js +45 -0
  53. package/dist/cjs/serialized.js.map +1 -0
  54. package/dist/cjs/server.js +974 -0
  55. package/dist/cjs/server.js.map +1 -0
  56. package/dist/cjs/test-utils/mock-oidc-server.js +99 -0
  57. package/dist/cjs/test-utils/mock-oidc-server.js.map +1 -0
  58. package/dist/cjs/types.js +8 -0
  59. package/dist/cjs/types.js.map +1 -0
  60. package/dist/cjs/validate.js +84 -0
  61. package/dist/cjs/validate.js.map +1 -0
  62. package/dist/registry-consumer.d.ts.map +1 -1
  63. package/dist/registry-consumer.js +1 -1
  64. package/dist/registry-consumer.js.map +1 -1
  65. package/package.json +13 -5
  66. package/src/registry-consumer.ts +3 -1
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ /**
3
+ * JWT utilities for auth tokens.
4
+ *
5
+ * Supports two modes:
6
+ * - ES256 (asymmetric) — for production / cross-registry trust
7
+ * - HS256 (HMAC) — for backward compat / simple single-server setups
8
+ *
9
+ * Uses `jose` library for all crypto operations.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.generateSigningKey = generateSigningKey;
13
+ exports.exportSigningKey = exportSigningKey;
14
+ exports.importSigningKey = importSigningKey;
15
+ exports.buildJwks = buildJwks;
16
+ exports.signJwtES256 = signJwtES256;
17
+ exports.verifyJwtLocal = verifyJwtLocal;
18
+ exports.verifyJwtFromIssuer = verifyJwtFromIssuer;
19
+ exports.signJwt = signJwt;
20
+ exports.verifyJwt = verifyJwt;
21
+ const jose_1 = require("jose");
22
+ // ============================================
23
+ // Key Generation
24
+ // ============================================
25
+ /**
26
+ * Generate a new ES256 signing key pair.
27
+ */
28
+ async function generateSigningKey(kid) {
29
+ const { privateKey, publicKey } = await (0, jose_1.generateKeyPair)("ES256", {
30
+ extractable: true,
31
+ });
32
+ return {
33
+ kid: kid ?? `key-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
34
+ privateKey,
35
+ publicKey,
36
+ alg: "ES256",
37
+ status: "active",
38
+ createdAt: Date.now(),
39
+ };
40
+ }
41
+ /**
42
+ * Export a signing key to JWK format (for storage).
43
+ */
44
+ async function exportSigningKey(key) {
45
+ const privateKeyJwk = await (0, jose_1.exportJWK)(key.privateKey);
46
+ const publicKeyJwk = await (0, jose_1.exportJWK)(key.publicKey);
47
+ return {
48
+ kid: key.kid,
49
+ alg: key.alg,
50
+ privateKeyJwk,
51
+ publicKeyJwk,
52
+ status: key.status,
53
+ createdAt: key.createdAt,
54
+ };
55
+ }
56
+ /**
57
+ * Import a signing key from stored JWK format.
58
+ */
59
+ async function importSigningKey(exported) {
60
+ const privateKey = (await (0, jose_1.importJWK)(exported.privateKeyJwk, exported.alg));
61
+ const publicKey = (await (0, jose_1.importJWK)(exported.publicKeyJwk, exported.alg));
62
+ return {
63
+ kid: exported.kid,
64
+ privateKey,
65
+ publicKey,
66
+ alg: exported.alg,
67
+ status: exported.status,
68
+ createdAt: exported.createdAt,
69
+ };
70
+ }
71
+ /**
72
+ * Build a JWKS (JSON Web Key Set) from signing keys.
73
+ * Only includes public keys.
74
+ */
75
+ async function buildJwks(keys) {
76
+ const jwks = [];
77
+ for (const key of keys) {
78
+ if (key.status === "revoked")
79
+ continue;
80
+ const jwk = await (0, jose_1.exportJWK)(key.publicKey);
81
+ jwk.kid = key.kid;
82
+ jwk.alg = key.alg;
83
+ jwk.use = "sig";
84
+ jwks.push(jwk);
85
+ }
86
+ return { keys: jwks };
87
+ }
88
+ // ============================================
89
+ // Signing (ES256)
90
+ // ============================================
91
+ /**
92
+ * Sign a JWT with ES256 using the server's private key.
93
+ */
94
+ async function signJwtES256(payload, privateKey, kid, issuer, expiresIn) {
95
+ let builder = new jose_1.SignJWT(payload)
96
+ .setProtectedHeader({ alg: "ES256", kid })
97
+ .setIssuedAt();
98
+ if (issuer)
99
+ builder = builder.setIssuer(issuer);
100
+ if (payload.sub)
101
+ builder = builder.setSubject(payload.sub);
102
+ if (expiresIn) {
103
+ builder = builder.setExpirationTime(expiresIn);
104
+ }
105
+ else if (payload.exp) {
106
+ builder = builder.setExpirationTime(payload.exp);
107
+ }
108
+ else {
109
+ builder = builder.setExpirationTime("1h");
110
+ }
111
+ return builder.sign(privateKey);
112
+ }
113
+ // ============================================
114
+ // Verification
115
+ // ============================================
116
+ /**
117
+ * Verify a JWT against a local public key.
118
+ */
119
+ async function verifyJwtLocal(token, publicKey) {
120
+ try {
121
+ const { payload } = await (0, jose_1.jwtVerify)(token, publicKey);
122
+ return payload;
123
+ }
124
+ catch {
125
+ return null;
126
+ }
127
+ }
128
+ /** JWKS cache for remote issuers */
129
+ const jwksCache = new Map();
130
+ /**
131
+ * Verify a JWT against a remote issuer's JWKS.
132
+ * Fetches and caches the JWKS from the issuer's /.well-known/jwks.json
133
+ */
134
+ async function verifyJwtFromIssuer(token, issuerUrl) {
135
+ try {
136
+ const jwksUrl = `${issuerUrl.replace(/\/$/, "")}/.well-known/jwks.json`;
137
+ let jwks = jwksCache.get(jwksUrl);
138
+ if (!jwks) {
139
+ jwks = (0, jose_1.createRemoteJWKSet)(new URL(jwksUrl));
140
+ jwksCache.set(jwksUrl, jwks);
141
+ }
142
+ const { payload } = await (0, jose_1.jwtVerify)(token, jwks);
143
+ return payload;
144
+ }
145
+ catch {
146
+ return null;
147
+ }
148
+ }
149
+ // ============================================
150
+ // Legacy HMAC (backward compat)
151
+ // ============================================
152
+ const encoder = new TextEncoder();
153
+ function base64UrlEncode(data) {
154
+ const str = btoa(String.fromCharCode(...data));
155
+ return str.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
156
+ }
157
+ function base64UrlDecode(str) {
158
+ const padded = str.replace(/-/g, "+").replace(/_/g, "/");
159
+ const binary = atob(padded);
160
+ return Uint8Array.from(binary, (c) => c.charCodeAt(0));
161
+ }
162
+ async function hmacSign(data, secret) {
163
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
164
+ const sig = await crypto.subtle.sign("HMAC", key, encoder.encode(data));
165
+ return new Uint8Array(sig);
166
+ }
167
+ async function hmacVerify(data, signature, secret) {
168
+ const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
169
+ return crypto.subtle.verify("HMAC", key, signature.buffer, encoder.encode(data));
170
+ }
171
+ /**
172
+ * Sign a JWT with HMAC-SHA256 (legacy).
173
+ * @deprecated Use signJwtES256 for new code.
174
+ */
175
+ async function signJwt(payload, secret) {
176
+ const header = { alg: "HS256", typ: "JWT" };
177
+ const headerB64 = base64UrlEncode(encoder.encode(JSON.stringify(header)));
178
+ const payloadB64 = base64UrlEncode(encoder.encode(JSON.stringify(payload)));
179
+ const signingInput = `${headerB64}.${payloadB64}`;
180
+ const signature = await hmacSign(signingInput, secret);
181
+ return `${signingInput}.${base64UrlEncode(signature)}`;
182
+ }
183
+ /**
184
+ * Verify and decode a JWT (HMAC-SHA256, legacy).
185
+ * @deprecated Use verifyJwtLocal or verifyJwtFromIssuer for new code.
186
+ */
187
+ async function verifyJwt(token, secret) {
188
+ const parts = token.split(".");
189
+ if (parts.length !== 3)
190
+ return null;
191
+ const [headerB64, payloadB64, signatureB64] = parts;
192
+ const signingInput = `${headerB64}.${payloadB64}`;
193
+ try {
194
+ const signature = base64UrlDecode(signatureB64);
195
+ const valid = await hmacVerify(signingInput, signature, secret);
196
+ if (!valid)
197
+ return null;
198
+ const payload = JSON.parse(new TextDecoder().decode(base64UrlDecode(payloadB64)));
199
+ if (payload.exp && payload.exp < Date.now() / 1000)
200
+ return null;
201
+ return payload;
202
+ }
203
+ catch {
204
+ return null;
205
+ }
206
+ }
207
+ //# sourceMappingURL=jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/jwt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ /**
3
+ * JWKS Key Manager
4
+ *
5
+ * Manages ES256 signing keys with automatic rotation and revocation.
6
+ * Store-agnostic — provide a KeyStore implementation for your DB.
7
+ *
8
+ * Features:
9
+ * - Automatic key rotation on a configurable schedule
10
+ * - Key lifecycle: active → deprecated → revoked → cleaned up
11
+ * - Multi-instance safe: checks DB before rotating (another instance may have already rotated)
12
+ * - Periodic background checks (configurable interval)
13
+ * - Exposes JWKS for /.well-known/jwks.json
14
+ * - Signs JWTs with the active key
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.createKeyManager = createKeyManager;
18
+ const jose_1 = require("jose");
19
+ // ── Constants ──
20
+ const FIVE_MINUTES = 5 * 60 * 1000;
21
+ const ONE_HOUR = 60 * 60 * 1000;
22
+ const TWO_HOURS = 2 * ONE_HOUR;
23
+ const ALG = "ES256";
24
+ // ── Key generation ──
25
+ function generateKid() {
26
+ return `key-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
27
+ }
28
+ async function generateNewKey(keyLifetimeMs) {
29
+ const { privateKey, publicKey } = await (0, jose_1.generateKeyPair)(ALG, {
30
+ extractable: true,
31
+ });
32
+ const kid = generateKid();
33
+ const publicJwk = await (0, jose_1.exportJWK)(publicKey);
34
+ publicJwk.kid = kid;
35
+ publicJwk.alg = ALG;
36
+ publicJwk.use = "sig";
37
+ const privateJwk = await (0, jose_1.exportJWK)(privateKey);
38
+ privateJwk.kid = kid;
39
+ privateJwk.alg = ALG;
40
+ return {
41
+ kid,
42
+ alg: ALG,
43
+ status: "active",
44
+ publicJwk,
45
+ privateJwk,
46
+ createdAt: new Date(),
47
+ expiresAt: new Date(Date.now() + keyLifetimeMs),
48
+ };
49
+ }
50
+ async function toCachedKey(stored) {
51
+ const privateKey = (await (0, jose_1.importJWK)(stored.privateJwk, ALG));
52
+ return { ...stored, privateKey };
53
+ }
54
+ // ── Key Manager ──
55
+ async function createKeyManager(opts) {
56
+ const { store, issuer, checkIntervalMs = FIVE_MINUTES, rotationThresholdMs = ONE_HOUR, keyLifetimeMs = TWO_HOURS, tokenTtlSeconds = 300, enableRotation = true, } = opts;
57
+ let keys = [];
58
+ /** Generate a new key, deprecate old ones, cleanup expired, refresh cache — all in one transaction */
59
+ async function rotate() {
60
+ await store.transaction(async () => {
61
+ const newKey = await generateNewKey(keyLifetimeMs);
62
+ await store.deprecateAllActive();
63
+ await store.insertKey(newKey);
64
+ await store.cleanupExpired();
65
+ const updated = await store.loadKeys();
66
+ keys = await Promise.all(updated.map(toCachedKey));
67
+ });
68
+ }
69
+ /** Check if rotation is needed and rotate if so — all within a single transaction */
70
+ async function checkAndRotate() {
71
+ // Quick check against cache — no DB/store hit if key is fresh
72
+ const cached = keys.find((k) => k.status === "active");
73
+ if (cached) {
74
+ const age = Date.now() - cached.createdAt.getTime();
75
+ if (age < rotationThresholdMs)
76
+ return;
77
+ }
78
+ // Cache says stale (or empty) — take a lock via transaction to check + rotate atomically
79
+ await store.transaction(async () => {
80
+ const stored = await store.loadKeys();
81
+ const active = stored.find((k) => k.status === "active");
82
+ if (active) {
83
+ const age = Date.now() - active.createdAt.getTime();
84
+ if (age < rotationThresholdMs) {
85
+ // Another instance already rotated — just update our cache
86
+ keys = await Promise.all(stored.map(toCachedKey));
87
+ return;
88
+ }
89
+ }
90
+ // Still stale (or no active key) — rotate within this tx
91
+ const newKey = await generateNewKey(keyLifetimeMs);
92
+ await store.deprecateAllActive();
93
+ await store.insertKey(newKey);
94
+ await store.cleanupExpired();
95
+ // Refresh cache inside the tx for a consistent read
96
+ const updated = await store.loadKeys();
97
+ keys = await Promise.all(updated.map(toCachedKey));
98
+ });
99
+ }
100
+ // Initial load + ensure we have at least one key
101
+ // Initial load from store
102
+ const stored = await store.loadKeys();
103
+ keys = await Promise.all(stored.map(toCachedKey));
104
+ if (!keys.some((k) => k.status === "active")) {
105
+ if (enableRotation) {
106
+ await rotate();
107
+ }
108
+ else {
109
+ // Read-only mode: generate a key in memory only (no store writes)
110
+ // This ensures signJwt works even without rotation enabled
111
+ const newKey = await generateNewKey(keyLifetimeMs);
112
+ keys.push(await toCachedKey(newKey));
113
+ }
114
+ }
115
+ else if (enableRotation) {
116
+ await checkAndRotate();
117
+ }
118
+ // Periodic background check (only if rotation enabled)
119
+ const interval = enableRotation
120
+ ? setInterval(async () => {
121
+ try {
122
+ await checkAndRotate();
123
+ }
124
+ catch (err) {
125
+ console.error("[key-manager] Check/rotation failed:", err);
126
+ }
127
+ }, checkIntervalMs)
128
+ : null;
129
+ function getActiveKey() {
130
+ const active = keys.find((k) => k.status === "active");
131
+ if (!active)
132
+ throw new Error("[key-manager] No active signing key");
133
+ return active;
134
+ }
135
+ return {
136
+ getJwks() {
137
+ return {
138
+ keys: keys
139
+ .filter((k) => k.status !== "revoked")
140
+ .map((k) => k.publicJwk),
141
+ };
142
+ },
143
+ async signJwt(claims) {
144
+ const key = getActiveKey();
145
+ return new jose_1.SignJWT({ ...claims })
146
+ .setProtectedHeader({ alg: ALG, kid: key.kid })
147
+ .setIssuer(issuer)
148
+ .setIssuedAt()
149
+ .setExpirationTime(`${tokenTtlSeconds}s`)
150
+ .sign(key.privateKey);
151
+ },
152
+ async rotate() {
153
+ await rotate();
154
+ },
155
+ stop() {
156
+ if (interval)
157
+ clearInterval(interval);
158
+ },
159
+ };
160
+ }
161
+ //# sourceMappingURL=key-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"key-manager.js","sourceRoot":"","sources":["../../src/key-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ /**
3
+ * OIDC Sign-In Provider
4
+ *
5
+ * Implements the full OIDC authorization code flow for user sign-in.
6
+ * The server acts as an OIDC Relying Party — users authenticate with
7
+ * an external Identity Provider and receive a server-signed JWT.
8
+ *
9
+ * Flow:
10
+ * GET /signin/authorize → 302 redirect to IdP
11
+ * GET /signin/callback → exchange code → fetch userinfo → sign JWT → return
12
+ */
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.createOIDCSignIn = createOIDCSignIn;
15
+ const jwt_js_1 = require("./jwt.js");
16
+ function createOIDCSignIn(config) {
17
+ let discoveryCache = null;
18
+ const pendingFlows = new Map();
19
+ async function fetchDiscovery() {
20
+ if (discoveryCache)
21
+ return discoveryCache;
22
+ const url = `${config.issuer}/.well-known/openid-configuration`;
23
+ const res = await fetch(url);
24
+ if (!res.ok)
25
+ throw new Error(`OIDC discovery failed: ${res.status}`);
26
+ discoveryCache = (await res.json());
27
+ return discoveryCache;
28
+ }
29
+ function generateState() {
30
+ const bytes = crypto.getRandomValues(new Uint8Array(24));
31
+ return Buffer.from(bytes).toString("base64url");
32
+ }
33
+ return {
34
+ async handleRequest(req, { baseUrl, signingKey, issuerUrl }) {
35
+ const url = new URL(req.url);
36
+ // ── GET /signin/authorize → redirect to IdP ──
37
+ if (url.pathname === "/signin/authorize" && req.method === "GET") {
38
+ const redirectUri = url.searchParams.get("redirect_uri") ?? "";
39
+ if (!redirectUri) {
40
+ return Response.json({
41
+ error: "invalid_request",
42
+ error_description: "Missing redirect_uri",
43
+ }, { status: 400 });
44
+ }
45
+ const discovery = await fetchDiscovery();
46
+ const state = generateState();
47
+ const nonce = generateState();
48
+ pendingFlows.set(state, {
49
+ redirectUri,
50
+ nonce,
51
+ createdAt: Date.now(),
52
+ });
53
+ // Clean up stale flows (> 10 min)
54
+ const now = Date.now();
55
+ for (const [k, v] of pendingFlows) {
56
+ if (now - v.createdAt > 600_000)
57
+ pendingFlows.delete(k);
58
+ }
59
+ const scopes = config.scopes ?? ["openid", "email", "profile"];
60
+ const callbackUrl = `${baseUrl}/signin/callback`;
61
+ const authUrl = new URL(discovery.authorization_endpoint);
62
+ authUrl.searchParams.set("response_type", "code");
63
+ authUrl.searchParams.set("client_id", config.clientId);
64
+ authUrl.searchParams.set("redirect_uri", callbackUrl);
65
+ authUrl.searchParams.set("scope", scopes.join(" "));
66
+ authUrl.searchParams.set("state", state);
67
+ authUrl.searchParams.set("nonce", nonce);
68
+ return Response.redirect(authUrl.toString(), 302);
69
+ }
70
+ // ── GET /signin/callback → exchange code → userinfo → JWT ──
71
+ if (url.pathname === "/signin/callback" && req.method === "GET") {
72
+ const code = url.searchParams.get("code");
73
+ const state = url.searchParams.get("state");
74
+ const error = url.searchParams.get("error");
75
+ if (error) {
76
+ return Response.json({
77
+ error,
78
+ error_description: url.searchParams.get("error_description") ?? "",
79
+ }, { status: 400 });
80
+ }
81
+ if (!code || !state) {
82
+ return Response.json({
83
+ error: "invalid_request",
84
+ error_description: "Missing code or state",
85
+ }, { status: 400 });
86
+ }
87
+ const flow = pendingFlows.get(state);
88
+ if (!flow) {
89
+ return Response.json({
90
+ error: "invalid_state",
91
+ error_description: "Unknown or expired state",
92
+ }, { status: 400 });
93
+ }
94
+ pendingFlows.delete(state);
95
+ const discovery = await fetchDiscovery();
96
+ const callbackUrl = `${baseUrl}/signin/callback`;
97
+ // Exchange code for tokens
98
+ const tokenRes = await fetch(discovery.token_endpoint, {
99
+ method: "POST",
100
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
101
+ body: new URLSearchParams({
102
+ grant_type: "authorization_code",
103
+ code,
104
+ redirect_uri: callbackUrl,
105
+ client_id: config.clientId,
106
+ client_secret: config.clientSecret,
107
+ }),
108
+ });
109
+ if (!tokenRes.ok) {
110
+ const text = await tokenRes.text();
111
+ return Response.json({ error: "token_exchange_failed", error_description: text }, { status: 502 });
112
+ }
113
+ const tokens = (await tokenRes.json());
114
+ // Fetch userinfo
115
+ const userinfoRes = await fetch(discovery.userinfo_endpoint, {
116
+ headers: { Authorization: `Bearer ${tokens.access_token}` },
117
+ });
118
+ if (!userinfoRes.ok) {
119
+ return Response.json({
120
+ error: "userinfo_failed",
121
+ error_description: `Status ${userinfoRes.status}`,
122
+ }, { status: 502 });
123
+ }
124
+ const userinfo = (await userinfoRes.json());
125
+ // Sign server JWT with user's identity
126
+ const jwt = await (0, jwt_js_1.signJwtES256)({
127
+ sub: userinfo.sub ?? "unknown",
128
+ name: userinfo.name ?? "unknown",
129
+ scopes: ["*"],
130
+ iss: issuerUrl,
131
+ }, signingKey.privateKey, signingKey.kid, issuerUrl, "1h");
132
+ // Redirect back to the caller with the JWT
133
+ const sep = flow.redirectUri.includes("?") ? "&" : "?";
134
+ return Response.redirect(`${flow.redirectUri}${sep}token=${jwt}`, 302);
135
+ }
136
+ // Not a signin route
137
+ return null;
138
+ },
139
+ };
140
+ }
141
+ //# sourceMappingURL=oidc-signin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oidc-signin.js","sourceRoot":"","sources":["../../src/oidc-signin.ts"],"names":[],"mappings":"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"}