@foldspace-fe/casdoor-next-auth-kit 0.1.22 → 0.1.24

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 (36) hide show
  1. package/README.md +70 -0
  2. package/dist/auth-role-C35sP1i6.d.ts +40 -0
  3. package/dist/callback-Da3JC_EN.d.ts +18 -0
  4. package/dist/casdoor/index.d.ts +3 -8
  5. package/dist/casdoor/index.js +6 -4
  6. package/dist/{chunk-GLK4IW22.js → chunk-CSQFNYTS.js} +25 -11
  7. package/dist/chunk-CSQFNYTS.js.map +1 -0
  8. package/dist/{chunk-MWXY4JSL.js → chunk-IPJT66SK.js} +19 -11
  9. package/dist/{chunk-MWXY4JSL.js.map → chunk-IPJT66SK.js.map} +1 -1
  10. package/dist/chunk-JCQ5P7QZ.js +74 -0
  11. package/dist/chunk-JCQ5P7QZ.js.map +1 -0
  12. package/dist/chunk-YHPSOLXM.js +904 -0
  13. package/dist/chunk-YHPSOLXM.js.map +1 -0
  14. package/dist/cli-templates-IhA9gjyF.d.ts +31 -0
  15. package/dist/cli-templates.d.ts +2 -0
  16. package/dist/cli-templates.js +7 -0
  17. package/dist/cli-templates.js.map +1 -0
  18. package/dist/cli.js +52 -557
  19. package/dist/cli.js.map +1 -1
  20. package/dist/index.d.ts +8 -14
  21. package/dist/index.js +56 -6
  22. package/dist/next/index.d.ts +3 -3
  23. package/dist/next/index.js +7 -5
  24. package/dist/{options-D2YQdRWu.d.ts → options-CpWDszxZ.d.ts} +5 -2
  25. package/dist/react/index.d.ts +5 -4
  26. package/dist/react/index.js +4 -18
  27. package/dist/react/index.js.map +1 -1
  28. package/dist/skills/casdoor-next-auth-kit/SKILL.md +49 -1
  29. package/dist/{types-BJv6j3NZ.d.ts → types-COXcI8tx.d.ts} +3 -1
  30. package/package.json +1 -1
  31. package/dist/callback-rEWxVGyL.d.ts +0 -12
  32. package/dist/chunk-FW4WDHNS.js +0 -332
  33. package/dist/chunk-FW4WDHNS.js.map +0 -1
  34. package/dist/chunk-GLK4IW22.js.map +0 -1
  35. package/dist/chunk-T2M5MVPE.js +0 -20
  36. package/dist/chunk-T2M5MVPE.js.map +0 -1
package/README.md CHANGED
@@ -57,6 +57,76 @@ import { BillingProvider } from '@foldspace-fe/casdoor-next-auth-kit/react';
57
57
 
58
58
  如果宿主已经有自己的会员计划 rows,先用 `buildBillingSubscriptionCatalog()` 生成 subscription catalog,再把结果交给 `BillingProvider`。商品项仍然可以单独拼进同一个 catalog,但订阅和商品要保持语义分离。
59
59
 
60
+ 一个可以直接复制的完整模板如下:
61
+
62
+ ```ts
63
+ const membershipPlans = [
64
+ {
65
+ id: 'plan-basic',
66
+ code: 'membership-monthly',
67
+ name: 'Membership Monthly',
68
+ level: 'BASIC',
69
+ priceCents: 99900,
70
+ giftPoints: 10000,
71
+ billingCycle: 'MONTH',
72
+ benefits: {
73
+ faceLibrary: true,
74
+ monthlyReports: true,
75
+ },
76
+ },
77
+ ];
78
+
79
+ const subscriptionCatalog = buildBillingSubscriptionCatalog(membershipPlans, {
80
+ catalogKey: 'main',
81
+ title: 'Billing Catalog',
82
+ mapPlan: (plan) => ({
83
+ source: plan,
84
+ key: plan.code,
85
+ title: plan.name,
86
+ description: `${plan.level} membership`,
87
+ productId: 'qixiaoju/创小剧会员订阅',
88
+ planId: plan.id,
89
+ priceId: `pricing_${plan.code}`,
90
+ interval: 'month',
91
+ priceValue: plan.priceCents,
92
+ metadata: {
93
+ level: plan.level,
94
+ giftPoints: String(plan.giftPoints),
95
+ billingCycle: plan.billingCycle,
96
+ },
97
+ }),
98
+ });
99
+
100
+ const billingCatalog = {
101
+ ...subscriptionCatalog,
102
+ purchasableIds: [...subscriptionCatalog.purchasableIds, 'credits-50'],
103
+ items: [
104
+ ...subscriptionCatalog.items,
105
+ {
106
+ key: 'credits-50',
107
+ kind: 'product',
108
+ title: '50 Credits',
109
+ description: 'One-time product used for credits or other non-recurring goods.',
110
+ credits: 50,
111
+ backendRef: {
112
+ productId: 'qixiaoju/创小剧积分包-50',
113
+ priceId: 'price_credits_50',
114
+ },
115
+ creditGrant: {
116
+ creditsPerUnit: 50,
117
+ unitName: 'credits',
118
+ },
119
+ },
120
+ ],
121
+ };
122
+ ```
123
+
124
+ 如果你只是想配白名单,`.env` 里可以直接写:
125
+
126
+ ```env
127
+ NEXT_PUBLIC_BILLING_PURCHASABLE_IDS=membership-monthly,credits-50
128
+ ```
129
+
60
130
  ### Billing 动作
61
131
 
62
132
  ```tsx
@@ -0,0 +1,40 @@
1
+ import { A as AuthUserRole, a as AuthUser } from './types-COXcI8tx.js';
2
+
3
+ type AuthSummaryRole = 'guest' | AuthUserRole;
4
+ interface AuthUserLike {
5
+ id?: string | null;
6
+ sub?: string | null;
7
+ name?: string | null;
8
+ displayName?: string | null;
9
+ email?: string | null;
10
+ image?: string | null;
11
+ picture?: string | null;
12
+ avatarUrl?: string | null;
13
+ isAdmin?: boolean;
14
+ role?: string | null;
15
+ tokenBalance?: number;
16
+ isVip?: boolean;
17
+ }
18
+ interface AuthUserSummaryShape {
19
+ id: string | null;
20
+ name: string;
21
+ email: string | null;
22
+ image: string | null;
23
+ isAuthenticated: boolean;
24
+ isAdmin: boolean;
25
+ tokenBalance: number;
26
+ isVip: boolean;
27
+ role: AuthSummaryRole;
28
+ }
29
+ declare function resolveAuthUserRole(role: string | null | undefined, isAdmin: boolean): AuthUserRole;
30
+ declare function buildAuthUserFromProfile(profile: AuthUserLike, isAdmin: boolean): AuthUser;
31
+ declare function buildAuthUserFromToken(token: AuthUserLike & {
32
+ userId?: string;
33
+ sub?: string;
34
+ id?: string;
35
+ accessToken?: string;
36
+ expiresAt?: number;
37
+ }, isAdmin: boolean): AuthUser;
38
+ declare function buildAuthUserSummary(user: AuthUserLike | null | undefined): AuthUserSummaryShape;
39
+
40
+ export { type AuthSummaryRole as A, type AuthUserLike as a, type AuthUserSummaryShape as b, buildAuthUserFromProfile as c, buildAuthUserFromToken as d, buildAuthUserSummary as e, resolveAuthUserRole as r };
@@ -0,0 +1,18 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ import { b as AuthKitConfig, O as OAuthTokens, C as CasdoorUserInfo, c as AuthBusinessAdapter, d as AuthPersistenceAdapter, a as AuthUser } from './types-COXcI8tx.js';
3
+
4
+ declare function exchangeCodeForToken(config: AuthKitConfig, code: string, redirectUri: string, codeVerifier: string): Promise<OAuthTokens>;
5
+ declare function fetchCasdoorUserInfo(config: AuthKitConfig, accessToken: string): Promise<CasdoorUserInfo>;
6
+ declare function decodeCasdoorAccessToken(accessToken: string): Record<string, unknown> | null;
7
+ declare const exchangeCasdoorOAuthToken: typeof exchangeCodeForToken;
8
+
9
+ interface CallbackHandlerOptions {
10
+ config: AuthKitConfig;
11
+ adapter?: AuthBusinessAdapter;
12
+ persistence?: AuthPersistenceAdapter;
13
+ }
14
+ declare function mapProfileToAuthUser(profile: Awaited<ReturnType<typeof fetchCasdoorUserInfo>>, adapter?: AuthBusinessAdapter): AuthUser;
15
+ declare function createCallbackResponse(request: NextRequest, options: CallbackHandlerOptions): Promise<NextResponse>;
16
+ declare function createCallbackHandler(options: CallbackHandlerOptions): (request: NextRequest) => Promise<NextResponse<unknown>>;
17
+
18
+ export { type CallbackHandlerOptions as C, createCallbackResponse as a, exchangeCodeForToken as b, createCallbackHandler as c, decodeCasdoorAccessToken as d, exchangeCasdoorOAuthToken as e, fetchCasdoorUserInfo as f, mapProfileToAuthUser as m };
@@ -1,6 +1,6 @@
1
- import { A as AuthKitConfig, O as OAuthTokens, C as CasdoorUserInfo } from '../types-BJv6j3NZ.js';
1
+ import { b as AuthKitConfig } from '../types-COXcI8tx.js';
2
+ export { C as CallbackHandlerOptions, c as createCallbackHandler, a as createCallbackResponse, d as decodeCasdoorAccessToken, e as exchangeCasdoorOAuthToken, b as exchangeCodeForToken, f as fetchCasdoorUserInfo, m as mapProfileToAuthUser } from '../callback-Da3JC_EN.js';
2
3
  import { NextRequest, NextResponse } from 'next/server';
3
- export { C as CallbackHandlerOptions, c as createCallbackHandler, a as createCallbackResponse } from '../callback-rEWxVGyL.js';
4
4
 
5
5
  declare function getCasdoorConfig(config: AuthKitConfig): AuthKitConfig;
6
6
  declare function getCasdoorAuthorizeUrl(config: AuthKitConfig, params: {
@@ -12,11 +12,6 @@ declare function getCasdoorAuthorizeUrl(config: AuthKitConfig, params: {
12
12
  declare function getCasdoorTokenUrl(config: AuthKitConfig): string;
13
13
  declare function getCasdoorUserInfoUrl(config: AuthKitConfig): string;
14
14
 
15
- declare function exchangeCodeForToken(config: AuthKitConfig, code: string, redirectUri: string, codeVerifier: string): Promise<OAuthTokens>;
16
- declare function fetchCasdoorUserInfo(config: AuthKitConfig, accessToken: string): Promise<CasdoorUserInfo>;
17
- declare function decodeCasdoorAccessToken(accessToken: string): Record<string, unknown> | null;
18
- declare const exchangeCasdoorOAuthToken: typeof exchangeCodeForToken;
19
-
20
15
  declare function createLoginEntryResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse>;
21
16
  declare function createSignupEntryResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse>;
22
17
  declare function createAuthorizeEntryResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse>;
@@ -25,4 +20,4 @@ declare function createCasdoorApiProxyHandler(config: AuthKitConfig, prefix?: st
25
20
  declare function createCasdoorPageProxyHandler(config: AuthKitConfig, prefix?: string, upstreamPrefix?: string): (request: NextRequest) => Promise<NextResponse>;
26
21
  declare function createCasdoorCommerceProxyHandler(config: AuthKitConfig, prefix?: string, upstreamPrefix?: string): (request: NextRequest) => Promise<NextResponse>;
27
22
 
28
- export { createAuthorizeEntryResponse, createCasdoorApiProxyHandler, createCasdoorCommerceProxyHandler, createCasdoorPageProxyHandler, createLoginEntryResponse, createSignupEntryResponse, decodeCasdoorAccessToken, exchangeCasdoorOAuthToken, exchangeCodeForToken, fetchCasdoorUserInfo, getCasdoorAuthorizeUrl, getCasdoorConfig, getCasdoorTokenUrl, getCasdoorUserInfoUrl };
23
+ export { createAuthorizeEntryResponse, createCasdoorApiProxyHandler, createCasdoorCommerceProxyHandler, createCasdoorPageProxyHandler, createLoginEntryResponse, createSignupEntryResponse, getCasdoorAuthorizeUrl, getCasdoorConfig, getCasdoorTokenUrl, getCasdoorUserInfoUrl };
@@ -16,9 +16,10 @@ import {
16
16
  getCasdoorAuthorizeUrl,
17
17
  getCasdoorConfig,
18
18
  getCasdoorTokenUrl,
19
- getCasdoorUserInfoUrl
20
- } from "../chunk-MWXY4JSL.js";
21
- import "../chunk-T2M5MVPE.js";
19
+ getCasdoorUserInfoUrl,
20
+ mapProfileToAuthUser
21
+ } from "../chunk-IPJT66SK.js";
22
+ import "../chunk-JCQ5P7QZ.js";
22
23
  export {
23
24
  createAuthorizeEntryResponse,
24
25
  createCallbackHandler,
@@ -35,6 +36,7 @@ export {
35
36
  getCasdoorAuthorizeUrl,
36
37
  getCasdoorConfig,
37
38
  getCasdoorTokenUrl,
38
- getCasdoorUserInfoUrl
39
+ getCasdoorUserInfoUrl,
40
+ mapProfileToAuthUser
39
41
  };
40
42
  //# sourceMappingURL=index.js.map
@@ -9,7 +9,10 @@ import {
9
9
  isGlobalAdminEmail,
10
10
  isSecureRequest,
11
11
  normalizeAuthKitConfig
12
- } from "./chunk-MWXY4JSL.js";
12
+ } from "./chunk-IPJT66SK.js";
13
+ import {
14
+ buildAuthUserFromToken
15
+ } from "./chunk-JCQ5P7QZ.js";
13
16
 
14
17
  // src/next/login.ts
15
18
  function createLoginRouteHandler(config) {
@@ -85,15 +88,22 @@ function createLogoutHandler(config) {
85
88
  import NextAuth from "next-auth";
86
89
  function resolveAuthUserFromToken(token, adapter) {
87
90
  const email = typeof token.email === "string" ? token.email : null;
88
- return {
89
- id: token.userId || token.sub || token.id || email || "casdoor-user",
90
- name: typeof token.name === "string" ? token.name : null,
91
- email,
92
- image: typeof token.picture === "string" ? token.picture : null,
93
- isAdmin: Boolean(token.isAdmin) || Boolean(adapter?.isAdminEmail?.(email)) || isGlobalAdminEmail(email),
94
- tokenBalance: Number(token.tokenBalance ?? 2580),
95
- isVip: Boolean(token.isVip ?? true)
96
- };
91
+ const isAdmin = Boolean(token.isAdmin) || token.role === "admin" || Boolean(adapter?.isAdminEmail?.(email)) || isGlobalAdminEmail(email);
92
+ return buildAuthUserFromToken(
93
+ {
94
+ userId: token.userId,
95
+ sub: token.sub,
96
+ id: token.id,
97
+ name: token.name,
98
+ email,
99
+ picture: token.picture ?? null,
100
+ isAdmin: token.isAdmin,
101
+ role: token.role,
102
+ tokenBalance: token.tokenBalance,
103
+ isVip: token.isVip
104
+ },
105
+ isAdmin
106
+ );
97
107
  }
98
108
  function createNextAuthOptions(options) {
99
109
  const normalized = normalizeAuthKitConfig(options.config);
@@ -124,6 +134,7 @@ function createNextAuthOptions(options) {
124
134
  typedToken.email = typedProfile.email || typedToken.email;
125
135
  typedToken.picture = typedProfile.image || typedProfile.picture || typedToken.picture;
126
136
  typedToken.isAdmin = Boolean(typedProfile.isAdmin ?? typedToken.isAdmin);
137
+ typedToken.role = typedProfile.role === "admin" || typedProfile.role === "user" ? typedProfile.role : typedToken.role ?? (typedToken.isAdmin ? "admin" : "user");
127
138
  typedToken.tokenBalance = typedProfile.tokenBalance ?? typedToken.tokenBalance ?? 2580;
128
139
  typedToken.isVip = typedProfile.isVip ?? typedToken.isVip ?? true;
129
140
  }
@@ -139,6 +150,7 @@ function createNextAuthOptions(options) {
139
150
  if (typedSession.user) {
140
151
  typedSession.user.id = resolvedUser.id;
141
152
  typedSession.user.isAdmin = resolvedUser.isAdmin;
153
+ typedSession.user.role = resolvedUser.role;
142
154
  typedSession.user.tokenBalance = resolvedUser.tokenBalance;
143
155
  typedSession.user.isVip = resolvedUser.isVip;
144
156
  }
@@ -151,6 +163,7 @@ function createNextAuthOptions(options) {
151
163
  image: typedSession.user?.image || resolvedUser.image,
152
164
  id: resolvedUser.id,
153
165
  isAdmin: resolvedUser.isAdmin,
166
+ role: resolvedUser.role,
154
167
  tokenBalance: resolvedUser.tokenBalance,
155
168
  isVip: resolvedUser.isVip
156
169
  };
@@ -190,7 +203,8 @@ export {
190
203
  createSignupRouteHandler,
191
204
  createAuthorizeRouteHandler,
192
205
  createLogoutHandler,
206
+ resolveAuthUserFromToken,
193
207
  createNextAuthOptions,
194
208
  createNextAuthRouteHandler
195
209
  };
196
- //# sourceMappingURL=chunk-GLK4IW22.js.map
210
+ //# sourceMappingURL=chunk-CSQFNYTS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/next/login.ts","../src/next/signup.ts","../src/next/authorize.ts","../src/next/logout.ts","../src/next/options.ts"],"sourcesContent":["import type { NextRequest } from 'next/server';\nimport type { AuthKitConfig } from '../types';\nimport { createLoginEntryResponse } from '../casdoor/entry';\n\nexport function createLoginRouteHandler(config: AuthKitConfig) {\n return async (request: NextRequest) => createLoginEntryResponse(request, config);\n}\n","import type { NextRequest } from 'next/server';\nimport type { AuthKitConfig } from '../types';\nimport { createSignupEntryResponse } from '../casdoor/entry';\n\nexport function createSignupRouteHandler(config: AuthKitConfig) {\n return async (request: NextRequest) => createSignupEntryResponse(request, config);\n}\n","import type { NextRequest } from 'next/server';\nimport type { AuthKitConfig } from '../types';\nimport { createAuthorizeEntryResponse } from '../casdoor/entry';\n\nexport function createAuthorizeRouteHandler(config: AuthKitConfig) {\n return async (request: NextRequest) => createAuthorizeEntryResponse(request, config);\n}\n","import { NextResponse, type NextRequest } from 'next/server';\nimport type { AuthKitConfig } from '../types';\nimport { isSecureRequest } from '../core/request-security';\nimport { clearAuthRedirectCookie } from '../core/auth-redirect';\nimport { clearPublicOriginCookie } from '../core/public-origin';\n\nfunction getCookieNamesFromHeader(cookieHeader: string | null): string[] {\n if (!cookieHeader) {\n return [];\n }\n\n return cookieHeader\n .split(';')\n .map((part) => part.trim())\n .filter(Boolean)\n .map((part) => part.split('=')[0]?.trim())\n .filter((name): name is string => Boolean(name));\n}\n\nfunction getPathCandidates(pathname: string): string[] {\n const normalized = pathname.startsWith('/') ? pathname : `/${pathname}`;\n const segments = normalized.split('/').filter(Boolean);\n const paths = new Set<string>(['/']);\n\n let current = '';\n for (const segment of segments) {\n current += `/${segment}`;\n paths.add(current);\n }\n\n return [...paths];\n}\n\nfunction resolveLogoutTargetUrl(request: NextRequest, config: AuthKitConfig): URL {\n const origin = request.cookies.get('auth_origin')?.value ?? config.appUrl ?? new URL(request.url).origin;\n const logoutRedirectPath = config.logoutRedirectPath ?? '/';\n return new URL(logoutRedirectPath, origin);\n}\n\nfunction clearCookieEverywhere(\n response: NextResponse,\n cookieName: string,\n secure: boolean,\n pathCandidates: string[],\n) {\n for (const path of pathCandidates) {\n response.cookies.set(cookieName, '', {\n path,\n httpOnly: true,\n sameSite: 'lax',\n secure,\n maxAge: 0,\n });\n }\n}\n\nexport function createLogoutHandler(config: AuthKitConfig) {\n return async function GET(request: NextRequest) {\n const secure = config.cookie?.secure === 'auto' ? isSecureRequest(request, config.appUrl) : Boolean(config.cookie?.secure);\n // 307 keeps same-path targets behaving like a reload instead of a cache-friendly rewrite.\n const targetUrl = resolveLogoutTargetUrl(request, config);\n const response = NextResponse.redirect(targetUrl, 307);\n response.headers.set('Clear-Site-Data', '\"cookies\"');\n const cookieNames = getCookieNamesFromHeader(request.headers.get('cookie'));\n const pathCandidates = getPathCandidates(request.nextUrl.pathname);\n\n for (const cookieName of cookieNames) {\n clearCookieEverywhere(response, cookieName, secure, pathCandidates);\n }\n clearCookieEverywhere(response, 'oauth_state', secure, pathCandidates);\n clearCookieEverywhere(response, 'auth_origin', secure, pathCandidates);\n clearCookieEverywhere(response, 'auth_redirect', secure, pathCandidates);\n clearAuthRedirectCookie(response, secure);\n clearPublicOriginCookie(response, secure);\n\n return response;\n };\n}\n","import NextAuth from 'next-auth';\nimport type { NextAuthOptions, Session } from 'next-auth';\nimport type { JWT } from 'next-auth/jwt';\nimport type { AuthBusinessAdapter, AuthKitConfig, AuthPersistenceAdapter, AuthUser, AuthUserRole } from '../types';\nimport { normalizeAuthKitConfig } from '../core/config';\nimport { decodeSessionToken, encodeSessionToken } from '../core/session-token';\nimport { isGlobalAdminEmail } from '../core/admin';\nimport { buildAuthUserFromToken } from '../core/auth-role';\n\nexport interface NextAuthRouteOptions {\n config: AuthKitConfig;\n adapter?: AuthBusinessAdapter;\n persistence?: AuthPersistenceAdapter;\n providers?: NextAuthOptions['providers'];\n}\n\nexport interface AuthTokenPayload extends JWT {\n id?: string;\n name?: string;\n email?: string;\n picture?: string | null;\n userId?: string;\n accessToken?: string;\n expiresAt?: number;\n tokenBalance?: number;\n isVip?: boolean;\n isAdmin?: boolean;\n role?: AuthUserRole;\n}\n\nexport interface AuthSessionUser {\n id?: string;\n isAdmin?: boolean;\n role?: AuthUserRole;\n tokenBalance?: number;\n isVip?: boolean;\n}\n\nexport interface AuthSession extends Session {\n accessToken?: string;\n expiresAt?: number;\n user?: AuthSessionUser & NonNullable<Session['user']>;\n}\n\nexport function resolveAuthUserFromToken(token: AuthTokenPayload, adapter?: AuthBusinessAdapter): AuthUser {\n const email = typeof token.email === 'string' ? token.email : null;\n const isAdmin = Boolean(token.isAdmin) || token.role === 'admin' || Boolean(adapter?.isAdminEmail?.(email)) || isGlobalAdminEmail(email);\n\n return buildAuthUserFromToken(\n {\n userId: token.userId,\n sub: token.sub,\n id: token.id,\n name: token.name,\n email,\n picture: token.picture ?? null,\n isAdmin: token.isAdmin,\n role: token.role,\n tokenBalance: token.tokenBalance,\n isVip: token.isVip,\n },\n isAdmin,\n );\n}\n\nexport function createNextAuthOptions(options: NextAuthRouteOptions): NextAuthOptions {\n const normalized = normalizeAuthKitConfig(options.config);\n\n return {\n providers: options.providers ?? [],\n session: {\n strategy: 'jwt',\n },\n jwt: {\n encode: encodeSessionToken,\n decode: decodeSessionToken,\n },\n pages: {\n signIn: '/login',\n error: '/callback/error',\n },\n callbacks: {\n async jwt({ token, account, profile }) {\n const typedToken = token as AuthTokenPayload;\n\n if (account) {\n typedToken.accessToken = account.access_token;\n typedToken.expiresAt = account.expires_at ? account.expires_at * 1000 : undefined;\n }\n\n if (profile && typeof profile === 'object') {\n const typedProfile = profile as Partial<AuthUser> & {\n sub?: string;\n id?: string;\n picture?: string;\n };\n\n typedToken.userId = typedProfile.id || typedProfile.sub || typedToken.userId;\n typedToken.name = typedProfile.name || typedToken.name;\n typedToken.email = typedProfile.email || typedToken.email;\n typedToken.picture = typedProfile.image || typedProfile.picture || typedToken.picture;\n typedToken.isAdmin = Boolean(typedProfile.isAdmin ?? typedToken.isAdmin);\n typedToken.role =\n typedProfile.role === 'admin' || typedProfile.role === 'user'\n ? typedProfile.role\n : typedToken.role ?? (typedToken.isAdmin ? 'admin' : 'user');\n typedToken.tokenBalance = typedProfile.tokenBalance ?? typedToken.tokenBalance ?? 2580;\n typedToken.isVip = typedProfile.isVip ?? typedToken.isVip ?? true;\n }\n\n return typedToken;\n },\n async session({ session, token }) {\n const typedSession = session as AuthSession;\n const typedToken = token as AuthTokenPayload;\n const tokenUserId = typedToken.userId || typedToken.sub || typedToken.id || '';\n const tokenEmail = typeof typedToken.email === 'string' ? typedToken.email : null;\n const persistedUser = options.persistence?.findAuthUser\n ? await options.persistence.findAuthUser({ id: tokenUserId || undefined, email: tokenEmail })\n : null;\n const resolvedUser = persistedUser ?? resolveAuthUserFromToken(typedToken, options.adapter);\n\n if (typedSession.user) {\n typedSession.user.id = resolvedUser.id;\n typedSession.user.isAdmin = resolvedUser.isAdmin;\n typedSession.user.role = resolvedUser.role;\n typedSession.user.tokenBalance = resolvedUser.tokenBalance;\n typedSession.user.isVip = resolvedUser.isVip;\n }\n\n typedSession.accessToken = typedToken.accessToken;\n typedSession.expiresAt = typedToken.expiresAt;\n typedSession.user = {\n ...(typedSession.user || {}),\n name: typedSession.user?.name || resolvedUser.name,\n email: typedSession.user?.email || resolvedUser.email,\n image: typedSession.user?.image || resolvedUser.image,\n id: resolvedUser.id,\n isAdmin: resolvedUser.isAdmin,\n role: resolvedUser.role,\n tokenBalance: resolvedUser.tokenBalance,\n isVip: resolvedUser.isVip,\n };\n\n return typedSession;\n },\n },\n events: {\n async signOut({ token }) {\n const typedToken = token as AuthTokenPayload | null;\n if (!typedToken?.accessToken || !normalized.appUrl) {\n return;\n }\n\n try {\n await fetch(new URL('/api/casdoor/logout', normalized.appUrl).toString(), {\n method: 'POST',\n headers: {\n Authorization: `Bearer ${typedToken.accessToken}`,\n },\n });\n } catch {\n // ignored\n }\n },\n },\n secret: normalized.nextauthSecret,\n };\n}\n\nexport function createNextAuthRouteHandler(options: NextAuthRouteOptions) {\n const handler = NextAuth(createNextAuthOptions(options));\n return {\n GET: handler,\n POST: handler,\n };\n}\n"],"mappings":"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","names":[]}
@@ -1,6 +1,7 @@
1
1
  import {
2
+ buildAuthUserFromProfile,
2
3
  resolvePostLoginRedirect
3
- } from "./chunk-T2M5MVPE.js";
4
+ } from "./chunk-JCQ5P7QZ.js";
4
5
 
5
6
  // src/core/config.ts
6
7
  function normalizeAuthKitConfig(config) {
@@ -735,15 +736,20 @@ function mapProfileToAuthUser(profile, adapter) {
735
736
  const typedProfile = profile;
736
737
  const email = typedProfile.email || null;
737
738
  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
- };
739
+ return buildAuthUserFromProfile(
740
+ {
741
+ id: typedProfile.id,
742
+ sub: typedProfile.sub,
743
+ name: typedProfile.name,
744
+ displayName: typedProfile.displayName,
745
+ email,
746
+ picture: typedProfile.picture,
747
+ avatarUrl: typedProfile.avatarUrl,
748
+ isAdmin: typedProfile.isAdmin,
749
+ role: typedProfile.role
750
+ },
751
+ isAdmin
752
+ );
747
753
  }
748
754
  function getRedirectTarget(request, user, adapter) {
749
755
  const adapterRedirect = adapter?.resolvePostLoginRedirect?.(user);
@@ -836,6 +842,7 @@ async function createCallbackResponse(request, options) {
836
842
  accessToken,
837
843
  expiresAt: tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : decodedAccessToken?.exp,
838
844
  isAdmin: mappedUser.isAdmin,
845
+ role: mappedUser.role,
839
846
  tokenBalance: mappedUser.tokenBalance,
840
847
  isVip: mappedUser.isVip
841
848
  },
@@ -903,7 +910,8 @@ export {
903
910
  createLoginEntryResponse,
904
911
  createSignupEntryResponse,
905
912
  createAuthorizeEntryResponse,
913
+ mapProfileToAuthUser,
906
914
  createCallbackResponse,
907
915
  createCallbackHandler
908
916
  };
909
- //# sourceMappingURL=chunk-MWXY4JSL.js.map
917
+ //# sourceMappingURL=chunk-IPJT66SK.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/config.ts","../src/core/public-origin.ts","../src/core/request-security.ts","../src/core/auth-redirect.ts","../src/core/admin.ts","../src/core/index-html.ts","../src/core/oauth-state.ts","../src/core/session-token.ts","../src/casdoor/config.ts","../src/casdoor/oauth.ts","../src/casdoor/entry.ts","../src/core/pkce.ts","../src/casdoor/callback.ts"],"sourcesContent":["import type { AuthKitConfig } from '../types';\n\nexport function normalizeAuthKitConfig(config: AuthKitConfig): AuthKitConfig {\n return {\n ...config,\n casdoor: {\n redirectPath: '/callback',\n signinPath: '/login/oauth/authorize',\n ...config.casdoor\n },\n cookie: {\n secure: 'auto',\n ...config.cookie\n },\n session: {\n maxAgeSeconds: 60 * 60 * 24 * 7,\n ...config.session\n }\n };\n}\n","export const PUBLIC_ORIGIN_COOKIE_NAME = 'auth_origin';\n\nexport function getRequestOrigin(request: Request, appUrl?: string): string {\n if (appUrl) {\n try {\n return new URL(appUrl).origin;\n } catch {\n // ignore and fall back to request headers\n }\n }\n\n const referer = request.headers.get('referer');\n if (referer) {\n try {\n return new URL(referer).origin;\n } catch {\n // ignore\n }\n }\n\n const origin = request.headers.get('origin');\n if (origin) {\n try {\n return new URL(origin).origin;\n } catch {\n // ignore\n }\n }\n\n const forwardedProto = request.headers.get('x-forwarded-proto')?.split(',')[0]?.trim();\n const forwardedHost = request.headers.get('x-forwarded-host')?.split(',')[0]?.trim();\n if (forwardedProto && forwardedHost) {\n return `${forwardedProto}://${forwardedHost}`;\n }\n\n return new URL(request.url).origin;\n}\n\nexport function setPublicOriginCookie(response: { cookies: { set: (...args: any[]) => void } }, origin: string, secure: boolean) {\n response.cookies.set(PUBLIC_ORIGIN_COOKIE_NAME, origin, {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n });\n}\n\nexport function clearPublicOriginCookie(response: { cookies: { set: (...args: any[]) => void } }, secure: boolean) {\n response.cookies.set(PUBLIC_ORIGIN_COOKIE_NAME, '', {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n maxAge: 0,\n });\n}\n\nexport function getStoredPublicOrigin(request: Request): string | null {\n const cookieHeader = request.headers.get('cookie');\n if (!cookieHeader) {\n return null;\n }\n\n for (const entry of cookieHeader.split(';')) {\n const [rawName, ...valueParts] = entry.trim().split('=');\n if (rawName === PUBLIC_ORIGIN_COOKIE_NAME) {\n const value = valueParts.join('=').trim();\n if (!value) {\n return null;\n }\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n }\n }\n\n return null;\n}\n","export function isSecureRequest(request: Request, appUrl?: string): boolean {\n const url = new URL(request.url);\n if (url.protocol === 'https:') return true;\n\n const forwardedProto = request.headers.get('x-forwarded-proto')?.split(',')[0]?.trim().toLowerCase();\n if (forwardedProto === 'https') return true;\n\n if (appUrl) {\n try {\n return new URL(appUrl).protocol === 'https:';\n } catch {\n return false;\n }\n }\n\n return false;\n}\n","export const AUTH_REDIRECT_COOKIE_NAME = 'auth_redirect';\n\nexport function getAuthRedirectTarget(request: Request): string | null {\n const cookieHeader = request.headers.get('cookie');\n if (!cookieHeader) {\n return null;\n }\n\n for (const entry of cookieHeader.split(';')) {\n const [rawName, ...valueParts] = entry.trim().split('=');\n if (rawName === AUTH_REDIRECT_COOKIE_NAME) {\n const value = valueParts.join('=').trim();\n if (!value) {\n return null;\n }\n let decoded = value;\n try {\n decoded = decodeURIComponent(value);\n } catch {\n // ignore\n }\n if (decoded.startsWith('/') && !decoded.startsWith('//')) {\n return decoded;\n }\n return null;\n }\n }\n\n return null;\n}\n\nexport function setAuthRedirectCookie(\n response: { cookies: { set: (...args: any[]) => void } },\n target: string,\n secure: boolean,\n) {\n response.cookies.set(AUTH_REDIRECT_COOKIE_NAME, target, {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n });\n}\n\nexport function clearAuthRedirectCookie(\n response: { cookies: { set: (...args: any[]) => void } },\n secure: boolean,\n) {\n response.cookies.set(AUTH_REDIRECT_COOKIE_NAME, '', {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n maxAge: 0,\n });\n}\n","const DEFAULT_ADMIN_EMAILS = ['admin@example.com'];\n\nfunction readAdminEmailSource(): string {\n return process.env.GLOBAL_ADMIN_EMAILS || process.env.ADMIN_EMAILS || '';\n}\n\nexport function getGlobalAdminEmails(): string[] {\n const source = readAdminEmailSource();\n if (!source) {\n return DEFAULT_ADMIN_EMAILS;\n }\n\n return source\n .split(',')\n .map((value) => value.trim().toLowerCase())\n .filter(Boolean);\n}\n\nexport function isGlobalAdminEmail(email: string | null | undefined): boolean {\n if (!email) {\n return false;\n }\n\n return getGlobalAdminEmails().includes(email.toLowerCase());\n}\n","import type { AuthIndexHtmlOptions } from '../types';\n\nconst DEFAULT_CASDOOR_STATIC_ORIGIN = 'https://casdoor-static.foldspace.cn';\nconst DEFAULT_CASDOOR_ORIGIN = process.env.NEXT_PUBLIC_CASDOOR_SERVER_URL || 'https://auth.heyaai.com';\n\nconst DEFAULT_ICON_HREF = 'https://cdn.casbin.org/img/favicon.png';\nconst DEFAULT_MANIFEST_HREF = '/manifest.json';\n\nfunction escapeHtmlAttribute(value: string): string {\n return value.replaceAll('&', '&amp;').replaceAll('\"', '&quot;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');\n}\n\nexport function createAuthIndexHtml(options: AuthIndexHtmlOptions = {}): string {\n const staticOrigin = options.staticOrigin || DEFAULT_CASDOOR_STATIC_ORIGIN;\n const casdoorOrigin = options.casdoorOrigin || DEFAULT_CASDOOR_ORIGIN;\n const apiProxyPrefix = options.apiProxyPrefix || '/auth/';\n const appName = options.appName || '创小剧 AI';\n const organizationName = options.organizationName || 'built-in';\n const description = options.description || '创小剧 AI 登录 - 一个支持 OAuth 2.0、OIDC、SAML 和 CAS 的身份与单点登录平台';\n const iconHref = options.iconHref || DEFAULT_ICON_HREF;\n const manifestHref = options.manifestHref || DEFAULT_MANIFEST_HREF;\n const mainJs = `${staticOrigin}/static/js/main.5ddbc6ff.js`;\n const mainCss = `${staticOrigin}/static/css/main.f35879a1.css`;\n\n return String.raw`<!doctype html>\n<html lang=\"zh-CN\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n <meta name=\"theme-color\" content=\"#000000\" />\n <meta name=\"description\" content=\"${escapeHtmlAttribute(description)}\" />\n <link rel=\"apple-touch-icon\" href=\"${escapeHtmlAttribute(iconHref)}\" />\n <link rel=\"manifest\" href=\"${escapeHtmlAttribute(manifestHref)}\" />\n <title>${escapeHtmlAttribute(appName)}</title>\n <script>\n (function () {\n var cdnOrigin = ${JSON.stringify(staticOrigin)}\n var casdoorOrigin = ${JSON.stringify(casdoorOrigin)}\n var currentOrigin = window.location.origin\n var proxyPrefix = ${JSON.stringify(apiProxyPrefix)}\n var proxyPathPrefix = proxyPrefix.replace(/\\/$/, '')\n var applicationId = ${JSON.stringify((options.organizationName || 'built-in') + '/' + (options.appName || '创小剧 AI'))}\n\n function toProxyUrl(input) {\n try {\n var url = typeof input === 'string' ? new URL(input, window.location.href) : input instanceof URL ? input : null\n if (!url) {\n return input\n }\n\n if (url.origin === cdnOrigin && url.pathname.indexOf(proxyPrefix) === 0) {\n return currentOrigin + url.pathname + url.search + url.hash\n }\n\n if (url.origin === currentOrigin && url.pathname.indexOf('/static/') === 0) {\n return cdnOrigin + url.pathname + url.search + url.hash\n }\n\n if (url.origin === currentOrigin && (url.pathname === '/auth' || url.pathname.indexOf('/auth/') === 0)) {\n if (url.pathname === '/auth/api/get-application') {\n url.searchParams.set('id', applicationId)\n }\n return currentOrigin + proxyPathPrefix + url.pathname.slice('/auth'.length) + url.search + url.hash\n }\n\n if (url.origin === casdoorOrigin) {\n return currentOrigin + proxyPathPrefix + url.pathname + url.search + url.hash\n }\n } catch (error) {\n return input\n }\n\n return input\n }\n\n function rewriteElement(element) {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return\n }\n\n if (element.tagName === 'A' && element.getAttribute('href')) {\n var href = element.getAttribute('href')\n var rewrittenHref = toProxyUrl(href)\n if (rewrittenHref !== href) {\n element.setAttribute('href', rewrittenHref)\n }\n }\n\n if (element.tagName === 'FORM' && element.getAttribute('action')) {\n var action = element.getAttribute('action')\n var rewrittenAction = toProxyUrl(action)\n if (rewrittenAction !== action) {\n element.setAttribute('action', rewrittenAction)\n }\n }\n\n if (element.tagName === 'SCRIPT' && element.getAttribute('src')) {\n var scriptSrc = element.getAttribute('src')\n var rewrittenScriptSrc = toProxyUrl(scriptSrc)\n if (rewrittenScriptSrc !== scriptSrc) {\n element.setAttribute('src', rewrittenScriptSrc)\n }\n }\n\n if (element.tagName === 'LINK' && element.getAttribute('href')) {\n var linkHref = element.getAttribute('href')\n var rewrittenLinkHref = toProxyUrl(linkHref)\n if (rewrittenLinkHref !== linkHref) {\n element.setAttribute('href', rewrittenLinkHref)\n }\n }\n\n if (element.tagName === 'IMG' && element.getAttribute('src')) {\n var imgSrc = element.getAttribute('src')\n var rewrittenImgSrc = toProxyUrl(imgSrc)\n if (rewrittenImgSrc !== imgSrc) {\n element.setAttribute('src', rewrittenImgSrc)\n }\n }\n\n if (typeof element.querySelectorAll === 'function') {\n element.querySelectorAll('a[href], form[action], script[src], link[href], img[src]').forEach(rewriteElement)\n }\n }\n\n if (typeof window.fetch === 'function') {\n var originalFetch = window.fetch.bind(window)\n window.fetch = function (input, init) {\n return originalFetch(toProxyUrl(input), init)\n }\n }\n\n if (window.XMLHttpRequest && window.XMLHttpRequest.prototype) {\n var originalOpen = window.XMLHttpRequest.prototype.open\n window.XMLHttpRequest.prototype.open = function (method, url) {\n var rewrittenUrl = toProxyUrl(url)\n return originalOpen.apply(this, [method, rewrittenUrl].concat(Array.prototype.slice.call(arguments, 2)))\n }\n }\n\n if (window.open) {\n var originalOpenWindow = window.open.bind(window)\n window.open = function (url) {\n return originalOpenWindow(toProxyUrl(url), arguments[1], arguments[2])\n }\n }\n\n if (window.location && typeof window.location.assign === 'function') {\n var originalAssign = window.location.assign.bind(window.location)\n window.location.assign = function (url) {\n return originalAssign(toProxyUrl(url))\n }\n }\n\n if (window.location && typeof window.location.replace === 'function') {\n var originalReplace = window.location.replace.bind(window.location)\n window.location.replace = function (url) {\n return originalReplace(toProxyUrl(url))\n }\n }\n\n if (window.HTMLFormElement && window.HTMLFormElement.prototype) {\n var originalSubmit = window.HTMLFormElement.prototype.submit\n window.HTMLFormElement.prototype.submit = function () {\n if (this.action) {\n this.action = toProxyUrl(this.action)\n }\n return originalSubmit.apply(this, arguments)\n }\n }\n\n document.addEventListener('click', function (event) {\n var target = event.target instanceof Element ? event.target.closest('a[href]') : null\n if (!target) {\n return\n }\n\n var href = target.getAttribute('href')\n var rewritten = toProxyUrl(href)\n if (rewritten !== href) {\n event.preventDefault()\n window.location.href = rewritten\n }\n }, true)\n\n document.addEventListener('submit', function (event) {\n var form = event.target instanceof HTMLFormElement ? event.target : null\n if (!form || !form.action) {\n return\n }\n\n var rewritten = toProxyUrl(form.action)\n if (rewritten !== form.action) {\n event.preventDefault()\n form.action = rewritten\n form.submit()\n }\n }, true)\n\n var originalAppendChild = Node.prototype.appendChild\n Node.prototype.appendChild = function (node) {\n rewriteElement(node)\n return originalAppendChild.call(this, node)\n }\n\n var originalInsertBefore = Node.prototype.insertBefore\n Node.prototype.insertBefore = function (node, referenceNode) {\n rewriteElement(node)\n return originalInsertBefore.call(this, node, referenceNode)\n }\n\n if (document.body) {\n rewriteElement(document.body)\n }\n\n if (window.MutationObserver) {\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(rewriteElement)\n })\n })\n observer.observe(document.documentElement, { childList: true, subtree: true })\n }\n })()\n </script>\n <script defer=\"defer\" src=\"${escapeHtmlAttribute(mainJs)}\"></script>\n <link href=\"${escapeHtmlAttribute(mainCss)}\" rel=\"stylesheet\" />\n </head>\n <body>\n <noscript>你需要启用 JavaScript 才能继续。</noscript>\n <div id=\"root\"></div>\n </body>\n</html>\n`;\n}\n\nexport const AUTH_INDEX_HTML = createAuthIndexHtml();\n","import { Buffer } from 'node:buffer';\nimport crypto from 'node:crypto';\n\nconst STATE_EXPIRY_SECONDS = 600;\nconst STATE_SECRET =\n process.env.NEXTAUTH_SECRET || process.env.CASDOOR_CLIENT_SECRET || 'dev-state-secret';\n\nexport const pkceCookiePrefix = 'pkce_code_verifier';\n\nexport interface StatePayload {\n nonce: string;\n issuedAt: number;\n}\n\nfunction signStatePayload(payload: StatePayload): string {\n const body = Buffer.from(JSON.stringify(payload)).toString('base64url');\n const signature = crypto.createHmac('sha256', STATE_SECRET).update(body).digest('base64url');\n return `${body}.${signature}`;\n}\n\nfunction decodeStatePayload(state: string): StatePayload | null {\n const [body, signature] = state.split('.');\n\n if (!body || !signature) {\n return null;\n }\n\n const expectedSignature = crypto.createHmac('sha256', STATE_SECRET).update(body).digest('base64url');\n\n if (\n expectedSignature.length !== signature.length ||\n !crypto.timingSafeEqual(Buffer.from(expectedSignature), Buffer.from(signature))\n ) {\n return null;\n }\n\n try {\n return JSON.parse(Buffer.from(body, 'base64url').toString('utf8')) as StatePayload;\n } catch {\n return null;\n }\n}\n\nexport function generateStateToken(): string {\n return signStatePayload({\n nonce: crypto.randomUUID(),\n issuedAt: Date.now(),\n });\n}\n\nexport function getPkceCookieName(state: string): string {\n const digest = crypto.createHash('sha256').update(state).digest('base64url');\n return `${pkceCookiePrefix}.${digest}`;\n}\n\nexport async function verifyState(stateFromUrl: string): Promise<boolean> {\n const payload = decodeStatePayload(stateFromUrl);\n if (!payload) {\n return false;\n }\n\n return Date.now() - payload.issuedAt <= STATE_EXPIRY_SECONDS * 1000;\n}\n\nexport function parseStateToken(token: string | null | undefined): StatePayload | null {\n if (!token) return null;\n return decodeStatePayload(token);\n}\n\nexport function verifyStateToken(token: string | null | undefined): boolean {\n if (!token) return false;\n return Boolean(decodeStatePayload(token));\n}\n","import { Buffer } from 'node:buffer';\nimport crypto from 'node:crypto';\nimport type { JWT, JWTDecodeParams, JWTEncodeParams } from 'next-auth/jwt';\n\nconst DEFAULT_MAX_AGE = 30 * 24 * 60 * 60;\n\nfunction base64UrlEncode(value: string): string {\n return Buffer.from(value, 'utf8').toString('base64url');\n}\n\nfunction base64UrlDecode(value: string): string {\n return Buffer.from(value, 'base64url').toString('utf8');\n}\n\nfunction createSignature(input: string, secret: string | Buffer): string {\n return crypto.createHmac('sha256', secret).update(input).digest('base64url');\n}\n\nfunction timingSafeEqual(left: string, right: string): boolean {\n const leftBuffer = Buffer.from(left);\n const rightBuffer = Buffer.from(right);\n\n if (leftBuffer.length !== rightBuffer.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(leftBuffer, rightBuffer);\n}\n\nexport async function encodeSessionToken(params: JWTEncodeParams): Promise<string> {\n const { token = {}, secret, maxAge = DEFAULT_MAX_AGE } = params;\n const issuedAt = Math.floor(Date.now() / 1000);\n const header = base64UrlEncode(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));\n const payload = base64UrlEncode(\n JSON.stringify({\n ...token,\n iat: issuedAt,\n exp: issuedAt + maxAge,\n jti: crypto.randomUUID(),\n }),\n );\n const signature = createSignature(`${header}.${payload}`, secret);\n\n return `${header}.${payload}.${signature}`;\n}\n\nexport async function decodeSessionToken(params: JWTDecodeParams): Promise<JWT | null> {\n const { token, secret } = params;\n\n if (!token) {\n return null;\n }\n\n const [header, payload, signature] = token.split('.');\n\n if (!header || !payload || !signature) {\n return null;\n }\n\n const expectedSignature = createSignature(`${header}.${payload}`, secret);\n\n if (!timingSafeEqual(signature, expectedSignature)) {\n return null;\n }\n\n try {\n const parsedPayload = JSON.parse(base64UrlDecode(payload)) as JWT & { exp?: number };\n\n if (parsedPayload.exp && parsedPayload.exp <= Math.floor(Date.now() / 1000)) {\n return null;\n }\n\n return parsedPayload;\n } catch {\n return null;\n }\n}\n","import type { AuthKitConfig } from '../types';\nimport { normalizeAuthKitConfig } from '../core/config';\n\nexport function getCasdoorConfig(config: AuthKitConfig): AuthKitConfig {\n return normalizeAuthKitConfig(config);\n}\n\nexport function getCasdoorAuthorizeUrl(config: AuthKitConfig, params: { state: string; codeChallenge: string; redirectUri: string; kind: 'login' | 'signup' }): string {\n const base = new URL(config.casdoor.signinPath ?? '/login/oauth/authorize', config.casdoor.serverUrl);\n base.searchParams.set('response_type', 'code');\n base.searchParams.set('client_id', config.casdoor.clientId);\n base.searchParams.set('redirect_uri', params.redirectUri);\n base.searchParams.set('scope', 'profile');\n base.searchParams.set('state', params.state);\n base.searchParams.set('code_challenge', params.codeChallenge);\n base.searchParams.set('code_challenge_method', 'S256');\n if (params.kind === 'signup') {\n base.searchParams.set('action', 'signup');\n }\n return base.toString();\n}\n\nexport function getCasdoorTokenUrl(config: AuthKitConfig): string {\n return new URL('/api/login/oauth/access_token', config.casdoor.serverUrl).toString();\n}\n\nexport function getCasdoorUserInfoUrl(config: AuthKitConfig): string {\n return new URL('/api/userinfo', config.casdoor.serverUrl).toString();\n}\n","import type { AuthKitConfig, CasdoorUserInfo, OAuthTokens } from '../types';\nimport { getCasdoorTokenUrl, getCasdoorUserInfoUrl } from './config';\nimport { Buffer } from 'node:buffer';\n\nfunction decodeJwtPayload(token: string): Record<string, unknown> | null {\n const parts = token.split('.');\n if (parts.length < 2) {\n return null;\n }\n\n try {\n const payload = parts[1];\n return JSON.parse(Buffer.from(payload, 'base64url').toString('utf8')) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport async function exchangeCodeForToken(config: AuthKitConfig, code: string, redirectUri: string, codeVerifier: string): Promise<OAuthTokens> {\n const response = await fetch(getCasdoorTokenUrl(config), {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n client_id: config.casdoor.clientId,\n client_secret: config.casdoor.clientSecret,\n code,\n redirect_uri: redirectUri,\n code_verifier: codeVerifier\n })\n });\n if (!response.ok) {\n throw new Error('Failed to exchange Casdoor authorization code.');\n }\n return (await response.json()) as OAuthTokens;\n}\n\nexport async function fetchCasdoorUserInfo(config: AuthKitConfig, accessToken: string): Promise<CasdoorUserInfo> {\n const response = await fetch(getCasdoorUserInfoUrl(config), {\n headers: {\n authorization: 'Bearer ' + accessToken\n }\n });\n if (!response.ok) {\n throw new Error('Failed to fetch Casdoor user profile.');\n }\n return (await response.json()) as CasdoorUserInfo;\n}\n\nexport function decodeCasdoorAccessToken(accessToken: string): Record<string, unknown> | null {\n return decodeJwtPayload(accessToken);\n}\n\nexport const exchangeCasdoorOAuthToken = exchangeCodeForToken;\n","import { NextResponse, type NextRequest } from 'next/server';\nimport type { AuthKitConfig } from '../types';\nimport { normalizeAuthKitConfig } from '../core/config';\nimport { getRequestOrigin, setPublicOriginCookie } from '../core/public-origin';\nimport { isSecureRequest } from '../core/request-security';\nimport { createPkcePair } from '../core/pkce';\nimport { generateStateToken, getPkceCookieName } from '../core/oauth-state';\nimport { getAuthRedirectTarget, setAuthRedirectCookie } from '../core/auth-redirect';\nimport { createAuthIndexHtml } from '../core/index-html';\n\nfunction buildLocalAuthorizeUrl(\n origin: string,\n config: AuthKitConfig,\n params: { state: string; codeChallenge: string; kind: 'login' | 'signup' },\n): string {\n const normalized = normalizeAuthKitConfig(config);\n const authorizePath =\n params.kind === 'signup'\n ? '/signup/oauth/authorize'\n : normalized.casdoor.signinPath || '/login/oauth/authorize';\n const authorizeUrl = new URL(authorizePath, origin);\n authorizeUrl.searchParams.set('response_type', 'code');\n authorizeUrl.searchParams.set('client_id', normalized.casdoor.clientId);\n authorizeUrl.searchParams.set('redirect_uri', `${origin}${normalized.casdoor.redirectPath || '/callback'}`);\n authorizeUrl.searchParams.set('scope', 'profile');\n authorizeUrl.searchParams.set('state', params.state);\n authorizeUrl.searchParams.set('code_challenge', params.codeChallenge);\n authorizeUrl.searchParams.set('code_challenge_method', 'S256');\n return authorizeUrl.toString();\n}\n\nasync function createRedirectEntryResponse(\n request: NextRequest,\n config: AuthKitConfig,\n kind: 'login' | 'signup',\n): Promise<NextResponse> {\n const normalized = normalizeAuthKitConfig(config);\n const origin = getRequestOrigin(request, normalized.appUrl);\n const secure =\n normalized.cookie?.secure === 'auto' ? isSecureRequest(request, normalized.appUrl) : Boolean(normalized.cookie?.secure);\n const { verifier, challenge } = await createPkcePair();\n const state = generateStateToken();\n const response = NextResponse.redirect(\n buildLocalAuthorizeUrl(origin, normalized, { state, codeChallenge: challenge, kind }),\n 307,\n );\n const redirectTarget = getAuthRedirectTarget(request);\n if (redirectTarget) {\n setAuthRedirectCookie(response, redirectTarget, secure);\n }\n setPublicOriginCookie(response, origin, secure);\n response.cookies.set('oauth_state', state, { httpOnly: true, sameSite: 'lax', secure, path: '/' });\n response.cookies.set(getPkceCookieName(state), verifier, { httpOnly: true, sameSite: 'lax', secure, path: '/' });\n return response;\n}\n\nasync function createAuthorizePageResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse> {\n const normalized = normalizeAuthKitConfig(config);\n const origin = getRequestOrigin(request, normalized.appUrl);\n const secure =\n normalized.cookie?.secure === 'auto' ? isSecureRequest(request, normalized.appUrl) : Boolean(normalized.cookie?.secure);\n const response = new NextResponse(\n createAuthIndexHtml({\n appName: normalized.casdoor.appName,\n organizationName: normalized.casdoor.organizationName,\n staticOrigin: process.env.NEXT_PUBLIC_CASDOOR_STATIC_ORIGIN,\n casdoorOrigin: normalized.casdoor.serverUrl,\n apiProxyPrefix: '/auth/',\n }),\n {\n status: 200,\n headers: {\n 'content-type': 'text/html; charset=utf-8',\n 'cache-control': 'no-store, max-age=0',\n },\n },\n );\n setPublicOriginCookie(response, origin, secure);\n return response;\n}\n\nexport async function createLoginEntryResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse> {\n return createRedirectEntryResponse(request, config, 'login');\n}\n\nexport async function createSignupEntryResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse> {\n return createRedirectEntryResponse(request, config, 'signup');\n}\n\nexport async function createAuthorizeEntryResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse> {\n return createAuthorizePageResponse(request, config);\n}\n","const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';\n\nfunction toBase64Url(bytes: ArrayBuffer): string {\n const raw = Buffer.from(bytes).toString('base64');\n return raw.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/g, '');\n}\n\nexport async function createPkcePair(): Promise<{ verifier: string; challenge: string }> {\n const bytes = crypto.getRandomValues(new Uint8Array(48));\n const verifier = Array.from(bytes, (byte) => chars[byte % chars.length]).join('');\n const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));\n return { verifier, challenge: toBase64Url(digest) };\n}\n","import { NextResponse, type NextRequest } from 'next/server';\nimport type { AuthBusinessAdapter, AuthKitConfig, AuthPersistenceAdapter, AuthUser } from '../types';\nimport { normalizeAuthKitConfig } from '../core/config';\nimport { getRequestOrigin, getStoredPublicOrigin, clearPublicOriginCookie } from '../core/public-origin';\nimport { isSecureRequest } from '../core/request-security';\nimport { getAuthRedirectTarget, clearAuthRedirectCookie } from '../core/auth-redirect';\nimport {\n decodeCasdoorAccessToken,\n exchangeCasdoorOAuthToken,\n fetchCasdoorUserInfo,\n} from './oauth';\nimport { getCasdoorConfig } from './config';\nimport { getPkceCookieName, verifyState } from '../core/oauth-state';\nimport { encodeSessionToken } from '../core/session-token';\nimport { isGlobalAdminEmail } from '../core/admin';\nimport { resolvePostLoginRedirect } from '../core/redirect';\n\nexport interface CallbackHandlerOptions {\n config: AuthKitConfig;\n adapter?: AuthBusinessAdapter;\n persistence?: AuthPersistenceAdapter;\n}\n\nfunction readCookieHeaderValue(cookieHeader: string | null, name: string): string | null {\n if (!cookieHeader) {\n return null;\n }\n\n for (const entry of cookieHeader.split(';')) {\n const [rawName, ...valueParts] = entry.trim().split('=');\n if (rawName === name) {\n const value = valueParts.join('=').trim();\n return value || null;\n }\n }\n\n return null;\n}\n\nfunction getPublicOrigin(request: NextRequest, config: AuthKitConfig): string {\n return getStoredPublicOrigin(request) || getRequestOrigin(request, config.appUrl);\n}\n\nfunction rewriteToCallbackErrorPage(\n request: NextRequest,\n config: AuthKitConfig,\n title: string,\n message: string,\n details?: string,\n): NextResponse {\n const origin = getPublicOrigin(request, config);\n const targetUrl = new URL('/callback/error', origin);\n targetUrl.searchParams.set('title', title);\n targetUrl.searchParams.set('message', message);\n\n if (details) {\n targetUrl.searchParams.set('details', details);\n }\n\n return NextResponse.redirect(targetUrl, 307);\n}\n\nfunction getPkceCodeVerifier(request: NextRequest, state: string): string | null {\n return readCookieHeaderValue(request.headers.get('cookie'), getPkceCookieName(state));\n}\n\nfunction setNextAuthSessionCookies(response: NextResponse, sessionToken: string, isSecure: boolean): void {\n const cookieName = isSecure ? '__Secure-next-auth.session-token' : 'next-auth.session-token';\n const expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);\n const baseOptions = {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n secure: isSecure,\n expires,\n };\n const maxCookieSize = 3933;\n\n if (sessionToken.length <= maxCookieSize) {\n response.cookies.set(cookieName, sessionToken, baseOptions);\n return;\n }\n\n const chunkCount = Math.ceil(sessionToken.length / maxCookieSize);\n for (let index = 0; index < chunkCount; index++) {\n response.cookies.set(\n `${cookieName}.${index}`,\n sessionToken.slice(index * maxCookieSize, (index + 1) * maxCookieSize),\n baseOptions,\n );\n }\n}\n\nfunction sanitizeRedirectPath(value: string | null): string {\n if (!value || !value.startsWith('/') || value.startsWith('//')) {\n return '/user/account';\n }\n\n return value;\n}\n\nfunction summarizeCookieHeader(cookieHeader: string | null): Record<string, unknown> {\n if (!cookieHeader) {\n return { present: false };\n }\n\n const cookieNames = cookieHeader\n .split(';')\n .map((entry) => entry.trim().split('=')[0])\n .filter(Boolean);\n\n return {\n present: true,\n count: cookieNames.length,\n names: cookieNames,\n };\n}\n\nfunction mapProfileToAuthUser(profile: Awaited<ReturnType<typeof fetchCasdoorUserInfo>>, adapter?: AuthBusinessAdapter): AuthUser {\n const typedProfile = profile as Awaited<ReturnType<typeof fetchCasdoorUserInfo>> & {\n sub?: string;\n picture?: string;\n avatarUrl?: string;\n };\n const email = typedProfile.email || null;\n const isAdmin =\n Boolean(typedProfile.isAdmin) ||\n Boolean(adapter?.isAdminEmail?.(email)) ||\n isGlobalAdminEmail(email);\n\n return {\n id: typedProfile.sub || typedProfile.id || typedProfile.email || 'casdoor-user',\n name: typedProfile.name || typedProfile.displayName || null,\n email,\n image: typedProfile.picture || typedProfile.avatarUrl || null,\n isAdmin,\n tokenBalance: 2580,\n isVip: true,\n };\n}\n\nfunction getRedirectTarget(request: NextRequest, user: AuthUser, adapter?: AuthBusinessAdapter): string {\n const adapterRedirect = adapter?.resolvePostLoginRedirect?.(user);\n if (adapterRedirect) {\n return sanitizeRedirectPath(adapterRedirect);\n }\n\n const storedRedirect = getAuthRedirectTarget(request);\n if (storedRedirect) {\n return sanitizeRedirectPath(storedRedirect);\n }\n\n return sanitizeRedirectPath(resolvePostLoginRedirect(user, '/user/account'));\n}\n\nexport async function createCallbackResponse(\n request: NextRequest,\n options: CallbackHandlerOptions,\n): Promise<NextResponse> {\n const normalized = normalizeAuthKitConfig(options.config);\n const publicOrigin = getPublicOrigin(request, normalized);\n const url = new URL(request.url);\n const code = url.searchParams.get('code');\n const state = url.searchParams.get('state');\n const error = url.searchParams.get('error');\n const secure = normalized.cookie?.secure === 'auto'\n ? isSecureRequest(request, normalized.appUrl)\n : Boolean(normalized.cookie?.secure);\n\n if (error) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n 'Casdoor 返回了授权错误',\n '授权服务器在回调阶段返回了错误信息。请返回首页或重新登录后再试。',\n error,\n );\n }\n\n if (!code) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n '缺少授权码',\n 'Casdoor 回调没有带回 code,这通常意味着授权流程未完成。',\n 'no_code',\n );\n }\n\n if (!state || !(await verifyState(state))) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n '登录状态校验失败',\n '回调中的 state 与本次登录流程不匹配,请重新发起登录。',\n 'invalid_state',\n );\n }\n\n const codeVerifier = getPkceCodeVerifier(request, state);\n if (!codeVerifier) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n '缺少 PKCE 校验值',\n '回调请求里没有找到 pkce_code_verifier cookie。请重新从登录入口发起流程。',\n 'missing_pkce_code_verifier',\n );\n }\n\n const casdoorConfig = getCasdoorConfig(normalized);\n const redirectUri = `${publicOrigin}${casdoorConfig.casdoor.redirectPath}`;\n const tokens = await exchangeCasdoorOAuthToken(casdoorConfig, code, redirectUri, codeVerifier);\n const accessToken = tokens.access_token ?? tokens.accessToken ?? '';\n\n if (!accessToken) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n '缺少访问令牌',\n 'Casdoor 回调没有返回 access token。',\n 'missing_access_token',\n );\n }\n\n const profile = await fetchCasdoorUserInfo(casdoorConfig, accessToken);\n\n const decodedAccessToken = decodeCasdoorAccessToken(accessToken) as { exp?: number } | null;\n const mappedUser = options.adapter?.onUserSync\n ? await options.adapter.onUserSync(profile, {\n accessToken,\n refreshToken: tokens.refresh_token || tokens.refreshToken,\n idToken: tokens.id_token || tokens.idToken,\n expiresAt: tokens.expires_in ? Date.now() + tokens.expires_in * 1000 : tokens.expiresAt,\n })\n : mapProfileToAuthUser(profile, options.adapter);\n\n if (options.persistence?.syncAuthUser) {\n await options.persistence.syncAuthUser(mappedUser);\n }\n\n const sessionToken = await encodeSessionToken({\n token: {\n id: mappedUser.id,\n sub: mappedUser.id,\n userId: mappedUser.id,\n name: mappedUser.name,\n email: mappedUser.email,\n picture: mappedUser.image,\n accessToken,\n expiresAt: tokens.expires_in ? Date.now() + tokens.expires_in * 1000 : decodedAccessToken?.exp,\n isAdmin: mappedUser.isAdmin,\n tokenBalance: mappedUser.tokenBalance,\n isVip: mappedUser.isVip,\n },\n secret: normalized.nextauthSecret,\n maxAge: normalized.session?.maxAgeSeconds,\n });\n\n const response = NextResponse.redirect(new URL(getRedirectTarget(request, mappedUser, options.adapter), publicOrigin));\n setNextAuthSessionCookies(response, sessionToken, secure);\n response.cookies.set(getPkceCookieName(state), '', {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n maxAge: 0,\n });\n response.cookies.set('oauth_state', '', {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n maxAge: 0,\n });\n clearAuthRedirectCookie(response, secure);\n clearPublicOriginCookie(response, secure);\n return response;\n}\n\nexport function createCallbackHandler(options: CallbackHandlerOptions) {\n return async function GET(request: NextRequest) {\n return createCallbackResponse(request, options);\n };\n}\n"],"mappings":"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","names":["Buffer","crypto","Buffer","crypto","Buffer","NextResponse","NextResponse","NextResponse"]}
1
+ {"version":3,"sources":["../src/core/config.ts","../src/core/public-origin.ts","../src/core/request-security.ts","../src/core/auth-redirect.ts","../src/core/admin.ts","../src/core/index-html.ts","../src/core/oauth-state.ts","../src/core/session-token.ts","../src/casdoor/config.ts","../src/casdoor/oauth.ts","../src/casdoor/entry.ts","../src/core/pkce.ts","../src/casdoor/callback.ts"],"sourcesContent":["import type { AuthKitConfig } from '../types';\n\nexport function normalizeAuthKitConfig(config: AuthKitConfig): AuthKitConfig {\n return {\n ...config,\n casdoor: {\n redirectPath: '/callback',\n signinPath: '/login/oauth/authorize',\n ...config.casdoor\n },\n cookie: {\n secure: 'auto',\n ...config.cookie\n },\n session: {\n maxAgeSeconds: 60 * 60 * 24 * 7,\n ...config.session\n }\n };\n}\n","export const PUBLIC_ORIGIN_COOKIE_NAME = 'auth_origin';\n\nexport function getRequestOrigin(request: Request, appUrl?: string): string {\n if (appUrl) {\n try {\n return new URL(appUrl).origin;\n } catch {\n // ignore and fall back to request headers\n }\n }\n\n const referer = request.headers.get('referer');\n if (referer) {\n try {\n return new URL(referer).origin;\n } catch {\n // ignore\n }\n }\n\n const origin = request.headers.get('origin');\n if (origin) {\n try {\n return new URL(origin).origin;\n } catch {\n // ignore\n }\n }\n\n const forwardedProto = request.headers.get('x-forwarded-proto')?.split(',')[0]?.trim();\n const forwardedHost = request.headers.get('x-forwarded-host')?.split(',')[0]?.trim();\n if (forwardedProto && forwardedHost) {\n return `${forwardedProto}://${forwardedHost}`;\n }\n\n return new URL(request.url).origin;\n}\n\nexport function setPublicOriginCookie(response: { cookies: { set: (...args: any[]) => void } }, origin: string, secure: boolean) {\n response.cookies.set(PUBLIC_ORIGIN_COOKIE_NAME, origin, {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n });\n}\n\nexport function clearPublicOriginCookie(response: { cookies: { set: (...args: any[]) => void } }, secure: boolean) {\n response.cookies.set(PUBLIC_ORIGIN_COOKIE_NAME, '', {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n maxAge: 0,\n });\n}\n\nexport function getStoredPublicOrigin(request: Request): string | null {\n const cookieHeader = request.headers.get('cookie');\n if (!cookieHeader) {\n return null;\n }\n\n for (const entry of cookieHeader.split(';')) {\n const [rawName, ...valueParts] = entry.trim().split('=');\n if (rawName === PUBLIC_ORIGIN_COOKIE_NAME) {\n const value = valueParts.join('=').trim();\n if (!value) {\n return null;\n }\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n }\n }\n\n return null;\n}\n","export function isSecureRequest(request: Request, appUrl?: string): boolean {\n const url = new URL(request.url);\n if (url.protocol === 'https:') return true;\n\n const forwardedProto = request.headers.get('x-forwarded-proto')?.split(',')[0]?.trim().toLowerCase();\n if (forwardedProto === 'https') return true;\n\n if (appUrl) {\n try {\n return new URL(appUrl).protocol === 'https:';\n } catch {\n return false;\n }\n }\n\n return false;\n}\n","export const AUTH_REDIRECT_COOKIE_NAME = 'auth_redirect';\n\nexport function getAuthRedirectTarget(request: Request): string | null {\n const cookieHeader = request.headers.get('cookie');\n if (!cookieHeader) {\n return null;\n }\n\n for (const entry of cookieHeader.split(';')) {\n const [rawName, ...valueParts] = entry.trim().split('=');\n if (rawName === AUTH_REDIRECT_COOKIE_NAME) {\n const value = valueParts.join('=').trim();\n if (!value) {\n return null;\n }\n let decoded = value;\n try {\n decoded = decodeURIComponent(value);\n } catch {\n // ignore\n }\n if (decoded.startsWith('/') && !decoded.startsWith('//')) {\n return decoded;\n }\n return null;\n }\n }\n\n return null;\n}\n\nexport function setAuthRedirectCookie(\n response: { cookies: { set: (...args: any[]) => void } },\n target: string,\n secure: boolean,\n) {\n response.cookies.set(AUTH_REDIRECT_COOKIE_NAME, target, {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n });\n}\n\nexport function clearAuthRedirectCookie(\n response: { cookies: { set: (...args: any[]) => void } },\n secure: boolean,\n) {\n response.cookies.set(AUTH_REDIRECT_COOKIE_NAME, '', {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n maxAge: 0,\n });\n}\n","const DEFAULT_ADMIN_EMAILS = ['admin@example.com'];\n\nfunction readAdminEmailSource(): string {\n return process.env.GLOBAL_ADMIN_EMAILS || process.env.ADMIN_EMAILS || '';\n}\n\nexport function getGlobalAdminEmails(): string[] {\n const source = readAdminEmailSource();\n if (!source) {\n return DEFAULT_ADMIN_EMAILS;\n }\n\n return source\n .split(',')\n .map((value) => value.trim().toLowerCase())\n .filter(Boolean);\n}\n\nexport function isGlobalAdminEmail(email: string | null | undefined): boolean {\n if (!email) {\n return false;\n }\n\n return getGlobalAdminEmails().includes(email.toLowerCase());\n}\n","import type { AuthIndexHtmlOptions } from '../types';\n\nconst DEFAULT_CASDOOR_STATIC_ORIGIN = 'https://casdoor-static.foldspace.cn';\nconst DEFAULT_CASDOOR_ORIGIN = process.env.NEXT_PUBLIC_CASDOOR_SERVER_URL || 'https://auth.heyaai.com';\n\nconst DEFAULT_ICON_HREF = 'https://cdn.casbin.org/img/favicon.png';\nconst DEFAULT_MANIFEST_HREF = '/manifest.json';\n\nfunction escapeHtmlAttribute(value: string): string {\n return value.replaceAll('&', '&amp;').replaceAll('\"', '&quot;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');\n}\n\nexport function createAuthIndexHtml(options: AuthIndexHtmlOptions = {}): string {\n const staticOrigin = options.staticOrigin || DEFAULT_CASDOOR_STATIC_ORIGIN;\n const casdoorOrigin = options.casdoorOrigin || DEFAULT_CASDOOR_ORIGIN;\n const apiProxyPrefix = options.apiProxyPrefix || '/auth/';\n const appName = options.appName || '创小剧 AI';\n const organizationName = options.organizationName || 'built-in';\n const description = options.description || '创小剧 AI 登录 - 一个支持 OAuth 2.0、OIDC、SAML 和 CAS 的身份与单点登录平台';\n const iconHref = options.iconHref || DEFAULT_ICON_HREF;\n const manifestHref = options.manifestHref || DEFAULT_MANIFEST_HREF;\n const mainJs = `${staticOrigin}/static/js/main.5ddbc6ff.js`;\n const mainCss = `${staticOrigin}/static/css/main.f35879a1.css`;\n\n return String.raw`<!doctype html>\n<html lang=\"zh-CN\">\n <head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n <meta name=\"theme-color\" content=\"#000000\" />\n <meta name=\"description\" content=\"${escapeHtmlAttribute(description)}\" />\n <link rel=\"apple-touch-icon\" href=\"${escapeHtmlAttribute(iconHref)}\" />\n <link rel=\"manifest\" href=\"${escapeHtmlAttribute(manifestHref)}\" />\n <title>${escapeHtmlAttribute(appName)}</title>\n <script>\n (function () {\n var cdnOrigin = ${JSON.stringify(staticOrigin)}\n var casdoorOrigin = ${JSON.stringify(casdoorOrigin)}\n var currentOrigin = window.location.origin\n var proxyPrefix = ${JSON.stringify(apiProxyPrefix)}\n var proxyPathPrefix = proxyPrefix.replace(/\\/$/, '')\n var applicationId = ${JSON.stringify((options.organizationName || 'built-in') + '/' + (options.appName || '创小剧 AI'))}\n\n function toProxyUrl(input) {\n try {\n var url = typeof input === 'string' ? new URL(input, window.location.href) : input instanceof URL ? input : null\n if (!url) {\n return input\n }\n\n if (url.origin === cdnOrigin && url.pathname.indexOf(proxyPrefix) === 0) {\n return currentOrigin + url.pathname + url.search + url.hash\n }\n\n if (url.origin === currentOrigin && url.pathname.indexOf('/static/') === 0) {\n return cdnOrigin + url.pathname + url.search + url.hash\n }\n\n if (url.origin === currentOrigin && (url.pathname === '/auth' || url.pathname.indexOf('/auth/') === 0)) {\n if (url.pathname === '/auth/api/get-application') {\n url.searchParams.set('id', applicationId)\n }\n return currentOrigin + proxyPathPrefix + url.pathname.slice('/auth'.length) + url.search + url.hash\n }\n\n if (url.origin === casdoorOrigin) {\n return currentOrigin + proxyPathPrefix + url.pathname + url.search + url.hash\n }\n } catch (error) {\n return input\n }\n\n return input\n }\n\n function rewriteElement(element) {\n if (!element || element.nodeType !== Node.ELEMENT_NODE) {\n return\n }\n\n if (element.tagName === 'A' && element.getAttribute('href')) {\n var href = element.getAttribute('href')\n var rewrittenHref = toProxyUrl(href)\n if (rewrittenHref !== href) {\n element.setAttribute('href', rewrittenHref)\n }\n }\n\n if (element.tagName === 'FORM' && element.getAttribute('action')) {\n var action = element.getAttribute('action')\n var rewrittenAction = toProxyUrl(action)\n if (rewrittenAction !== action) {\n element.setAttribute('action', rewrittenAction)\n }\n }\n\n if (element.tagName === 'SCRIPT' && element.getAttribute('src')) {\n var scriptSrc = element.getAttribute('src')\n var rewrittenScriptSrc = toProxyUrl(scriptSrc)\n if (rewrittenScriptSrc !== scriptSrc) {\n element.setAttribute('src', rewrittenScriptSrc)\n }\n }\n\n if (element.tagName === 'LINK' && element.getAttribute('href')) {\n var linkHref = element.getAttribute('href')\n var rewrittenLinkHref = toProxyUrl(linkHref)\n if (rewrittenLinkHref !== linkHref) {\n element.setAttribute('href', rewrittenLinkHref)\n }\n }\n\n if (element.tagName === 'IMG' && element.getAttribute('src')) {\n var imgSrc = element.getAttribute('src')\n var rewrittenImgSrc = toProxyUrl(imgSrc)\n if (rewrittenImgSrc !== imgSrc) {\n element.setAttribute('src', rewrittenImgSrc)\n }\n }\n\n if (typeof element.querySelectorAll === 'function') {\n element.querySelectorAll('a[href], form[action], script[src], link[href], img[src]').forEach(rewriteElement)\n }\n }\n\n if (typeof window.fetch === 'function') {\n var originalFetch = window.fetch.bind(window)\n window.fetch = function (input, init) {\n return originalFetch(toProxyUrl(input), init)\n }\n }\n\n if (window.XMLHttpRequest && window.XMLHttpRequest.prototype) {\n var originalOpen = window.XMLHttpRequest.prototype.open\n window.XMLHttpRequest.prototype.open = function (method, url) {\n var rewrittenUrl = toProxyUrl(url)\n return originalOpen.apply(this, [method, rewrittenUrl].concat(Array.prototype.slice.call(arguments, 2)))\n }\n }\n\n if (window.open) {\n var originalOpenWindow = window.open.bind(window)\n window.open = function (url) {\n return originalOpenWindow(toProxyUrl(url), arguments[1], arguments[2])\n }\n }\n\n if (window.location && typeof window.location.assign === 'function') {\n var originalAssign = window.location.assign.bind(window.location)\n window.location.assign = function (url) {\n return originalAssign(toProxyUrl(url))\n }\n }\n\n if (window.location && typeof window.location.replace === 'function') {\n var originalReplace = window.location.replace.bind(window.location)\n window.location.replace = function (url) {\n return originalReplace(toProxyUrl(url))\n }\n }\n\n if (window.HTMLFormElement && window.HTMLFormElement.prototype) {\n var originalSubmit = window.HTMLFormElement.prototype.submit\n window.HTMLFormElement.prototype.submit = function () {\n if (this.action) {\n this.action = toProxyUrl(this.action)\n }\n return originalSubmit.apply(this, arguments)\n }\n }\n\n document.addEventListener('click', function (event) {\n var target = event.target instanceof Element ? event.target.closest('a[href]') : null\n if (!target) {\n return\n }\n\n var href = target.getAttribute('href')\n var rewritten = toProxyUrl(href)\n if (rewritten !== href) {\n event.preventDefault()\n window.location.href = rewritten\n }\n }, true)\n\n document.addEventListener('submit', function (event) {\n var form = event.target instanceof HTMLFormElement ? event.target : null\n if (!form || !form.action) {\n return\n }\n\n var rewritten = toProxyUrl(form.action)\n if (rewritten !== form.action) {\n event.preventDefault()\n form.action = rewritten\n form.submit()\n }\n }, true)\n\n var originalAppendChild = Node.prototype.appendChild\n Node.prototype.appendChild = function (node) {\n rewriteElement(node)\n return originalAppendChild.call(this, node)\n }\n\n var originalInsertBefore = Node.prototype.insertBefore\n Node.prototype.insertBefore = function (node, referenceNode) {\n rewriteElement(node)\n return originalInsertBefore.call(this, node, referenceNode)\n }\n\n if (document.body) {\n rewriteElement(document.body)\n }\n\n if (window.MutationObserver) {\n var observer = new MutationObserver(function (mutations) {\n mutations.forEach(function (mutation) {\n mutation.addedNodes.forEach(rewriteElement)\n })\n })\n observer.observe(document.documentElement, { childList: true, subtree: true })\n }\n })()\n </script>\n <script defer=\"defer\" src=\"${escapeHtmlAttribute(mainJs)}\"></script>\n <link href=\"${escapeHtmlAttribute(mainCss)}\" rel=\"stylesheet\" />\n </head>\n <body>\n <noscript>你需要启用 JavaScript 才能继续。</noscript>\n <div id=\"root\"></div>\n </body>\n</html>\n`;\n}\n\nexport const AUTH_INDEX_HTML = createAuthIndexHtml();\n","import { Buffer } from 'node:buffer';\nimport crypto from 'node:crypto';\n\nconst STATE_EXPIRY_SECONDS = 600;\nconst STATE_SECRET =\n process.env.NEXTAUTH_SECRET || process.env.CASDOOR_CLIENT_SECRET || 'dev-state-secret';\n\nexport const pkceCookiePrefix = 'pkce_code_verifier';\n\nexport interface StatePayload {\n nonce: string;\n issuedAt: number;\n}\n\nfunction signStatePayload(payload: StatePayload): string {\n const body = Buffer.from(JSON.stringify(payload)).toString('base64url');\n const signature = crypto.createHmac('sha256', STATE_SECRET).update(body).digest('base64url');\n return `${body}.${signature}`;\n}\n\nfunction decodeStatePayload(state: string): StatePayload | null {\n const [body, signature] = state.split('.');\n\n if (!body || !signature) {\n return null;\n }\n\n const expectedSignature = crypto.createHmac('sha256', STATE_SECRET).update(body).digest('base64url');\n\n if (\n expectedSignature.length !== signature.length ||\n !crypto.timingSafeEqual(Buffer.from(expectedSignature), Buffer.from(signature))\n ) {\n return null;\n }\n\n try {\n return JSON.parse(Buffer.from(body, 'base64url').toString('utf8')) as StatePayload;\n } catch {\n return null;\n }\n}\n\nexport function generateStateToken(): string {\n return signStatePayload({\n nonce: crypto.randomUUID(),\n issuedAt: Date.now(),\n });\n}\n\nexport function getPkceCookieName(state: string): string {\n const digest = crypto.createHash('sha256').update(state).digest('base64url');\n return `${pkceCookiePrefix}.${digest}`;\n}\n\nexport async function verifyState(stateFromUrl: string): Promise<boolean> {\n const payload = decodeStatePayload(stateFromUrl);\n if (!payload) {\n return false;\n }\n\n return Date.now() - payload.issuedAt <= STATE_EXPIRY_SECONDS * 1000;\n}\n\nexport function parseStateToken(token: string | null | undefined): StatePayload | null {\n if (!token) return null;\n return decodeStatePayload(token);\n}\n\nexport function verifyStateToken(token: string | null | undefined): boolean {\n if (!token) return false;\n return Boolean(decodeStatePayload(token));\n}\n","import { Buffer } from 'node:buffer';\nimport crypto from 'node:crypto';\nimport type { JWT, JWTDecodeParams, JWTEncodeParams } from 'next-auth/jwt';\n\nconst DEFAULT_MAX_AGE = 30 * 24 * 60 * 60;\n\nfunction base64UrlEncode(value: string): string {\n return Buffer.from(value, 'utf8').toString('base64url');\n}\n\nfunction base64UrlDecode(value: string): string {\n return Buffer.from(value, 'base64url').toString('utf8');\n}\n\nfunction createSignature(input: string, secret: string | Buffer): string {\n return crypto.createHmac('sha256', secret).update(input).digest('base64url');\n}\n\nfunction timingSafeEqual(left: string, right: string): boolean {\n const leftBuffer = Buffer.from(left);\n const rightBuffer = Buffer.from(right);\n\n if (leftBuffer.length !== rightBuffer.length) {\n return false;\n }\n\n return crypto.timingSafeEqual(leftBuffer, rightBuffer);\n}\n\nexport async function encodeSessionToken(params: JWTEncodeParams): Promise<string> {\n const { token = {}, secret, maxAge = DEFAULT_MAX_AGE } = params;\n const issuedAt = Math.floor(Date.now() / 1000);\n const header = base64UrlEncode(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));\n const payload = base64UrlEncode(\n JSON.stringify({\n ...token,\n iat: issuedAt,\n exp: issuedAt + maxAge,\n jti: crypto.randomUUID(),\n }),\n );\n const signature = createSignature(`${header}.${payload}`, secret);\n\n return `${header}.${payload}.${signature}`;\n}\n\nexport async function decodeSessionToken(params: JWTDecodeParams): Promise<JWT | null> {\n const { token, secret } = params;\n\n if (!token) {\n return null;\n }\n\n const [header, payload, signature] = token.split('.');\n\n if (!header || !payload || !signature) {\n return null;\n }\n\n const expectedSignature = createSignature(`${header}.${payload}`, secret);\n\n if (!timingSafeEqual(signature, expectedSignature)) {\n return null;\n }\n\n try {\n const parsedPayload = JSON.parse(base64UrlDecode(payload)) as JWT & { exp?: number };\n\n if (parsedPayload.exp && parsedPayload.exp <= Math.floor(Date.now() / 1000)) {\n return null;\n }\n\n return parsedPayload;\n } catch {\n return null;\n }\n}\n","import type { AuthKitConfig } from '../types';\nimport { normalizeAuthKitConfig } from '../core/config';\n\nexport function getCasdoorConfig(config: AuthKitConfig): AuthKitConfig {\n return normalizeAuthKitConfig(config);\n}\n\nexport function getCasdoorAuthorizeUrl(config: AuthKitConfig, params: { state: string; codeChallenge: string; redirectUri: string; kind: 'login' | 'signup' }): string {\n const base = new URL(config.casdoor.signinPath ?? '/login/oauth/authorize', config.casdoor.serverUrl);\n base.searchParams.set('response_type', 'code');\n base.searchParams.set('client_id', config.casdoor.clientId);\n base.searchParams.set('redirect_uri', params.redirectUri);\n base.searchParams.set('scope', 'profile');\n base.searchParams.set('state', params.state);\n base.searchParams.set('code_challenge', params.codeChallenge);\n base.searchParams.set('code_challenge_method', 'S256');\n if (params.kind === 'signup') {\n base.searchParams.set('action', 'signup');\n }\n return base.toString();\n}\n\nexport function getCasdoorTokenUrl(config: AuthKitConfig): string {\n return new URL('/api/login/oauth/access_token', config.casdoor.serverUrl).toString();\n}\n\nexport function getCasdoorUserInfoUrl(config: AuthKitConfig): string {\n return new URL('/api/userinfo', config.casdoor.serverUrl).toString();\n}\n","import type { AuthKitConfig, CasdoorUserInfo, OAuthTokens } from '../types';\nimport { getCasdoorTokenUrl, getCasdoorUserInfoUrl } from './config';\nimport { Buffer } from 'node:buffer';\n\nfunction decodeJwtPayload(token: string): Record<string, unknown> | null {\n const parts = token.split('.');\n if (parts.length < 2) {\n return null;\n }\n\n try {\n const payload = parts[1];\n return JSON.parse(Buffer.from(payload, 'base64url').toString('utf8')) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\nexport async function exchangeCodeForToken(config: AuthKitConfig, code: string, redirectUri: string, codeVerifier: string): Promise<OAuthTokens> {\n const response = await fetch(getCasdoorTokenUrl(config), {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n client_id: config.casdoor.clientId,\n client_secret: config.casdoor.clientSecret,\n code,\n redirect_uri: redirectUri,\n code_verifier: codeVerifier\n })\n });\n if (!response.ok) {\n throw new Error('Failed to exchange Casdoor authorization code.');\n }\n return (await response.json()) as OAuthTokens;\n}\n\nexport async function fetchCasdoorUserInfo(config: AuthKitConfig, accessToken: string): Promise<CasdoorUserInfo> {\n const response = await fetch(getCasdoorUserInfoUrl(config), {\n headers: {\n authorization: 'Bearer ' + accessToken\n }\n });\n if (!response.ok) {\n throw new Error('Failed to fetch Casdoor user profile.');\n }\n return (await response.json()) as CasdoorUserInfo;\n}\n\nexport function decodeCasdoorAccessToken(accessToken: string): Record<string, unknown> | null {\n return decodeJwtPayload(accessToken);\n}\n\nexport const exchangeCasdoorOAuthToken = exchangeCodeForToken;\n","import { NextResponse, type NextRequest } from 'next/server';\nimport type { AuthKitConfig } from '../types';\nimport { normalizeAuthKitConfig } from '../core/config';\nimport { getRequestOrigin, setPublicOriginCookie } from '../core/public-origin';\nimport { isSecureRequest } from '../core/request-security';\nimport { createPkcePair } from '../core/pkce';\nimport { generateStateToken, getPkceCookieName } from '../core/oauth-state';\nimport { getAuthRedirectTarget, setAuthRedirectCookie } from '../core/auth-redirect';\nimport { createAuthIndexHtml } from '../core/index-html';\n\nfunction buildLocalAuthorizeUrl(\n origin: string,\n config: AuthKitConfig,\n params: { state: string; codeChallenge: string; kind: 'login' | 'signup' },\n): string {\n const normalized = normalizeAuthKitConfig(config);\n const authorizePath =\n params.kind === 'signup'\n ? '/signup/oauth/authorize'\n : normalized.casdoor.signinPath || '/login/oauth/authorize';\n const authorizeUrl = new URL(authorizePath, origin);\n authorizeUrl.searchParams.set('response_type', 'code');\n authorizeUrl.searchParams.set('client_id', normalized.casdoor.clientId);\n authorizeUrl.searchParams.set('redirect_uri', `${origin}${normalized.casdoor.redirectPath || '/callback'}`);\n authorizeUrl.searchParams.set('scope', 'profile');\n authorizeUrl.searchParams.set('state', params.state);\n authorizeUrl.searchParams.set('code_challenge', params.codeChallenge);\n authorizeUrl.searchParams.set('code_challenge_method', 'S256');\n return authorizeUrl.toString();\n}\n\nasync function createRedirectEntryResponse(\n request: NextRequest,\n config: AuthKitConfig,\n kind: 'login' | 'signup',\n): Promise<NextResponse> {\n const normalized = normalizeAuthKitConfig(config);\n const origin = getRequestOrigin(request, normalized.appUrl);\n const secure =\n normalized.cookie?.secure === 'auto' ? isSecureRequest(request, normalized.appUrl) : Boolean(normalized.cookie?.secure);\n const { verifier, challenge } = await createPkcePair();\n const state = generateStateToken();\n const response = NextResponse.redirect(\n buildLocalAuthorizeUrl(origin, normalized, { state, codeChallenge: challenge, kind }),\n 307,\n );\n const redirectTarget = getAuthRedirectTarget(request);\n if (redirectTarget) {\n setAuthRedirectCookie(response, redirectTarget, secure);\n }\n setPublicOriginCookie(response, origin, secure);\n response.cookies.set('oauth_state', state, { httpOnly: true, sameSite: 'lax', secure, path: '/' });\n response.cookies.set(getPkceCookieName(state), verifier, { httpOnly: true, sameSite: 'lax', secure, path: '/' });\n return response;\n}\n\nasync function createAuthorizePageResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse> {\n const normalized = normalizeAuthKitConfig(config);\n const origin = getRequestOrigin(request, normalized.appUrl);\n const secure =\n normalized.cookie?.secure === 'auto' ? isSecureRequest(request, normalized.appUrl) : Boolean(normalized.cookie?.secure);\n const response = new NextResponse(\n createAuthIndexHtml({\n appName: normalized.casdoor.appName,\n organizationName: normalized.casdoor.organizationName,\n staticOrigin: process.env.NEXT_PUBLIC_CASDOOR_STATIC_ORIGIN,\n casdoorOrigin: normalized.casdoor.serverUrl,\n apiProxyPrefix: '/auth/',\n }),\n {\n status: 200,\n headers: {\n 'content-type': 'text/html; charset=utf-8',\n 'cache-control': 'no-store, max-age=0',\n },\n },\n );\n setPublicOriginCookie(response, origin, secure);\n return response;\n}\n\nexport async function createLoginEntryResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse> {\n return createRedirectEntryResponse(request, config, 'login');\n}\n\nexport async function createSignupEntryResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse> {\n return createRedirectEntryResponse(request, config, 'signup');\n}\n\nexport async function createAuthorizeEntryResponse(request: NextRequest, config: AuthKitConfig): Promise<NextResponse> {\n return createAuthorizePageResponse(request, config);\n}\n","const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';\n\nfunction toBase64Url(bytes: ArrayBuffer): string {\n const raw = Buffer.from(bytes).toString('base64');\n return raw.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/g, '');\n}\n\nexport async function createPkcePair(): Promise<{ verifier: string; challenge: string }> {\n const bytes = crypto.getRandomValues(new Uint8Array(48));\n const verifier = Array.from(bytes, (byte) => chars[byte % chars.length]).join('');\n const digest = await crypto.subtle.digest('SHA-256', new TextEncoder().encode(verifier));\n return { verifier, challenge: toBase64Url(digest) };\n}\n","import { NextResponse, type NextRequest } from 'next/server';\nimport type { AuthBusinessAdapter, AuthKitConfig, AuthPersistenceAdapter, AuthUser } from '../types';\nimport { normalizeAuthKitConfig } from '../core/config';\nimport { getRequestOrigin, getStoredPublicOrigin, clearPublicOriginCookie } from '../core/public-origin';\nimport { isSecureRequest } from '../core/request-security';\nimport { getAuthRedirectTarget, clearAuthRedirectCookie } from '../core/auth-redirect';\nimport {\n decodeCasdoorAccessToken,\n exchangeCasdoorOAuthToken,\n fetchCasdoorUserInfo,\n} from './oauth';\nimport { getCasdoorConfig } from './config';\nimport { getPkceCookieName, verifyState } from '../core/oauth-state';\nimport { encodeSessionToken } from '../core/session-token';\nimport { isGlobalAdminEmail } from '../core/admin';\nimport { resolvePostLoginRedirect } from '../core/redirect';\nimport { buildAuthUserFromProfile } from '../core/auth-role';\n\nexport interface CallbackHandlerOptions {\n config: AuthKitConfig;\n adapter?: AuthBusinessAdapter;\n persistence?: AuthPersistenceAdapter;\n}\n\nfunction readCookieHeaderValue(cookieHeader: string | null, name: string): string | null {\n if (!cookieHeader) {\n return null;\n }\n\n for (const entry of cookieHeader.split(';')) {\n const [rawName, ...valueParts] = entry.trim().split('=');\n if (rawName === name) {\n const value = valueParts.join('=').trim();\n return value || null;\n }\n }\n\n return null;\n}\n\nfunction getPublicOrigin(request: NextRequest, config: AuthKitConfig): string {\n return getStoredPublicOrigin(request) || getRequestOrigin(request, config.appUrl);\n}\n\nfunction rewriteToCallbackErrorPage(\n request: NextRequest,\n config: AuthKitConfig,\n title: string,\n message: string,\n details?: string,\n): NextResponse {\n const origin = getPublicOrigin(request, config);\n const targetUrl = new URL('/callback/error', origin);\n targetUrl.searchParams.set('title', title);\n targetUrl.searchParams.set('message', message);\n\n if (details) {\n targetUrl.searchParams.set('details', details);\n }\n\n return NextResponse.redirect(targetUrl, 307);\n}\n\nfunction getPkceCodeVerifier(request: NextRequest, state: string): string | null {\n return readCookieHeaderValue(request.headers.get('cookie'), getPkceCookieName(state));\n}\n\nfunction setNextAuthSessionCookies(response: NextResponse, sessionToken: string, isSecure: boolean): void {\n const cookieName = isSecure ? '__Secure-next-auth.session-token' : 'next-auth.session-token';\n const expires = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000);\n const baseOptions = {\n path: '/',\n httpOnly: true,\n sameSite: 'lax' as const,\n secure: isSecure,\n expires,\n };\n const maxCookieSize = 3933;\n\n if (sessionToken.length <= maxCookieSize) {\n response.cookies.set(cookieName, sessionToken, baseOptions);\n return;\n }\n\n const chunkCount = Math.ceil(sessionToken.length / maxCookieSize);\n for (let index = 0; index < chunkCount; index++) {\n response.cookies.set(\n `${cookieName}.${index}`,\n sessionToken.slice(index * maxCookieSize, (index + 1) * maxCookieSize),\n baseOptions,\n );\n }\n}\n\nfunction sanitizeRedirectPath(value: string | null): string {\n if (!value || !value.startsWith('/') || value.startsWith('//')) {\n return '/user/account';\n }\n\n return value;\n}\n\nfunction summarizeCookieHeader(cookieHeader: string | null): Record<string, unknown> {\n if (!cookieHeader) {\n return { present: false };\n }\n\n const cookieNames = cookieHeader\n .split(';')\n .map((entry) => entry.trim().split('=')[0])\n .filter(Boolean);\n\n return {\n present: true,\n count: cookieNames.length,\n names: cookieNames,\n };\n}\n\nexport function mapProfileToAuthUser(profile: Awaited<ReturnType<typeof fetchCasdoorUserInfo>>, adapter?: AuthBusinessAdapter): AuthUser {\n const typedProfile = profile as Awaited<ReturnType<typeof fetchCasdoorUserInfo>> & {\n sub?: string;\n picture?: string;\n avatarUrl?: string;\n role?: string;\n };\n const email = typedProfile.email || null;\n const isAdmin =\n Boolean(typedProfile.isAdmin) ||\n Boolean(adapter?.isAdminEmail?.(email)) ||\n isGlobalAdminEmail(email);\n\n return buildAuthUserFromProfile(\n {\n id: typedProfile.id,\n sub: typedProfile.sub,\n name: typedProfile.name,\n displayName: typedProfile.displayName,\n email,\n picture: typedProfile.picture,\n avatarUrl: typedProfile.avatarUrl,\n isAdmin: typedProfile.isAdmin,\n role: typedProfile.role,\n },\n isAdmin,\n );\n}\n\nfunction getRedirectTarget(request: NextRequest, user: AuthUser, adapter?: AuthBusinessAdapter): string {\n const adapterRedirect = adapter?.resolvePostLoginRedirect?.(user);\n if (adapterRedirect) {\n return sanitizeRedirectPath(adapterRedirect);\n }\n\n const storedRedirect = getAuthRedirectTarget(request);\n if (storedRedirect) {\n return sanitizeRedirectPath(storedRedirect);\n }\n\n return sanitizeRedirectPath(resolvePostLoginRedirect(user, '/user/account'));\n}\n\nexport async function createCallbackResponse(\n request: NextRequest,\n options: CallbackHandlerOptions,\n): Promise<NextResponse> {\n const normalized = normalizeAuthKitConfig(options.config);\n const publicOrigin = getPublicOrigin(request, normalized);\n const url = new URL(request.url);\n const code = url.searchParams.get('code');\n const state = url.searchParams.get('state');\n const error = url.searchParams.get('error');\n const secure = normalized.cookie?.secure === 'auto'\n ? isSecureRequest(request, normalized.appUrl)\n : Boolean(normalized.cookie?.secure);\n\n if (error) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n 'Casdoor 返回了授权错误',\n '授权服务器在回调阶段返回了错误信息。请返回首页或重新登录后再试。',\n error,\n );\n }\n\n if (!code) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n '缺少授权码',\n 'Casdoor 回调没有带回 code,这通常意味着授权流程未完成。',\n 'no_code',\n );\n }\n\n if (!state || !(await verifyState(state))) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n '登录状态校验失败',\n '回调中的 state 与本次登录流程不匹配,请重新发起登录。',\n 'invalid_state',\n );\n }\n\n const codeVerifier = getPkceCodeVerifier(request, state);\n if (!codeVerifier) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n '缺少 PKCE 校验值',\n '回调请求里没有找到 pkce_code_verifier cookie。请重新从登录入口发起流程。',\n 'missing_pkce_code_verifier',\n );\n }\n\n const casdoorConfig = getCasdoorConfig(normalized);\n const redirectUri = `${publicOrigin}${casdoorConfig.casdoor.redirectPath}`;\n const tokens = await exchangeCasdoorOAuthToken(casdoorConfig, code, redirectUri, codeVerifier);\n const accessToken = tokens.access_token ?? tokens.accessToken ?? '';\n\n if (!accessToken) {\n return rewriteToCallbackErrorPage(\n request,\n normalized,\n '缺少访问令牌',\n 'Casdoor 回调没有返回 access token。',\n 'missing_access_token',\n );\n }\n\n const profile = await fetchCasdoorUserInfo(casdoorConfig, accessToken);\n\n const decodedAccessToken = decodeCasdoorAccessToken(accessToken) as { exp?: number } | null;\n const mappedUser = options.adapter?.onUserSync\n ? await options.adapter.onUserSync(profile, {\n accessToken,\n refreshToken: tokens.refresh_token || tokens.refreshToken,\n idToken: tokens.id_token || tokens.idToken,\n expiresAt: tokens.expires_in ? Date.now() + tokens.expires_in * 1000 : tokens.expiresAt,\n })\n : mapProfileToAuthUser(profile, options.adapter);\n\n if (options.persistence?.syncAuthUser) {\n await options.persistence.syncAuthUser(mappedUser);\n }\n\n const sessionToken = await encodeSessionToken({\n token: {\n id: mappedUser.id,\n sub: mappedUser.id,\n userId: mappedUser.id,\n name: mappedUser.name,\n email: mappedUser.email,\n picture: mappedUser.image,\n accessToken,\n expiresAt: tokens.expires_in ? Date.now() + tokens.expires_in * 1000 : decodedAccessToken?.exp,\n isAdmin: mappedUser.isAdmin,\n role: mappedUser.role,\n tokenBalance: mappedUser.tokenBalance,\n isVip: mappedUser.isVip,\n },\n secret: normalized.nextauthSecret,\n maxAge: normalized.session?.maxAgeSeconds,\n });\n\n const response = NextResponse.redirect(new URL(getRedirectTarget(request, mappedUser, options.adapter), publicOrigin));\n setNextAuthSessionCookies(response, sessionToken, secure);\n response.cookies.set(getPkceCookieName(state), '', {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n maxAge: 0,\n });\n response.cookies.set('oauth_state', '', {\n path: '/',\n httpOnly: true,\n sameSite: 'lax',\n secure,\n maxAge: 0,\n });\n clearAuthRedirectCookie(response, secure);\n clearPublicOriginCookie(response, secure);\n return response;\n}\n\nexport function createCallbackHandler(options: CallbackHandlerOptions) {\n return async function GET(request: NextRequest) {\n return createCallbackResponse(request, options);\n };\n}\n"],"mappings":"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","names":["Buffer","crypto","Buffer","crypto","Buffer","NextResponse","NextResponse","NextResponse"]}