@pontive/pontkit-server 1.2.1 → 1.3.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.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +201 -179
- package/dist/index.js.map +1 -1
- package/dist/oidc.d.ts +7 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jwtVerify as
|
|
2
|
-
const
|
|
3
|
-
function
|
|
1
|
+
import { jwtVerify as R, createLocalJWKSet as Q, jwtDecrypt as q, EncryptJWT as ee } from "jose";
|
|
2
|
+
const v = 3500, $ = 16;
|
|
3
|
+
function U(t) {
|
|
4
4
|
const e = /* @__PURE__ */ new Map();
|
|
5
5
|
if (!t) return e;
|
|
6
6
|
for (const r of t.split(";")) {
|
|
@@ -11,122 +11,122 @@ function S(t) {
|
|
|
11
11
|
}
|
|
12
12
|
return e;
|
|
13
13
|
}
|
|
14
|
-
function
|
|
14
|
+
function L(t) {
|
|
15
15
|
return [...t].map(([e, r]) => `${e}=${r}`).join("; ");
|
|
16
16
|
}
|
|
17
|
-
function
|
|
17
|
+
function b(t, e, r) {
|
|
18
18
|
const n = [`${t}=${e}`, "Path=/", "HttpOnly", "SameSite=Lax", `Max-Age=${r.maxAge}`];
|
|
19
19
|
return r.secure && n.push("Secure"), n.join("; ");
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function C(t, e) {
|
|
22
22
|
return e === 0 ? t : `${t}.${e}`;
|
|
23
23
|
}
|
|
24
|
-
function
|
|
24
|
+
function te(t, e) {
|
|
25
25
|
const r = t.get(e);
|
|
26
26
|
if (r === void 0) return null;
|
|
27
27
|
let n = r;
|
|
28
|
-
for (let s = 1; s <
|
|
29
|
-
const a = t.get(
|
|
28
|
+
for (let s = 1; s < $; s++) {
|
|
29
|
+
const a = t.get(C(e, s));
|
|
30
30
|
if (a === void 0) break;
|
|
31
31
|
n += a;
|
|
32
32
|
}
|
|
33
33
|
return n;
|
|
34
34
|
}
|
|
35
|
-
function
|
|
36
|
-
const s = [], a = Math.max(1, Math.ceil(r.length /
|
|
35
|
+
function re(t, e, r, n) {
|
|
36
|
+
const s = [], a = Math.max(1, Math.ceil(r.length / v));
|
|
37
37
|
for (let c = 0; c < a; c++) {
|
|
38
|
-
const
|
|
39
|
-
t.set(
|
|
38
|
+
const u = r.slice(c * v, (c + 1) * v);
|
|
39
|
+
t.set(C(e, c), u), s.push(b(C(e, c), u, n));
|
|
40
40
|
}
|
|
41
|
-
for (let c = a; c <
|
|
42
|
-
const
|
|
43
|
-
if (!t.has(
|
|
44
|
-
t.delete(
|
|
41
|
+
for (let c = a; c < $; c++) {
|
|
42
|
+
const u = C(e, c);
|
|
43
|
+
if (!t.has(u)) break;
|
|
44
|
+
t.delete(u), s.push(b(u, "", { ...n, maxAge: 0 }));
|
|
45
45
|
}
|
|
46
46
|
return s;
|
|
47
47
|
}
|
|
48
|
-
function
|
|
48
|
+
function M(t, e, r) {
|
|
49
49
|
const n = [];
|
|
50
|
-
for (let s = 0; s <
|
|
51
|
-
const a =
|
|
50
|
+
for (let s = 0; s < $; s++) {
|
|
51
|
+
const a = C(e, s);
|
|
52
52
|
if (!t.has(a)) {
|
|
53
53
|
if (s > 0) break;
|
|
54
54
|
continue;
|
|
55
55
|
}
|
|
56
|
-
t.delete(a), n.push(
|
|
56
|
+
t.delete(a), n.push(b(a, "", { maxAge: 0, secure: r }));
|
|
57
57
|
}
|
|
58
58
|
return n;
|
|
59
59
|
}
|
|
60
|
-
class
|
|
60
|
+
class K extends Error {
|
|
61
61
|
constructor(e, r, n) {
|
|
62
62
|
super(`token endpoint ${e} ${r}: ${n}`), this.status = e, this.code = r;
|
|
63
63
|
}
|
|
64
64
|
status;
|
|
65
65
|
code;
|
|
66
66
|
}
|
|
67
|
-
const
|
|
68
|
-
function
|
|
67
|
+
const ne = 600 * 1e3, T = /* @__PURE__ */ new Map(), N = /* @__PURE__ */ new Map();
|
|
68
|
+
function se(t) {
|
|
69
69
|
return t.replace(/\/+$/, "");
|
|
70
70
|
}
|
|
71
|
-
function
|
|
72
|
-
const r =
|
|
73
|
-
let n =
|
|
71
|
+
function x(t, e) {
|
|
72
|
+
const r = se(t);
|
|
73
|
+
let n = T.get(r);
|
|
74
74
|
return n || (n = e(`${r}/.well-known/openid-configuration`).then(async (s) => {
|
|
75
75
|
if (!s.ok) throw new Error(`OIDC discovery failed for ${r}: ${s.status}`);
|
|
76
76
|
return await s.json();
|
|
77
77
|
}).catch((s) => {
|
|
78
|
-
throw
|
|
79
|
-
}),
|
|
78
|
+
throw T.delete(r), s;
|
|
79
|
+
}), T.set(r, n)), n;
|
|
80
80
|
}
|
|
81
|
-
async function
|
|
82
|
-
const n =
|
|
83
|
-
if (n && !r && Date.now() - n.at <
|
|
81
|
+
async function H(t, e, r) {
|
|
82
|
+
const n = N.get(t);
|
|
83
|
+
if (n && !r && Date.now() - n.at < ne) return n.set;
|
|
84
84
|
const s = await e(t);
|
|
85
85
|
if (!s.ok) throw new Error(`JWKS fetch failed for ${t}: ${s.status}`);
|
|
86
|
-
const a =
|
|
87
|
-
return
|
|
86
|
+
const a = Q(await s.json());
|
|
87
|
+
return N.set(t, { at: Date.now(), set: a }), a;
|
|
88
88
|
}
|
|
89
|
-
function
|
|
89
|
+
function V(t) {
|
|
90
90
|
let e = "";
|
|
91
91
|
for (const r of t) e += String.fromCharCode(r);
|
|
92
92
|
return btoa(e).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
93
93
|
}
|
|
94
|
-
function
|
|
95
|
-
return
|
|
94
|
+
function I() {
|
|
95
|
+
return V(crypto.getRandomValues(new Uint8Array(32)));
|
|
96
96
|
}
|
|
97
|
-
async function
|
|
97
|
+
async function oe(t) {
|
|
98
98
|
const e = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(t));
|
|
99
|
-
return
|
|
99
|
+
return V(new Uint8Array(e));
|
|
100
100
|
}
|
|
101
|
-
async function
|
|
101
|
+
async function J(t) {
|
|
102
102
|
return [...new Uint8Array(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(t)))].map((r) => r.toString(16).padStart(2, "0")).join("");
|
|
103
103
|
}
|
|
104
104
|
async function ie(t, e, r) {
|
|
105
|
-
const n = await
|
|
105
|
+
const n = await x(t.issuer, e), s = new URL(n.authorization_endpoint);
|
|
106
106
|
return s.searchParams.set("response_type", "code"), s.searchParams.set("client_id", t.clientId), s.searchParams.set("redirect_uri", r.redirectUri), s.searchParams.set("scope", r.scopes), s.searchParams.set("state", r.state), s.searchParams.set("nonce", r.nonce), s.searchParams.set("code_challenge", r.codeChallenge), s.searchParams.set("code_challenge_method", "S256"), r.prompt && s.searchParams.set("prompt", r.prompt), s.toString();
|
|
107
107
|
}
|
|
108
|
-
async function
|
|
109
|
-
const n = await
|
|
108
|
+
async function z(t, e, r) {
|
|
109
|
+
const n = await x(t.issuer, e), s = new URLSearchParams(r);
|
|
110
110
|
s.set("client_id", t.clientId);
|
|
111
111
|
const a = { "content-type": "application/x-www-form-urlencoded" };
|
|
112
112
|
if (t.clientSecret) {
|
|
113
|
-
const
|
|
114
|
-
a.authorization = `Basic ${btoa(
|
|
113
|
+
const u = `${encodeURIComponent(t.clientId)}:${encodeURIComponent(t.clientSecret)}`;
|
|
114
|
+
a.authorization = `Basic ${btoa(u)}`;
|
|
115
115
|
}
|
|
116
116
|
const c = await e(n.token_endpoint, { method: "POST", headers: a, body: s });
|
|
117
117
|
if (!c.ok) {
|
|
118
|
-
let
|
|
118
|
+
let u = "unknown_error", h = "";
|
|
119
119
|
try {
|
|
120
|
-
const
|
|
121
|
-
|
|
120
|
+
const f = await c.json();
|
|
121
|
+
u = f.error ?? u, h = f.error_description ?? "";
|
|
122
122
|
} catch {
|
|
123
123
|
}
|
|
124
|
-
throw new
|
|
124
|
+
throw new K(c.status, u, h);
|
|
125
125
|
}
|
|
126
126
|
return await c.json();
|
|
127
127
|
}
|
|
128
128
|
function ae(t, e, r) {
|
|
129
|
-
return
|
|
129
|
+
return z(t, e, {
|
|
130
130
|
grant_type: "authorization_code",
|
|
131
131
|
code: r.code,
|
|
132
132
|
code_verifier: r.codeVerifier,
|
|
@@ -134,33 +134,40 @@ function ae(t, e, r) {
|
|
|
134
134
|
});
|
|
135
135
|
}
|
|
136
136
|
function ce(t, e, r) {
|
|
137
|
-
return
|
|
137
|
+
return z(t, e, { grant_type: "refresh_token", refresh_token: r });
|
|
138
138
|
}
|
|
139
|
-
async function
|
|
140
|
-
const n = await
|
|
139
|
+
async function G(t, e, r) {
|
|
140
|
+
const n = await x(t.issuer, e), s = { issuer: n.issuer, audience: t.clientId };
|
|
141
141
|
try {
|
|
142
|
-
return (await
|
|
142
|
+
return (await R(r, await H(n.jwks_uri, e, !1), s)).payload;
|
|
143
143
|
} catch (a) {
|
|
144
144
|
if (a.code !== "ERR_JWKS_NO_MATCHING_KEY") throw a;
|
|
145
|
-
return (await
|
|
145
|
+
return (await R(r, await H(n.jwks_uri, e, !0), s)).payload;
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
async function ue(t, e, r, n) {
|
|
149
|
-
const s = await
|
|
149
|
+
const s = await G(t, e, r);
|
|
150
150
|
if (s.nonce !== n) throw new Error("id_token nonce does not match the sign-in request");
|
|
151
151
|
return s;
|
|
152
152
|
}
|
|
153
153
|
async function de(t, e, r) {
|
|
154
|
-
const n = await
|
|
154
|
+
const n = await x(t.issuer, e);
|
|
155
|
+
if (!n.userinfo_endpoint) return null;
|
|
156
|
+
const s = await e(n.userinfo_endpoint, { headers: { authorization: `Bearer ${r}` } });
|
|
157
|
+
if (!s.ok) throw new Error(`userinfo ${s.status}`);
|
|
158
|
+
return await s.json();
|
|
159
|
+
}
|
|
160
|
+
async function le(t, e, r) {
|
|
161
|
+
const n = await x(t.issuer, e);
|
|
155
162
|
if (!n.end_session_endpoint) return null;
|
|
156
163
|
const s = new URL(n.end_session_endpoint);
|
|
157
164
|
return s.searchParams.set("client_id", t.clientId), s.searchParams.set("post_logout_redirect_uri", r.postLogoutRedirectUri), r.sessionId && s.searchParams.set("logout_hint", r.sessionId), s.toString();
|
|
158
165
|
}
|
|
159
|
-
const
|
|
160
|
-
function
|
|
166
|
+
const he = "__Host-pontive_access", fe = "__Secure-pontive_session_state";
|
|
167
|
+
function we(t) {
|
|
161
168
|
const e = (r) => typeof t[r] == "string" ? t[r] : void 0;
|
|
162
169
|
return {
|
|
163
|
-
id:
|
|
170
|
+
id: e("sub") ?? "",
|
|
164
171
|
email: e("email"),
|
|
165
172
|
name: e("name") ?? e("email"),
|
|
166
173
|
username: e("preferred_username"),
|
|
@@ -168,22 +175,37 @@ function fe(t) {
|
|
|
168
175
|
emailVerified: t.email_verified === !0
|
|
169
176
|
};
|
|
170
177
|
}
|
|
171
|
-
function
|
|
172
|
-
const e = { issuer: t.issuer, clientId: t.clientId };
|
|
173
|
-
|
|
174
|
-
const
|
|
175
|
-
|
|
176
|
-
|
|
178
|
+
function pe(t) {
|
|
179
|
+
const e = { issuer: t.issuer, clientId: t.clientId }, r = /* @__PURE__ */ new Map();
|
|
180
|
+
function n(c) {
|
|
181
|
+
for (const [u, h] of r)
|
|
182
|
+
h.expiresAt <= c && r.delete(u);
|
|
183
|
+
}
|
|
184
|
+
async function s(c, u) {
|
|
185
|
+
const h = Date.now();
|
|
186
|
+
n(h);
|
|
187
|
+
const f = await J(c), w = r.get(f);
|
|
188
|
+
if (w) return w.profile;
|
|
189
|
+
const p = de(e, t.fetch, c).catch((E) => (r.delete(f), t.logger.warn("[pontive] could not read the user's profile:", E instanceof Error ? E.message : String(E)), null));
|
|
190
|
+
return r.set(f, { expiresAt: u, profile: p }), p;
|
|
191
|
+
}
|
|
192
|
+
async function a(c) {
|
|
193
|
+
const u = U(c).get(he);
|
|
194
|
+
if (!u) return null;
|
|
195
|
+
let h;
|
|
177
196
|
try {
|
|
178
|
-
|
|
179
|
-
} catch (
|
|
180
|
-
return
|
|
197
|
+
h = await G(e, t.fetch, u);
|
|
198
|
+
} catch (p) {
|
|
199
|
+
return p.code !== "ERR_JWT_EXPIRED" && t.logger.warn("[pontive] access token cookie refused:", p instanceof Error ? p.message : String(p)), null;
|
|
181
200
|
}
|
|
201
|
+
const f = (h.exp ?? 0) * 1e3, w = await s(u, f);
|
|
182
202
|
return {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
203
|
+
// The token's own claims win for sub: the profile describes the user the
|
|
204
|
+
// token names, never another one.
|
|
205
|
+
user: we({ ...w, ...h, sub: h.sub }),
|
|
206
|
+
accessToken: u,
|
|
207
|
+
expiresAt: f,
|
|
208
|
+
sessionId: typeof h.sid == "string" ? h.sid : void 0
|
|
187
209
|
};
|
|
188
210
|
}
|
|
189
211
|
return {
|
|
@@ -191,17 +213,17 @@ function we(t) {
|
|
|
191
213
|
async handle() {
|
|
192
214
|
return null;
|
|
193
215
|
},
|
|
194
|
-
getSession:
|
|
195
|
-
async refresh(
|
|
196
|
-
const
|
|
197
|
-
if (
|
|
198
|
-
const
|
|
199
|
-
return
|
|
216
|
+
getSession: a,
|
|
217
|
+
async refresh(c) {
|
|
218
|
+
const u = c.headers.get("cookie"), h = await a(u), f = { session: h, setCookies: [], cookieHeader: u ?? "" };
|
|
219
|
+
if (h || !U(u).has(fe)) return f;
|
|
220
|
+
const w = new URL(c.url), p = new URL(`${t.authPath}/oauth2/session`, w.origin);
|
|
221
|
+
return p.searchParams.set("client_id", t.clientId), p.searchParams.set("return_to", w.pathname + w.search), { ...f, handshake: p.pathname + p.search };
|
|
200
222
|
}
|
|
201
223
|
};
|
|
202
224
|
}
|
|
203
|
-
const
|
|
204
|
-
function
|
|
225
|
+
const ge = 10080 * 60;
|
|
226
|
+
function ke(t) {
|
|
205
227
|
const e = t.clientSecret ? "server" : "browser", r = ["issuer", "clientId"];
|
|
206
228
|
e === "server" && r.push("sessionSecret");
|
|
207
229
|
for (const n of r)
|
|
@@ -230,22 +252,22 @@ function ge(t) {
|
|
|
230
252
|
prompt: t.prompt,
|
|
231
253
|
cookieName: t.cookieName ?? "pontive_session",
|
|
232
254
|
secureCookies: t.secureCookies,
|
|
233
|
-
sessionMaxAgeSeconds: t.sessionMaxAgeSeconds ??
|
|
255
|
+
sessionMaxAgeSeconds: t.sessionMaxAgeSeconds ?? ge,
|
|
234
256
|
refreshSkewSeconds: t.refreshSkewSeconds ?? 60,
|
|
235
257
|
fetch: t.fetch ?? ((...n) => fetch(...n)),
|
|
236
258
|
logger: t.logger ?? console
|
|
237
259
|
};
|
|
238
260
|
}
|
|
239
|
-
const
|
|
240
|
-
class
|
|
241
|
-
constructor(e =
|
|
261
|
+
const me = 3e4;
|
|
262
|
+
class Se {
|
|
263
|
+
constructor(e = me) {
|
|
242
264
|
this.recentMs = e;
|
|
243
265
|
}
|
|
244
266
|
recentMs;
|
|
245
267
|
inFlight = /* @__PURE__ */ new Map();
|
|
246
268
|
recent = /* @__PURE__ */ new Map();
|
|
247
269
|
async run(e, r) {
|
|
248
|
-
const n = await
|
|
270
|
+
const n = await J(e);
|
|
249
271
|
this.sweep();
|
|
250
272
|
const s = this.recent.get(n);
|
|
251
273
|
if (s) return s.result;
|
|
@@ -258,32 +280,32 @@ class me {
|
|
|
258
280
|
n.at < e && this.recent.delete(r);
|
|
259
281
|
}
|
|
260
282
|
}
|
|
261
|
-
const
|
|
262
|
-
function
|
|
263
|
-
let e =
|
|
264
|
-
return e || (e = crypto.subtle.digest("SHA-256", new TextEncoder().encode(t)).then((r) => new Uint8Array(r)),
|
|
283
|
+
const D = /* @__PURE__ */ new Map();
|
|
284
|
+
function B(t) {
|
|
285
|
+
let e = D.get(t);
|
|
286
|
+
return e || (e = crypto.subtle.digest("SHA-256", new TextEncoder().encode(t)).then((r) => new Uint8Array(r)), D.set(t, e)), e;
|
|
265
287
|
}
|
|
266
|
-
async function
|
|
267
|
-
return new
|
|
288
|
+
async function O(t, e, r) {
|
|
289
|
+
return new ee(t).setProtectedHeader({ alg: "dir", enc: "A256GCM" }).setIssuedAt().setExpirationTime(`${r}s`).encrypt(await B(e));
|
|
268
290
|
}
|
|
269
|
-
async function
|
|
291
|
+
async function j(t, e) {
|
|
270
292
|
try {
|
|
271
|
-
const { payload: r } = await
|
|
293
|
+
const { payload: r } = await q(t, await B(e));
|
|
272
294
|
return r;
|
|
273
295
|
} catch {
|
|
274
296
|
return null;
|
|
275
297
|
}
|
|
276
298
|
}
|
|
277
|
-
const
|
|
278
|
-
function
|
|
299
|
+
const _e = 900, W = 600;
|
|
300
|
+
function ye(t, e) {
|
|
279
301
|
return t && t.startsWith("/") && !t.startsWith("//") && !t.startsWith("/\\") ? t : e;
|
|
280
302
|
}
|
|
281
|
-
function
|
|
303
|
+
function y(t, e = []) {
|
|
282
304
|
const r = new Headers({ location: t, "cache-control": "no-store" });
|
|
283
305
|
for (const n of e) r.append("set-cookie", n);
|
|
284
306
|
return new Response(null, { status: 302, headers: r });
|
|
285
307
|
}
|
|
286
|
-
function
|
|
308
|
+
function P(t, e) {
|
|
287
309
|
if (t.baseUrl) return t.baseUrl;
|
|
288
310
|
const r = e.headers.get("x-forwarded-host")?.split(",")[0]?.trim() || e.headers.get("host")?.trim();
|
|
289
311
|
if (r) {
|
|
@@ -295,7 +317,7 @@ function E(t, e) {
|
|
|
295
317
|
}
|
|
296
318
|
return new URL(e.url).origin;
|
|
297
319
|
}
|
|
298
|
-
function
|
|
320
|
+
function Ue(t) {
|
|
299
321
|
const e = (n) => typeof t[n] == "string" ? t[n] : void 0, r = e("name") ?? ([e("given_name"), e("family_name")].filter(Boolean).join(" ") || void 0) ?? e("email");
|
|
300
322
|
return {
|
|
301
323
|
id: t.sub ?? "",
|
|
@@ -306,86 +328,86 @@ function ye(t) {
|
|
|
306
328
|
emailVerified: t.email_verified === !0
|
|
307
329
|
};
|
|
308
330
|
}
|
|
309
|
-
function
|
|
310
|
-
return Date.now() + (t.expires_in ??
|
|
331
|
+
function F(t) {
|
|
332
|
+
return Date.now() + (t.expires_in ?? _e) * 1e3;
|
|
311
333
|
}
|
|
312
334
|
function Ce(t) {
|
|
313
|
-
const e =
|
|
314
|
-
if (e.mode === "browser") return
|
|
315
|
-
const r = { issuer: e.issuer, clientId: e.clientId, clientSecret: e.clientSecret }, n = `${e.cookieName}_tx`, s = new
|
|
316
|
-
const
|
|
317
|
-
return i &&
|
|
335
|
+
const e = ke(t);
|
|
336
|
+
if (e.mode === "browser") return pe(e);
|
|
337
|
+
const r = { issuer: e.issuer, clientId: e.clientId, clientSecret: e.clientSecret }, n = `${e.cookieName}_tx`, s = new Se(), a = (o) => e.secureCookies ?? P(e, o).startsWith("https:"), c = (o) => e.redirectUri ?? `${P(e, o)}${e.basePath}/callback`, u = (o, i) => {
|
|
338
|
+
const d = new URL(e.signInPath, P(e, o));
|
|
339
|
+
return i && d.searchParams.set("error", i), d.toString();
|
|
318
340
|
};
|
|
319
341
|
async function h(o) {
|
|
320
|
-
const i =
|
|
342
|
+
const i = te(o, e.cookieName);
|
|
321
343
|
if (i === null) return null;
|
|
322
|
-
const
|
|
323
|
-
return
|
|
344
|
+
const d = await j(i, e.sessionSecret);
|
|
345
|
+
return d || e.logger.warn("[pontive] session cookie could not be read (sealed with another secret, or truncated)"), d;
|
|
324
346
|
}
|
|
325
|
-
async function
|
|
326
|
-
const l = await
|
|
327
|
-
return
|
|
347
|
+
async function f(o, i, d) {
|
|
348
|
+
const l = await O({ ...i }, e.sessionSecret, e.sessionMaxAgeSeconds);
|
|
349
|
+
return re(o, e.cookieName, l, { maxAge: e.sessionMaxAgeSeconds, secure: a(d) });
|
|
328
350
|
}
|
|
329
|
-
function
|
|
330
|
-
const { refreshToken: i, ...
|
|
331
|
-
return
|
|
351
|
+
function w(o) {
|
|
352
|
+
const { refreshToken: i, ...d } = o;
|
|
353
|
+
return d;
|
|
332
354
|
}
|
|
333
|
-
async function
|
|
334
|
-
const i = new URL(o.url),
|
|
335
|
-
state:
|
|
336
|
-
verifier:
|
|
337
|
-
nonce:
|
|
338
|
-
returnTo:
|
|
355
|
+
async function p(o) {
|
|
356
|
+
const i = new URL(o.url), d = {
|
|
357
|
+
state: I(),
|
|
358
|
+
verifier: I(),
|
|
359
|
+
nonce: I(),
|
|
360
|
+
returnTo: ye(i.searchParams.get("returnTo") ?? i.searchParams.get("next"), e.afterSignInPath)
|
|
339
361
|
}, l = await ie(r, e.fetch, {
|
|
340
362
|
redirectUri: c(o),
|
|
341
363
|
scopes: e.scopes,
|
|
342
|
-
state:
|
|
343
|
-
nonce:
|
|
344
|
-
codeChallenge: await
|
|
364
|
+
state: d.state,
|
|
365
|
+
nonce: d.nonce,
|
|
366
|
+
codeChallenge: await oe(d.verifier),
|
|
345
367
|
prompt: e.prompt
|
|
346
|
-
}),
|
|
347
|
-
return
|
|
368
|
+
}), g = await O({ ...d }, e.sessionSecret, W);
|
|
369
|
+
return y(l, [b(n, g, { maxAge: W, secure: a(o) })]);
|
|
348
370
|
}
|
|
349
|
-
async function
|
|
350
|
-
const i = new URL(o.url),
|
|
351
|
-
if (
|
|
352
|
-
const
|
|
353
|
-
if (!
|
|
354
|
-
return
|
|
371
|
+
async function E(o) {
|
|
372
|
+
const i = new URL(o.url), d = U(o.headers.get("cookie")), l = [b(n, "", { maxAge: 0, secure: a(o) })], g = i.searchParams.get("error");
|
|
373
|
+
if (g) return y(u(o, g), l);
|
|
374
|
+
const k = d.get(n), _ = k ? await j(k, e.sessionSecret) : null, m = i.searchParams.get("code");
|
|
375
|
+
if (!_ || !m || i.searchParams.get("state") !== _.state)
|
|
376
|
+
return y(u(o, "invalid_state"), l);
|
|
355
377
|
try {
|
|
356
|
-
const
|
|
357
|
-
code:
|
|
358
|
-
codeVerifier:
|
|
378
|
+
const S = await ae(r, e.fetch, {
|
|
379
|
+
code: m,
|
|
380
|
+
codeVerifier: _.verifier,
|
|
359
381
|
redirectUri: c(o)
|
|
360
382
|
});
|
|
361
|
-
if (!
|
|
362
|
-
const
|
|
363
|
-
user:
|
|
364
|
-
accessToken:
|
|
365
|
-
refreshToken:
|
|
366
|
-
expiresAt:
|
|
367
|
-
sessionId: typeof
|
|
383
|
+
if (!S.id_token) throw new Error("the token response carried no id_token; is the openid scope requested?");
|
|
384
|
+
const A = await ue(r, e.fetch, S.id_token, _.nonce), Z = {
|
|
385
|
+
user: Ue(A),
|
|
386
|
+
accessToken: S.access_token,
|
|
387
|
+
refreshToken: S.refresh_token,
|
|
388
|
+
expiresAt: F(S),
|
|
389
|
+
sessionId: typeof A.sid == "string" ? A.sid : void 0
|
|
368
390
|
};
|
|
369
|
-
l.push(...await
|
|
370
|
-
} catch (
|
|
371
|
-
return e.logger.warn("[pontive] sign-in failed:",
|
|
391
|
+
l.push(...await f(d, Z, o));
|
|
392
|
+
} catch (S) {
|
|
393
|
+
return e.logger.warn("[pontive] sign-in failed:", S instanceof Error ? S.message : String(S)), y(u(o, "exchange_failed"), l);
|
|
372
394
|
}
|
|
373
|
-
return
|
|
395
|
+
return y(new URL(_.returnTo, P(e, o)).toString(), l);
|
|
374
396
|
}
|
|
375
|
-
async function
|
|
376
|
-
const i =
|
|
377
|
-
let
|
|
397
|
+
async function X(o) {
|
|
398
|
+
const i = U(o.headers.get("cookie")), d = await h(i), l = M(i, e.cookieName, a(o));
|
|
399
|
+
let g = u(o);
|
|
378
400
|
try {
|
|
379
|
-
|
|
380
|
-
postLogoutRedirectUri:
|
|
381
|
-
sessionId:
|
|
382
|
-
}) ??
|
|
383
|
-
} catch (
|
|
384
|
-
e.logger.warn("[pontive] could not reach the issuer to end its session:",
|
|
401
|
+
g = await le(r, e.fetch, {
|
|
402
|
+
postLogoutRedirectUri: u(o),
|
|
403
|
+
sessionId: d?.sessionId
|
|
404
|
+
}) ?? g;
|
|
405
|
+
} catch (k) {
|
|
406
|
+
e.logger.warn("[pontive] could not reach the issuer to end its session:", k instanceof Error ? k.message : String(k));
|
|
385
407
|
}
|
|
386
|
-
return
|
|
408
|
+
return y(g, l);
|
|
387
409
|
}
|
|
388
|
-
async function
|
|
410
|
+
async function Y(o) {
|
|
389
411
|
try {
|
|
390
412
|
const i = await ce(r, e.fetch, o.refreshToken);
|
|
391
413
|
return {
|
|
@@ -393,10 +415,10 @@ function Ce(t) {
|
|
|
393
415
|
accessToken: i.access_token,
|
|
394
416
|
// A response without one means rotation is off: the token in hand is still current.
|
|
395
417
|
refreshToken: i.refresh_token ?? o.refreshToken,
|
|
396
|
-
expiresAt:
|
|
418
|
+
expiresAt: F(i)
|
|
397
419
|
};
|
|
398
420
|
} catch (i) {
|
|
399
|
-
if (i instanceof
|
|
421
|
+
if (i instanceof K && i.status >= 400 && i.status < 500)
|
|
400
422
|
return e.logger.warn("[pontive] refresh refused; signing out:", i.message), null;
|
|
401
423
|
throw i;
|
|
402
424
|
}
|
|
@@ -405,42 +427,42 @@ function Ce(t) {
|
|
|
405
427
|
async handle(o) {
|
|
406
428
|
const { pathname: i } = new URL(o.url);
|
|
407
429
|
if (!i.startsWith(`${e.basePath}/`)) return null;
|
|
408
|
-
const
|
|
409
|
-
return
|
|
430
|
+
const d = i.slice(e.basePath.length + 1);
|
|
431
|
+
return d === "login" && o.method === "GET" ? p(o) : d === "callback" && o.method === "GET" ? E(o) : d === "logout" && (o.method === "GET" || o.method === "POST") ? X(o) : null;
|
|
410
432
|
},
|
|
411
433
|
async getSession(o) {
|
|
412
|
-
const i = await h(
|
|
434
|
+
const i = await h(U(o));
|
|
413
435
|
return i ? Date.now() >= i.expiresAt ? (e.logger.warn(
|
|
414
436
|
"[pontive] the session's access token has expired and getSession cannot refresh it. Run the SDK's middleware on this path so it refreshes before the request is handled."
|
|
415
|
-
), null) :
|
|
437
|
+
), null) : w(i) : null;
|
|
416
438
|
},
|
|
417
439
|
async refresh(o) {
|
|
418
|
-
const i =
|
|
419
|
-
session:
|
|
440
|
+
const i = U(o.headers.get("cookie")), d = (m) => ({
|
|
441
|
+
session: m,
|
|
420
442
|
setCookies: [],
|
|
421
443
|
cookieHeader: o.headers.get("cookie") ?? ""
|
|
422
444
|
}), l = await h(i);
|
|
423
|
-
if (!l) return
|
|
445
|
+
if (!l) return d(null);
|
|
424
446
|
if (new URL(o.url).pathname.startsWith(`${e.basePath}/`))
|
|
425
|
-
return
|
|
426
|
-
if (Date.now() < l.expiresAt - e.refreshSkewSeconds * 1e3) return
|
|
427
|
-
const
|
|
428
|
-
if (!l.refreshToken) return
|
|
429
|
-
let
|
|
447
|
+
return d(Date.now() < l.expiresAt ? w(l) : null);
|
|
448
|
+
if (Date.now() < l.expiresAt - e.refreshSkewSeconds * 1e3) return d(w(l));
|
|
449
|
+
const g = () => ({ session: null, setCookies: M(i, e.cookieName, a(o)), cookieHeader: L(i) });
|
|
450
|
+
if (!l.refreshToken) return g();
|
|
451
|
+
let k;
|
|
430
452
|
try {
|
|
431
|
-
|
|
432
|
-
} catch (
|
|
433
|
-
return e.logger.warn("[pontive] refresh failed, will retry:",
|
|
453
|
+
k = await s.run(l.refreshToken, () => Y(l));
|
|
454
|
+
} catch (m) {
|
|
455
|
+
return e.logger.warn("[pontive] refresh failed, will retry:", m instanceof Error ? m.message : String(m)), d(Date.now() < l.expiresAt ? w(l) : null);
|
|
434
456
|
}
|
|
435
|
-
if (!
|
|
436
|
-
const
|
|
437
|
-
return { session:
|
|
457
|
+
if (!k) return g();
|
|
458
|
+
const _ = await f(i, k, o);
|
|
459
|
+
return { session: w(k), setCookies: _, cookieHeader: L(i) };
|
|
438
460
|
}
|
|
439
461
|
};
|
|
440
462
|
}
|
|
441
463
|
export {
|
|
442
|
-
|
|
443
|
-
|
|
464
|
+
he as ACCESS_COOKIE,
|
|
465
|
+
fe as SESSION_HINT_COOKIE,
|
|
444
466
|
Ce as createServerAuth
|
|
445
467
|
};
|
|
446
468
|
//# sourceMappingURL=index.js.map
|