@foldspace-fe/casdoor-next-auth-kit 0.1.1

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 (40) hide show
  1. package/dist/billing/index.d.ts +16 -0
  2. package/dist/billing/index.js +28 -0
  3. package/dist/billing/index.js.map +1 -0
  4. package/dist/callback-BTzHQK_r.d.ts +12 -0
  5. package/dist/casdoor/index.d.ts +28 -0
  6. package/dist/casdoor/index.js +40 -0
  7. package/dist/casdoor/index.js.map +1 -0
  8. package/dist/chunk-6E27SZ7V.js +291 -0
  9. package/dist/chunk-6E27SZ7V.js.map +1 -0
  10. package/dist/chunk-DONQHN4U.js +56 -0
  11. package/dist/chunk-DONQHN4U.js.map +1 -0
  12. package/dist/chunk-IQEVUR77.js +909 -0
  13. package/dist/chunk-IQEVUR77.js.map +1 -0
  14. package/dist/chunk-RGTVPBH7.js +182 -0
  15. package/dist/chunk-RGTVPBH7.js.map +1 -0
  16. package/dist/chunk-T2M5MVPE.js +20 -0
  17. package/dist/chunk-T2M5MVPE.js.map +1 -0
  18. package/dist/chunk-XMBHIEYL.js +1 -0
  19. package/dist/chunk-XMBHIEYL.js.map +1 -0
  20. package/dist/chunk-Y4GJ2AEI.js +192 -0
  21. package/dist/chunk-Y4GJ2AEI.js.map +1 -0
  22. package/dist/cli.d.ts +2 -0
  23. package/dist/cli.js +437 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/index.d.ts +77 -0
  26. package/dist/index.js +148 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/next/index.d.ts +17 -0
  29. package/dist/next/index.js +24 -0
  30. package/dist/next/index.js.map +1 -0
  31. package/dist/options-JUwZSXu2.d.ts +40 -0
  32. package/dist/react/index.d.ts +242 -0
  33. package/dist/react/index.js +774 -0
  34. package/dist/react/index.js.map +1 -0
  35. package/dist/skills/casdoor-next-auth-kit/SKILL.md +158 -0
  36. package/dist/skills/casdoor-next-auth-kit/references/casdoor-api-reference.md +2387 -0
  37. package/dist/skills/casdoor-next-auth-kit/references/swagger.json +3686 -0
  38. package/dist/types-BPsPs5Rv.d.ts +337 -0
  39. package/dist/types-DqVXdUge.d.ts +121 -0
  40. package/package.json +69 -0
@@ -0,0 +1,909 @@
1
+ import {
2
+ resolvePostLoginRedirect
3
+ } from "./chunk-T2M5MVPE.js";
4
+
5
+ // src/core/config.ts
6
+ function normalizeAuthKitConfig(config) {
7
+ return {
8
+ ...config,
9
+ casdoor: {
10
+ redirectPath: "/callback",
11
+ signinPath: "/login/oauth/authorize",
12
+ ...config.casdoor
13
+ },
14
+ cookie: {
15
+ secure: "auto",
16
+ ...config.cookie
17
+ },
18
+ session: {
19
+ maxAgeSeconds: 60 * 60 * 24 * 7,
20
+ ...config.session
21
+ }
22
+ };
23
+ }
24
+
25
+ // src/core/public-origin.ts
26
+ var PUBLIC_ORIGIN_COOKIE_NAME = "auth_origin";
27
+ function getRequestOrigin(request, appUrl) {
28
+ const referer = request.headers.get("referer");
29
+ if (referer) {
30
+ try {
31
+ return new URL(referer).origin;
32
+ } catch {
33
+ }
34
+ }
35
+ const origin = request.headers.get("origin");
36
+ if (origin) {
37
+ try {
38
+ return new URL(origin).origin;
39
+ } catch {
40
+ }
41
+ }
42
+ if (appUrl) {
43
+ try {
44
+ return new URL(appUrl).origin;
45
+ } catch {
46
+ }
47
+ }
48
+ const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
49
+ const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
50
+ if (forwardedProto && forwardedHost) {
51
+ return `${forwardedProto}://${forwardedHost}`;
52
+ }
53
+ return new URL(request.url).origin;
54
+ }
55
+ function setPublicOriginCookie(response, origin, secure) {
56
+ response.cookies.set(PUBLIC_ORIGIN_COOKIE_NAME, origin, {
57
+ path: "/",
58
+ httpOnly: true,
59
+ sameSite: "lax",
60
+ secure
61
+ });
62
+ }
63
+ function clearPublicOriginCookie(response, secure) {
64
+ response.cookies.set(PUBLIC_ORIGIN_COOKIE_NAME, "", {
65
+ path: "/",
66
+ httpOnly: true,
67
+ sameSite: "lax",
68
+ secure,
69
+ maxAge: 0
70
+ });
71
+ }
72
+ function getStoredPublicOrigin(request) {
73
+ const cookieHeader = request.headers.get("cookie");
74
+ if (!cookieHeader) {
75
+ return null;
76
+ }
77
+ for (const entry of cookieHeader.split(";")) {
78
+ const [rawName, ...valueParts] = entry.trim().split("=");
79
+ if (rawName === PUBLIC_ORIGIN_COOKIE_NAME) {
80
+ const value = valueParts.join("=").trim();
81
+ if (!value) {
82
+ return null;
83
+ }
84
+ try {
85
+ return decodeURIComponent(value);
86
+ } catch {
87
+ return value;
88
+ }
89
+ }
90
+ }
91
+ return null;
92
+ }
93
+
94
+ // src/core/request-security.ts
95
+ function isSecureRequest(request, appUrl) {
96
+ const url = new URL(request.url);
97
+ if (url.protocol === "https:") return true;
98
+ const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim().toLowerCase();
99
+ if (forwardedProto === "https") return true;
100
+ if (appUrl) {
101
+ try {
102
+ return new URL(appUrl).protocol === "https:";
103
+ } catch {
104
+ return false;
105
+ }
106
+ }
107
+ return false;
108
+ }
109
+
110
+ // src/core/auth-redirect.ts
111
+ var AUTH_REDIRECT_COOKIE_NAME = "auth_redirect";
112
+ function getAuthRedirectTarget(request) {
113
+ const cookieHeader = request.headers.get("cookie");
114
+ if (!cookieHeader) {
115
+ return null;
116
+ }
117
+ for (const entry of cookieHeader.split(";")) {
118
+ const [rawName, ...valueParts] = entry.trim().split("=");
119
+ if (rawName === AUTH_REDIRECT_COOKIE_NAME) {
120
+ const value = valueParts.join("=").trim();
121
+ if (!value) {
122
+ return null;
123
+ }
124
+ let decoded = value;
125
+ try {
126
+ decoded = decodeURIComponent(value);
127
+ } catch {
128
+ }
129
+ if (decoded.startsWith("/") && !decoded.startsWith("//")) {
130
+ return decoded;
131
+ }
132
+ return null;
133
+ }
134
+ }
135
+ return null;
136
+ }
137
+ function setAuthRedirectCookie(response, target, secure) {
138
+ response.cookies.set(AUTH_REDIRECT_COOKIE_NAME, target, {
139
+ path: "/",
140
+ httpOnly: true,
141
+ sameSite: "lax",
142
+ secure
143
+ });
144
+ }
145
+ function clearAuthRedirectCookie(response, secure) {
146
+ response.cookies.set(AUTH_REDIRECT_COOKIE_NAME, "", {
147
+ path: "/",
148
+ httpOnly: true,
149
+ sameSite: "lax",
150
+ secure,
151
+ maxAge: 0
152
+ });
153
+ }
154
+
155
+ // src/core/admin.ts
156
+ var DEFAULT_ADMIN_EMAILS = ["admin@example.com"];
157
+ function readAdminEmailSource() {
158
+ return process.env.GLOBAL_ADMIN_EMAILS || process.env.ADMIN_EMAILS || "";
159
+ }
160
+ function getGlobalAdminEmails() {
161
+ const source = readAdminEmailSource();
162
+ if (!source) {
163
+ return DEFAULT_ADMIN_EMAILS;
164
+ }
165
+ return source.split(",").map((value) => value.trim().toLowerCase()).filter(Boolean);
166
+ }
167
+ function isGlobalAdminEmail(email) {
168
+ if (!email) {
169
+ return false;
170
+ }
171
+ return getGlobalAdminEmails().includes(email.toLowerCase());
172
+ }
173
+
174
+ // src/core/index-html.ts
175
+ var DEFAULT_CASDOOR_STATIC_ORIGIN = "https://casdoor-static.foldspace.cn";
176
+ var DEFAULT_CASDOOR_ORIGIN = process.env.NEXT_PUBLIC_CASDOOR_SERVER_URL || "https://auth.heyaai.com";
177
+ var DEFAULT_ICON_HREF = "https://cdn.casbin.org/img/favicon.png";
178
+ var DEFAULT_MANIFEST_HREF = "/manifest.json";
179
+ function escapeHtmlAttribute(value) {
180
+ return value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
181
+ }
182
+ function createAuthIndexHtml(options = {}) {
183
+ const staticOrigin = options.staticOrigin || DEFAULT_CASDOOR_STATIC_ORIGIN;
184
+ const casdoorOrigin = options.casdoorOrigin || DEFAULT_CASDOOR_ORIGIN;
185
+ const apiProxyPrefix = options.apiProxyPrefix || "/auth/";
186
+ const appName = options.appName || "\u521B\u5C0F\u5267 AI";
187
+ const organizationName = options.organizationName || "built-in";
188
+ const description = options.description || "\u521B\u5C0F\u5267 AI \u767B\u5F55 - \u4E00\u4E2A\u652F\u6301 OAuth 2.0\u3001OIDC\u3001SAML \u548C CAS \u7684\u8EAB\u4EFD\u4E0E\u5355\u70B9\u767B\u5F55\u5E73\u53F0";
189
+ const iconHref = options.iconHref || DEFAULT_ICON_HREF;
190
+ const manifestHref = options.manifestHref || DEFAULT_MANIFEST_HREF;
191
+ const mainJs = `${staticOrigin}/static/js/main.5ddbc6ff.js`;
192
+ const mainCss = `${staticOrigin}/static/css/main.f35879a1.css`;
193
+ return String.raw`<!doctype html>
194
+ <html lang="zh-CN">
195
+ <head>
196
+ <meta charset="utf-8" />
197
+ <meta name="viewport" content="width=device-width,initial-scale=1" />
198
+ <meta name="theme-color" content="#000000" />
199
+ <meta name="description" content="${escapeHtmlAttribute(description)}" />
200
+ <link rel="apple-touch-icon" href="${escapeHtmlAttribute(iconHref)}" />
201
+ <link rel="manifest" href="${escapeHtmlAttribute(manifestHref)}" />
202
+ <title>${escapeHtmlAttribute(appName)}</title>
203
+ <script>
204
+ (function () {
205
+ var cdnOrigin = ${JSON.stringify(staticOrigin)}
206
+ var casdoorOrigin = ${JSON.stringify(casdoorOrigin)}
207
+ var currentOrigin = window.location.origin
208
+ var proxyPrefix = ${JSON.stringify(apiProxyPrefix)}
209
+ var proxyPathPrefix = proxyPrefix.replace(/\/$/, '')
210
+ var applicationId = ${JSON.stringify((options.organizationName || "built-in") + "/" + (options.appName || "\u521B\u5C0F\u5267 AI"))}
211
+
212
+ function toProxyUrl(input) {
213
+ try {
214
+ var url = typeof input === 'string' ? new URL(input, window.location.href) : input instanceof URL ? input : null
215
+ if (!url) {
216
+ return input
217
+ }
218
+
219
+ if (url.origin === cdnOrigin && url.pathname.indexOf(proxyPrefix) === 0) {
220
+ return currentOrigin + url.pathname + url.search + url.hash
221
+ }
222
+
223
+ if (url.origin === currentOrigin && url.pathname.indexOf('/static/') === 0) {
224
+ return cdnOrigin + url.pathname + url.search + url.hash
225
+ }
226
+
227
+ if (url.origin === currentOrigin && (url.pathname === '/auth' || url.pathname.indexOf('/auth/') === 0)) {
228
+ if (url.pathname === '/auth/api/get-application') {
229
+ url.searchParams.set('id', applicationId)
230
+ }
231
+ return currentOrigin + proxyPathPrefix + url.pathname.slice('/auth'.length) + url.search + url.hash
232
+ }
233
+
234
+ if (url.origin === casdoorOrigin) {
235
+ return currentOrigin + proxyPathPrefix + url.pathname + url.search + url.hash
236
+ }
237
+ } catch (error) {
238
+ return input
239
+ }
240
+
241
+ return input
242
+ }
243
+
244
+ function rewriteElement(element) {
245
+ if (!element || element.nodeType !== Node.ELEMENT_NODE) {
246
+ return
247
+ }
248
+
249
+ if (element.tagName === 'A' && element.getAttribute('href')) {
250
+ var href = element.getAttribute('href')
251
+ var rewrittenHref = toProxyUrl(href)
252
+ if (rewrittenHref !== href) {
253
+ element.setAttribute('href', rewrittenHref)
254
+ }
255
+ }
256
+
257
+ if (element.tagName === 'FORM' && element.getAttribute('action')) {
258
+ var action = element.getAttribute('action')
259
+ var rewrittenAction = toProxyUrl(action)
260
+ if (rewrittenAction !== action) {
261
+ element.setAttribute('action', rewrittenAction)
262
+ }
263
+ }
264
+
265
+ if (element.tagName === 'SCRIPT' && element.getAttribute('src')) {
266
+ var scriptSrc = element.getAttribute('src')
267
+ var rewrittenScriptSrc = toProxyUrl(scriptSrc)
268
+ if (rewrittenScriptSrc !== scriptSrc) {
269
+ element.setAttribute('src', rewrittenScriptSrc)
270
+ }
271
+ }
272
+
273
+ if (element.tagName === 'LINK' && element.getAttribute('href')) {
274
+ var linkHref = element.getAttribute('href')
275
+ var rewrittenLinkHref = toProxyUrl(linkHref)
276
+ if (rewrittenLinkHref !== linkHref) {
277
+ element.setAttribute('href', rewrittenLinkHref)
278
+ }
279
+ }
280
+
281
+ if (element.tagName === 'IMG' && element.getAttribute('src')) {
282
+ var imgSrc = element.getAttribute('src')
283
+ var rewrittenImgSrc = toProxyUrl(imgSrc)
284
+ if (rewrittenImgSrc !== imgSrc) {
285
+ element.setAttribute('src', rewrittenImgSrc)
286
+ }
287
+ }
288
+
289
+ if (typeof element.querySelectorAll === 'function') {
290
+ element.querySelectorAll('a[href], form[action], script[src], link[href], img[src]').forEach(rewriteElement)
291
+ }
292
+ }
293
+
294
+ if (typeof window.fetch === 'function') {
295
+ var originalFetch = window.fetch.bind(window)
296
+ window.fetch = function (input, init) {
297
+ return originalFetch(toProxyUrl(input), init)
298
+ }
299
+ }
300
+
301
+ if (window.XMLHttpRequest && window.XMLHttpRequest.prototype) {
302
+ var originalOpen = window.XMLHttpRequest.prototype.open
303
+ window.XMLHttpRequest.prototype.open = function (method, url) {
304
+ var rewrittenUrl = toProxyUrl(url)
305
+ return originalOpen.apply(this, [method, rewrittenUrl].concat(Array.prototype.slice.call(arguments, 2)))
306
+ }
307
+ }
308
+
309
+ if (window.open) {
310
+ var originalOpenWindow = window.open.bind(window)
311
+ window.open = function (url) {
312
+ return originalOpenWindow(toProxyUrl(url), arguments[1], arguments[2])
313
+ }
314
+ }
315
+
316
+ if (window.location && typeof window.location.assign === 'function') {
317
+ var originalAssign = window.location.assign.bind(window.location)
318
+ window.location.assign = function (url) {
319
+ return originalAssign(toProxyUrl(url))
320
+ }
321
+ }
322
+
323
+ if (window.location && typeof window.location.replace === 'function') {
324
+ var originalReplace = window.location.replace.bind(window.location)
325
+ window.location.replace = function (url) {
326
+ return originalReplace(toProxyUrl(url))
327
+ }
328
+ }
329
+
330
+ if (window.HTMLFormElement && window.HTMLFormElement.prototype) {
331
+ var originalSubmit = window.HTMLFormElement.prototype.submit
332
+ window.HTMLFormElement.prototype.submit = function () {
333
+ if (this.action) {
334
+ this.action = toProxyUrl(this.action)
335
+ }
336
+ return originalSubmit.apply(this, arguments)
337
+ }
338
+ }
339
+
340
+ document.addEventListener('click', function (event) {
341
+ var target = event.target instanceof Element ? event.target.closest('a[href]') : null
342
+ if (!target) {
343
+ return
344
+ }
345
+
346
+ var href = target.getAttribute('href')
347
+ var rewritten = toProxyUrl(href)
348
+ if (rewritten !== href) {
349
+ event.preventDefault()
350
+ window.location.href = rewritten
351
+ }
352
+ }, true)
353
+
354
+ document.addEventListener('submit', function (event) {
355
+ var form = event.target instanceof HTMLFormElement ? event.target : null
356
+ if (!form || !form.action) {
357
+ return
358
+ }
359
+
360
+ var rewritten = toProxyUrl(form.action)
361
+ if (rewritten !== form.action) {
362
+ event.preventDefault()
363
+ form.action = rewritten
364
+ form.submit()
365
+ }
366
+ }, true)
367
+
368
+ var originalAppendChild = Node.prototype.appendChild
369
+ Node.prototype.appendChild = function (node) {
370
+ rewriteElement(node)
371
+ return originalAppendChild.call(this, node)
372
+ }
373
+
374
+ var originalInsertBefore = Node.prototype.insertBefore
375
+ Node.prototype.insertBefore = function (node, referenceNode) {
376
+ rewriteElement(node)
377
+ return originalInsertBefore.call(this, node, referenceNode)
378
+ }
379
+
380
+ if (document.body) {
381
+ rewriteElement(document.body)
382
+ }
383
+
384
+ if (window.MutationObserver) {
385
+ var observer = new MutationObserver(function (mutations) {
386
+ mutations.forEach(function (mutation) {
387
+ mutation.addedNodes.forEach(rewriteElement)
388
+ })
389
+ })
390
+ observer.observe(document.documentElement, { childList: true, subtree: true })
391
+ }
392
+ })()
393
+ </script>
394
+ <script defer="defer" src="${escapeHtmlAttribute(mainJs)}"></script>
395
+ <link href="${escapeHtmlAttribute(mainCss)}" rel="stylesheet" />
396
+ </head>
397
+ <body>
398
+ <noscript>你需要启用 JavaScript 才能继续。</noscript>
399
+ <div id="root"></div>
400
+ </body>
401
+ </html>
402
+ `;
403
+ }
404
+ var AUTH_INDEX_HTML = createAuthIndexHtml();
405
+
406
+ // src/core/oauth-state.ts
407
+ import { Buffer as Buffer2 } from "buffer";
408
+ import crypto2 from "crypto";
409
+ var STATE_EXPIRY_SECONDS = 600;
410
+ var STATE_SECRET = process.env.NEXTAUTH_SECRET || process.env.CASDOOR_CLIENT_SECRET || "dev-state-secret";
411
+ var pkceCookiePrefix = "pkce_code_verifier";
412
+ function signStatePayload(payload) {
413
+ const body = Buffer2.from(JSON.stringify(payload)).toString("base64url");
414
+ const signature = crypto2.createHmac("sha256", STATE_SECRET).update(body).digest("base64url");
415
+ return `${body}.${signature}`;
416
+ }
417
+ function decodeStatePayload(state) {
418
+ const [body, signature] = state.split(".");
419
+ if (!body || !signature) {
420
+ return null;
421
+ }
422
+ const expectedSignature = crypto2.createHmac("sha256", STATE_SECRET).update(body).digest("base64url");
423
+ if (expectedSignature.length !== signature.length || !crypto2.timingSafeEqual(Buffer2.from(expectedSignature), Buffer2.from(signature))) {
424
+ return null;
425
+ }
426
+ try {
427
+ return JSON.parse(Buffer2.from(body, "base64url").toString("utf8"));
428
+ } catch {
429
+ return null;
430
+ }
431
+ }
432
+ function generateStateToken() {
433
+ return signStatePayload({
434
+ nonce: crypto2.randomUUID(),
435
+ issuedAt: Date.now()
436
+ });
437
+ }
438
+ function getPkceCookieName(state) {
439
+ const digest = crypto2.createHash("sha256").update(state).digest("base64url");
440
+ return `${pkceCookiePrefix}.${digest}`;
441
+ }
442
+ async function verifyState(stateFromUrl) {
443
+ const payload = decodeStatePayload(stateFromUrl);
444
+ if (!payload) {
445
+ return false;
446
+ }
447
+ return Date.now() - payload.issuedAt <= STATE_EXPIRY_SECONDS * 1e3;
448
+ }
449
+ function parseStateToken(token) {
450
+ if (!token) return null;
451
+ return decodeStatePayload(token);
452
+ }
453
+ function verifyStateToken(token) {
454
+ if (!token) return false;
455
+ return Boolean(decodeStatePayload(token));
456
+ }
457
+
458
+ // src/core/session-token.ts
459
+ import { Buffer as Buffer3 } from "buffer";
460
+ import crypto3 from "crypto";
461
+ var DEFAULT_MAX_AGE = 30 * 24 * 60 * 60;
462
+ function base64UrlEncode(value) {
463
+ return Buffer3.from(value, "utf8").toString("base64url");
464
+ }
465
+ function base64UrlDecode(value) {
466
+ return Buffer3.from(value, "base64url").toString("utf8");
467
+ }
468
+ function createSignature(input, secret) {
469
+ return crypto3.createHmac("sha256", secret).update(input).digest("base64url");
470
+ }
471
+ function timingSafeEqual(left, right) {
472
+ const leftBuffer = Buffer3.from(left);
473
+ const rightBuffer = Buffer3.from(right);
474
+ if (leftBuffer.length !== rightBuffer.length) {
475
+ return false;
476
+ }
477
+ return crypto3.timingSafeEqual(leftBuffer, rightBuffer);
478
+ }
479
+ async function encodeSessionToken(params) {
480
+ const { token = {}, secret, maxAge = DEFAULT_MAX_AGE } = params;
481
+ const issuedAt = Math.floor(Date.now() / 1e3);
482
+ const header = base64UrlEncode(JSON.stringify({ alg: "HS256", typ: "JWT" }));
483
+ const payload = base64UrlEncode(
484
+ JSON.stringify({
485
+ ...token,
486
+ iat: issuedAt,
487
+ exp: issuedAt + maxAge,
488
+ jti: crypto3.randomUUID()
489
+ })
490
+ );
491
+ const signature = createSignature(`${header}.${payload}`, secret);
492
+ return `${header}.${payload}.${signature}`;
493
+ }
494
+ async function decodeSessionToken(params) {
495
+ const { token, secret } = params;
496
+ if (!token) {
497
+ return null;
498
+ }
499
+ const [header, payload, signature] = token.split(".");
500
+ if (!header || !payload || !signature) {
501
+ return null;
502
+ }
503
+ const expectedSignature = createSignature(`${header}.${payload}`, secret);
504
+ if (!timingSafeEqual(signature, expectedSignature)) {
505
+ return null;
506
+ }
507
+ try {
508
+ const parsedPayload = JSON.parse(base64UrlDecode(payload));
509
+ if (parsedPayload.exp && parsedPayload.exp <= Math.floor(Date.now() / 1e3)) {
510
+ return null;
511
+ }
512
+ return parsedPayload;
513
+ } catch {
514
+ return null;
515
+ }
516
+ }
517
+
518
+ // src/casdoor/config.ts
519
+ function getCasdoorConfig(config) {
520
+ return normalizeAuthKitConfig(config);
521
+ }
522
+ function getCasdoorAuthorizeUrl(config, params) {
523
+ const base = new URL(config.casdoor.signinPath ?? "/login/oauth/authorize", config.casdoor.serverUrl);
524
+ base.searchParams.set("response_type", "code");
525
+ base.searchParams.set("client_id", config.casdoor.clientId);
526
+ base.searchParams.set("redirect_uri", params.redirectUri);
527
+ base.searchParams.set("scope", "profile");
528
+ base.searchParams.set("state", params.state);
529
+ base.searchParams.set("code_challenge", params.codeChallenge);
530
+ base.searchParams.set("code_challenge_method", "S256");
531
+ if (params.kind === "signup") {
532
+ base.searchParams.set("action", "signup");
533
+ }
534
+ return base.toString();
535
+ }
536
+ function getCasdoorTokenUrl(config) {
537
+ return new URL("/api/login/oauth/access_token", config.casdoor.serverUrl).toString();
538
+ }
539
+ function getCasdoorUserInfoUrl(config) {
540
+ return new URL("/api/userinfo", config.casdoor.serverUrl).toString();
541
+ }
542
+
543
+ // src/casdoor/oauth.ts
544
+ import { Buffer as Buffer4 } from "buffer";
545
+ function decodeJwtPayload(token) {
546
+ const parts = token.split(".");
547
+ if (parts.length < 2) {
548
+ return null;
549
+ }
550
+ try {
551
+ const payload = parts[1];
552
+ return JSON.parse(Buffer4.from(payload, "base64url").toString("utf8"));
553
+ } catch {
554
+ return null;
555
+ }
556
+ }
557
+ async function exchangeCodeForToken(config, code, redirectUri, codeVerifier) {
558
+ const response = await fetch(getCasdoorTokenUrl(config), {
559
+ method: "POST",
560
+ headers: { "content-type": "application/json" },
561
+ body: JSON.stringify({
562
+ grant_type: "authorization_code",
563
+ client_id: config.casdoor.clientId,
564
+ client_secret: config.casdoor.clientSecret,
565
+ code,
566
+ redirect_uri: redirectUri,
567
+ code_verifier: codeVerifier
568
+ })
569
+ });
570
+ if (!response.ok) {
571
+ throw new Error("Failed to exchange Casdoor authorization code.");
572
+ }
573
+ return await response.json();
574
+ }
575
+ async function fetchCasdoorUserInfo(config, accessToken) {
576
+ const response = await fetch(getCasdoorUserInfoUrl(config), {
577
+ headers: {
578
+ authorization: "Bearer " + accessToken
579
+ }
580
+ });
581
+ if (!response.ok) {
582
+ throw new Error("Failed to fetch Casdoor user profile.");
583
+ }
584
+ return await response.json();
585
+ }
586
+ function decodeCasdoorAccessToken(accessToken) {
587
+ return decodeJwtPayload(accessToken);
588
+ }
589
+ var exchangeCasdoorOAuthToken = exchangeCodeForToken;
590
+
591
+ // src/casdoor/entry.ts
592
+ import { NextResponse } from "next/server";
593
+
594
+ // src/core/pkce.ts
595
+ var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~";
596
+ function toBase64Url(bytes) {
597
+ const raw = Buffer.from(bytes).toString("base64");
598
+ return raw.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
599
+ }
600
+ async function createPkcePair() {
601
+ const bytes = crypto.getRandomValues(new Uint8Array(48));
602
+ const verifier = Array.from(bytes, (byte) => chars[byte % chars.length]).join("");
603
+ const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
604
+ return { verifier, challenge: toBase64Url(digest) };
605
+ }
606
+
607
+ // src/casdoor/entry.ts
608
+ function buildLocalAuthorizeUrl(origin, config, params) {
609
+ const normalized = normalizeAuthKitConfig(config);
610
+ const authorizePath = params.kind === "signup" ? "/signup/oauth/authorize" : normalized.casdoor.signinPath || "/login/oauth/authorize";
611
+ const authorizeUrl = new URL(authorizePath, origin);
612
+ authorizeUrl.searchParams.set("response_type", "code");
613
+ authorizeUrl.searchParams.set("client_id", normalized.casdoor.clientId);
614
+ authorizeUrl.searchParams.set("redirect_uri", `${origin}${normalized.casdoor.redirectPath || "/callback"}`);
615
+ authorizeUrl.searchParams.set("scope", "profile");
616
+ authorizeUrl.searchParams.set("state", params.state);
617
+ authorizeUrl.searchParams.set("code_challenge", params.codeChallenge);
618
+ authorizeUrl.searchParams.set("code_challenge_method", "S256");
619
+ return authorizeUrl.toString();
620
+ }
621
+ async function createRedirectEntryResponse(request, config, kind) {
622
+ const normalized = normalizeAuthKitConfig(config);
623
+ const origin = getRequestOrigin(request, normalized.appUrl);
624
+ const secure = normalized.cookie?.secure === "auto" ? isSecureRequest(request, normalized.appUrl) : Boolean(normalized.cookie?.secure);
625
+ const { verifier, challenge } = await createPkcePair();
626
+ const state = generateStateToken();
627
+ const response = NextResponse.redirect(
628
+ buildLocalAuthorizeUrl(origin, normalized, { state, codeChallenge: challenge, kind }),
629
+ 307
630
+ );
631
+ const redirectTarget = getAuthRedirectTarget(request);
632
+ if (redirectTarget) {
633
+ setAuthRedirectCookie(response, redirectTarget, secure);
634
+ }
635
+ setPublicOriginCookie(response, origin, secure);
636
+ response.cookies.set("oauth_state", state, { httpOnly: true, sameSite: "lax", secure, path: "/" });
637
+ response.cookies.set(getPkceCookieName(state), verifier, { httpOnly: true, sameSite: "lax", secure, path: "/" });
638
+ return response;
639
+ }
640
+ async function createAuthorizePageResponse(request, config) {
641
+ const normalized = normalizeAuthKitConfig(config);
642
+ const origin = getRequestOrigin(request, normalized.appUrl);
643
+ const secure = normalized.cookie?.secure === "auto" ? isSecureRequest(request, normalized.appUrl) : Boolean(normalized.cookie?.secure);
644
+ const response = new NextResponse(
645
+ createAuthIndexHtml({
646
+ appName: normalized.casdoor.appName,
647
+ organizationName: normalized.casdoor.organizationName,
648
+ staticOrigin: process.env.NEXT_PUBLIC_CASDOOR_STATIC_ORIGIN,
649
+ casdoorOrigin: normalized.casdoor.serverUrl,
650
+ apiProxyPrefix: "/auth/"
651
+ }),
652
+ {
653
+ status: 200,
654
+ headers: {
655
+ "content-type": "text/html; charset=utf-8",
656
+ "cache-control": "no-store, max-age=0"
657
+ }
658
+ }
659
+ );
660
+ setPublicOriginCookie(response, origin, secure);
661
+ return response;
662
+ }
663
+ async function createLoginEntryResponse(request, config) {
664
+ return createRedirectEntryResponse(request, config, "login");
665
+ }
666
+ async function createSignupEntryResponse(request, config) {
667
+ return createRedirectEntryResponse(request, config, "signup");
668
+ }
669
+ async function createAuthorizeEntryResponse(request, config) {
670
+ return createAuthorizePageResponse(request, config);
671
+ }
672
+
673
+ // src/casdoor/callback.ts
674
+ import { NextResponse as NextResponse2 } from "next/server";
675
+ function readCookieHeaderValue(cookieHeader, name) {
676
+ if (!cookieHeader) {
677
+ return null;
678
+ }
679
+ for (const entry of cookieHeader.split(";")) {
680
+ const [rawName, ...valueParts] = entry.trim().split("=");
681
+ if (rawName === name) {
682
+ const value = valueParts.join("=").trim();
683
+ return value || null;
684
+ }
685
+ }
686
+ return null;
687
+ }
688
+ function getPublicOrigin(request, config) {
689
+ return getStoredPublicOrigin(request) || getRequestOrigin(request, config.appUrl);
690
+ }
691
+ function rewriteToCallbackErrorPage(request, config, title, message, details) {
692
+ const origin = getPublicOrigin(request, config);
693
+ const targetUrl = new URL("/callback/error", origin);
694
+ targetUrl.searchParams.set("title", title);
695
+ targetUrl.searchParams.set("message", message);
696
+ if (details) {
697
+ targetUrl.searchParams.set("details", details);
698
+ }
699
+ return NextResponse2.redirect(targetUrl, 307);
700
+ }
701
+ function getPkceCodeVerifier(request, state) {
702
+ return readCookieHeaderValue(request.headers.get("cookie"), getPkceCookieName(state));
703
+ }
704
+ function setNextAuthSessionCookies(response, sessionToken, isSecure) {
705
+ const cookieName = isSecure ? "__Secure-next-auth.session-token" : "next-auth.session-token";
706
+ const expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3);
707
+ const baseOptions = {
708
+ path: "/",
709
+ httpOnly: true,
710
+ sameSite: "lax",
711
+ secure: isSecure,
712
+ expires
713
+ };
714
+ const maxCookieSize = 3933;
715
+ if (sessionToken.length <= maxCookieSize) {
716
+ response.cookies.set(cookieName, sessionToken, baseOptions);
717
+ return;
718
+ }
719
+ const chunkCount = Math.ceil(sessionToken.length / maxCookieSize);
720
+ for (let index = 0; index < chunkCount; index++) {
721
+ response.cookies.set(
722
+ `${cookieName}.${index}`,
723
+ sessionToken.slice(index * maxCookieSize, (index + 1) * maxCookieSize),
724
+ baseOptions
725
+ );
726
+ }
727
+ }
728
+ function sanitizeRedirectPath(value) {
729
+ if (!value || !value.startsWith("/") || value.startsWith("//")) {
730
+ return "/user/account";
731
+ }
732
+ return value;
733
+ }
734
+ function mapProfileToAuthUser(profile, adapter) {
735
+ const typedProfile = profile;
736
+ const email = typedProfile.email || null;
737
+ const isAdmin = Boolean(typedProfile.isAdmin) || Boolean(adapter?.isAdminEmail?.(email)) || isGlobalAdminEmail(email);
738
+ return {
739
+ id: typedProfile.sub || typedProfile.id || typedProfile.email || "casdoor-user",
740
+ name: typedProfile.name || typedProfile.displayName || null,
741
+ email,
742
+ image: typedProfile.picture || typedProfile.avatarUrl || null,
743
+ isAdmin,
744
+ tokenBalance: 2580,
745
+ isVip: true
746
+ };
747
+ }
748
+ function getRedirectTarget(request, user, adapter) {
749
+ const adapterRedirect = adapter?.resolvePostLoginRedirect?.(user);
750
+ if (adapterRedirect) {
751
+ return sanitizeRedirectPath(adapterRedirect);
752
+ }
753
+ const storedRedirect = getAuthRedirectTarget(request);
754
+ if (storedRedirect) {
755
+ return sanitizeRedirectPath(storedRedirect);
756
+ }
757
+ return sanitizeRedirectPath(resolvePostLoginRedirect(user, "/user/account"));
758
+ }
759
+ async function createCallbackResponse(request, options) {
760
+ const normalized = normalizeAuthKitConfig(options.config);
761
+ const publicOrigin = getPublicOrigin(request, normalized);
762
+ const url = new URL(request.url);
763
+ const code = url.searchParams.get("code");
764
+ const state = url.searchParams.get("state");
765
+ const error = url.searchParams.get("error");
766
+ const secure = normalized.cookie?.secure === "auto" ? isSecureRequest(request, normalized.appUrl) : Boolean(normalized.cookie?.secure);
767
+ if (error) {
768
+ return rewriteToCallbackErrorPage(
769
+ request,
770
+ normalized,
771
+ "Casdoor \u8FD4\u56DE\u4E86\u6388\u6743\u9519\u8BEF",
772
+ "\u6388\u6743\u670D\u52A1\u5668\u5728\u56DE\u8C03\u9636\u6BB5\u8FD4\u56DE\u4E86\u9519\u8BEF\u4FE1\u606F\u3002\u8BF7\u8FD4\u56DE\u9996\u9875\u6216\u91CD\u65B0\u767B\u5F55\u540E\u518D\u8BD5\u3002",
773
+ error
774
+ );
775
+ }
776
+ if (!code) {
777
+ return rewriteToCallbackErrorPage(
778
+ request,
779
+ normalized,
780
+ "\u7F3A\u5C11\u6388\u6743\u7801",
781
+ "Casdoor \u56DE\u8C03\u6CA1\u6709\u5E26\u56DE code\uFF0C\u8FD9\u901A\u5E38\u610F\u5473\u7740\u6388\u6743\u6D41\u7A0B\u672A\u5B8C\u6210\u3002",
782
+ "no_code"
783
+ );
784
+ }
785
+ if (!state || !await verifyState(state)) {
786
+ return rewriteToCallbackErrorPage(
787
+ request,
788
+ normalized,
789
+ "\u767B\u5F55\u72B6\u6001\u6821\u9A8C\u5931\u8D25",
790
+ "\u56DE\u8C03\u4E2D\u7684 state \u4E0E\u672C\u6B21\u767B\u5F55\u6D41\u7A0B\u4E0D\u5339\u914D\uFF0C\u8BF7\u91CD\u65B0\u53D1\u8D77\u767B\u5F55\u3002",
791
+ "invalid_state"
792
+ );
793
+ }
794
+ const codeVerifier = getPkceCodeVerifier(request, state);
795
+ if (!codeVerifier) {
796
+ return rewriteToCallbackErrorPage(
797
+ request,
798
+ normalized,
799
+ "\u7F3A\u5C11 PKCE \u6821\u9A8C\u503C",
800
+ "\u56DE\u8C03\u8BF7\u6C42\u91CC\u6CA1\u6709\u627E\u5230 pkce_code_verifier cookie\u3002\u8BF7\u91CD\u65B0\u4ECE\u767B\u5F55\u5165\u53E3\u53D1\u8D77\u6D41\u7A0B\u3002",
801
+ "missing_pkce_code_verifier"
802
+ );
803
+ }
804
+ const casdoorConfig = getCasdoorConfig(normalized);
805
+ const redirectUri = `${publicOrigin}${casdoorConfig.casdoor.redirectPath}`;
806
+ const tokens = await exchangeCasdoorOAuthToken(casdoorConfig, code, redirectUri, codeVerifier);
807
+ const accessToken = tokens.access_token ?? tokens.accessToken ?? "";
808
+ if (!accessToken) {
809
+ return rewriteToCallbackErrorPage(
810
+ request,
811
+ normalized,
812
+ "\u7F3A\u5C11\u8BBF\u95EE\u4EE4\u724C",
813
+ "Casdoor \u56DE\u8C03\u6CA1\u6709\u8FD4\u56DE access token\u3002",
814
+ "missing_access_token"
815
+ );
816
+ }
817
+ const profile = await fetchCasdoorUserInfo(casdoorConfig, accessToken);
818
+ const decodedAccessToken = decodeCasdoorAccessToken(accessToken);
819
+ const mappedUser = options.adapter?.onUserSync ? await options.adapter.onUserSync(profile, {
820
+ accessToken,
821
+ refreshToken: tokens.refresh_token || tokens.refreshToken,
822
+ idToken: tokens.id_token || tokens.idToken,
823
+ expiresAt: tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : tokens.expiresAt
824
+ }) : mapProfileToAuthUser(profile, options.adapter);
825
+ if (options.persistence?.syncAuthUser) {
826
+ await options.persistence.syncAuthUser(mappedUser);
827
+ }
828
+ const sessionToken = await encodeSessionToken({
829
+ token: {
830
+ id: mappedUser.id,
831
+ sub: mappedUser.id,
832
+ userId: mappedUser.id,
833
+ name: mappedUser.name,
834
+ email: mappedUser.email,
835
+ picture: mappedUser.image,
836
+ accessToken,
837
+ expiresAt: tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : decodedAccessToken?.exp,
838
+ isAdmin: mappedUser.isAdmin,
839
+ tokenBalance: mappedUser.tokenBalance,
840
+ isVip: mappedUser.isVip
841
+ },
842
+ secret: normalized.nextauthSecret,
843
+ maxAge: normalized.session?.maxAgeSeconds
844
+ });
845
+ const response = NextResponse2.redirect(new URL(getRedirectTarget(request, mappedUser, options.adapter), publicOrigin));
846
+ setNextAuthSessionCookies(response, sessionToken, secure);
847
+ response.cookies.set(getPkceCookieName(state), "", {
848
+ path: "/",
849
+ httpOnly: true,
850
+ sameSite: "lax",
851
+ secure,
852
+ maxAge: 0
853
+ });
854
+ response.cookies.set("oauth_state", "", {
855
+ path: "/",
856
+ httpOnly: true,
857
+ sameSite: "lax",
858
+ secure,
859
+ maxAge: 0
860
+ });
861
+ clearAuthRedirectCookie(response, secure);
862
+ clearPublicOriginCookie(response, secure);
863
+ return response;
864
+ }
865
+ function createCallbackHandler(options) {
866
+ return async function GET(request) {
867
+ return createCallbackResponse(request, options);
868
+ };
869
+ }
870
+
871
+ export {
872
+ normalizeAuthKitConfig,
873
+ PUBLIC_ORIGIN_COOKIE_NAME,
874
+ getRequestOrigin,
875
+ setPublicOriginCookie,
876
+ clearPublicOriginCookie,
877
+ getStoredPublicOrigin,
878
+ isSecureRequest,
879
+ AUTH_REDIRECT_COOKIE_NAME,
880
+ getAuthRedirectTarget,
881
+ setAuthRedirectCookie,
882
+ clearAuthRedirectCookie,
883
+ getGlobalAdminEmails,
884
+ isGlobalAdminEmail,
885
+ createAuthIndexHtml,
886
+ AUTH_INDEX_HTML,
887
+ pkceCookiePrefix,
888
+ generateStateToken,
889
+ getPkceCookieName,
890
+ verifyState,
891
+ parseStateToken,
892
+ verifyStateToken,
893
+ encodeSessionToken,
894
+ decodeSessionToken,
895
+ getCasdoorConfig,
896
+ getCasdoorAuthorizeUrl,
897
+ getCasdoorTokenUrl,
898
+ getCasdoorUserInfoUrl,
899
+ exchangeCodeForToken,
900
+ fetchCasdoorUserInfo,
901
+ decodeCasdoorAccessToken,
902
+ exchangeCasdoorOAuthToken,
903
+ createLoginEntryResponse,
904
+ createSignupEntryResponse,
905
+ createAuthorizeEntryResponse,
906
+ createCallbackResponse,
907
+ createCallbackHandler
908
+ };
909
+ //# sourceMappingURL=chunk-IQEVUR77.js.map