@foldspace-fe/casdoor-next-auth-kit 0.1.12 → 0.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/billing/index.js +1 -1
- package/dist/casdoor/index.js +2 -2
- package/dist/{chunk-6CJ5DUZZ.js → chunk-5ISF7ZAG.js} +3 -5
- package/dist/chunk-5ISF7ZAG.js.map +1 -0
- package/dist/{chunk-YXTDGBLC.js → chunk-5W4H2IMT.js} +23 -13
- package/dist/chunk-5W4H2IMT.js.map +1 -0
- package/dist/{chunk-IQEVUR77.js → chunk-MWXY4JSL.js} +7 -7
- package/dist/chunk-MWXY4JSL.js.map +1 -0
- package/dist/{chunk-Y4GJ2AEI.js → chunk-QYGC4WNG.js} +2 -2
- package/dist/cli.js +168 -0
- package/dist/cli.js.map +1 -1
- package/dist/index.js +16 -16
- package/dist/next/index.js +2 -2
- package/dist/skills/casdoor-next-auth-kit/SKILL.md +3 -0
- package/package.json +2 -1
- package/dist/chunk-6CJ5DUZZ.js.map +0 -1
- package/dist/chunk-IQEVUR77.js.map +0 -1
- package/dist/chunk-YXTDGBLC.js.map +0 -1
- /package/dist/{chunk-Y4GJ2AEI.js.map → chunk-QYGC4WNG.js.map} +0 -0
package/dist/billing/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
createBillingPaymentFinishedRouteHandler,
|
|
4
4
|
createBillingPaymentSuccessResponse,
|
|
5
5
|
createBillingPaymentSuccessRouteHandler
|
|
6
|
-
} from "../chunk-
|
|
6
|
+
} from "../chunk-5ISF7ZAG.js";
|
|
7
7
|
import {
|
|
8
8
|
buildBillingActionPayload,
|
|
9
9
|
deriveBillingCreditsState,
|
package/dist/casdoor/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createCasdoorApiProxyHandler,
|
|
3
3
|
createCasdoorCommerceProxyHandler,
|
|
4
4
|
createCasdoorPageProxyHandler
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-5W4H2IMT.js";
|
|
6
6
|
import {
|
|
7
7
|
createAuthorizeEntryResponse,
|
|
8
8
|
createCallbackHandler,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
getCasdoorConfig,
|
|
18
18
|
getCasdoorTokenUrl,
|
|
19
19
|
getCasdoorUserInfoUrl
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-MWXY4JSL.js";
|
|
21
21
|
import "../chunk-T2M5MVPE.js";
|
|
22
22
|
export {
|
|
23
23
|
createAuthorizeEntryResponse,
|
|
@@ -11,14 +11,12 @@ function normalizeOrigin(value) {
|
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
function getRequestOrigin(request, appUrl) {
|
|
14
|
+
const configured = normalizeOrigin(appUrl);
|
|
15
|
+
if (configured) return configured;
|
|
14
16
|
const referer = normalizeOrigin(request.headers.get("referer"));
|
|
15
17
|
if (referer) return referer;
|
|
16
18
|
const origin = normalizeOrigin(request.headers.get("origin"));
|
|
17
19
|
if (origin) return origin;
|
|
18
|
-
if (appUrl) {
|
|
19
|
-
const normalized = normalizeOrigin(appUrl);
|
|
20
|
-
if (normalized) return normalized;
|
|
21
|
-
}
|
|
22
20
|
const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
|
|
23
21
|
const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
|
|
24
22
|
if (forwardedProto && forwardedHost) {
|
|
@@ -170,4 +168,4 @@ export {
|
|
|
170
168
|
createBillingPaymentFinishedResponse,
|
|
171
169
|
createBillingPaymentFinishedRouteHandler
|
|
172
170
|
};
|
|
173
|
-
//# sourceMappingURL=chunk-
|
|
171
|
+
//# sourceMappingURL=chunk-5ISF7ZAG.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/billing/payment-route.ts","../src/core/origin.ts","../src/billing/payment-success.ts","../src/billing/payment-finished.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\n\nimport { resolvePublicOrigin } from '../core/origin';\nimport type {\n BillingPaymentSuccessContext,\n BillingPaymentSuccessHandlerResult,\n BillingPaymentSuccessRouteOptions,\n} from './types';\n\nexport interface BillingPaymentRouteOptions extends BillingPaymentSuccessRouteOptions {\n routePath: string;\n missingHandlerFile: string;\n}\n\nfunction sanitizeRedirectPath(value: string | null | undefined, fallback: string): string {\n if (!value || !value.startsWith('/') || value.startsWith('//')) {\n return fallback;\n }\n\n return value;\n}\n\nfunction isDebugEnabled(): boolean {\n const value = process.env.BILLING_PAYMENT_SUCCESS_DEBUG;\n if (!value) {\n return false;\n }\n\n return ['1', 'true', 'yes', 'on'].includes(value.toLowerCase());\n}\n\nasync function readRequestBody(request: Request): Promise<unknown> {\n if (request.method === 'GET' || request.method === 'HEAD') {\n return null;\n }\n\n const rawBody = await request.clone().text();\n if (!rawBody) {\n return null;\n }\n\n const contentType = request.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n try {\n return JSON.parse(rawBody);\n } catch {\n return rawBody;\n }\n }\n\n if (contentType.includes('application/x-www-form-urlencoded')) {\n return Object.fromEntries(new URLSearchParams(rawBody).entries());\n }\n\n return rawBody;\n}\n\nasync function buildContext(request: Request): Promise<BillingPaymentSuccessContext> {\n const url = new URL(request.url);\n const params: Record<string, string> = {};\n\n for (const [key, value] of url.searchParams.entries()) {\n params[key] = value;\n }\n\n return {\n request,\n url,\n searchParams: url.searchParams,\n params,\n paymentId: url.searchParams.get('paymentId'),\n orderId: url.searchParams.get('orderId'),\n redirectTo: url.searchParams.get('redirect') ?? url.searchParams.get('returnTo'),\n body: await readRequestBody(request),\n };\n}\n\nfunction resolveRedirectTarget(\n result: BillingPaymentSuccessHandlerResult | undefined,\n context: BillingPaymentSuccessContext,\n fallbackRedirect: string,\n): string {\n if (typeof result === 'string') {\n return sanitizeRedirectPath(result, fallbackRedirect);\n }\n\n if (result && typeof result === 'object' && 'redirectTo' in result) {\n return sanitizeRedirectPath(result.redirectTo ?? null, fallbackRedirect);\n }\n\n return sanitizeRedirectPath(context.redirectTo, fallbackRedirect);\n}\n\nfunction resolveFallbackTarget(fallbackRedirect: string): string {\n return sanitizeRedirectPath(fallbackRedirect, '/');\n}\n\nfunction logMissingPaymentHandler(\n context: BillingPaymentSuccessContext,\n fallbackRedirect: string,\n missingHandlerFile: string,\n routePath: string,\n): void {\n console.warn(\n `[casdoor-next-auth-kit] default billing handler at ${missingHandlerFile} has no business logic. ` +\n `Edit this file to handle ${routePath} with order/payment enrichment before redirecting. ` +\n `Falling back to ${fallbackRedirect}.`,\n {\n paymentId: context.paymentId,\n orderId: context.orderId,\n params: context.params,\n },\n );\n}\n\nexport async function createBillingPaymentRouteResponse(\n request: Request,\n options: BillingPaymentRouteOptions,\n) {\n const origin = resolvePublicOrigin(request, options.appUrl);\n const fallbackRedirect = options.fallbackRedirect ?? '/';\n const context = await buildContext(request);\n\n if (isDebugEnabled()) {\n console.info(`[casdoor-next-auth-kit] ${options.routePath} request`, {\n method: request.method,\n path: context.url.pathname,\n query: context.params,\n body: context.body,\n });\n }\n\n try {\n if (options.handler) {\n const result = await options.handler(context);\n if (result instanceof Response) {\n return result;\n }\n\n const target = resolveRedirectTarget(result, context, fallbackRedirect);\n return NextResponse.redirect(new URL(target, origin), 307);\n }\n\n logMissingPaymentHandler(context, fallbackRedirect, options.missingHandlerFile, options.routePath);\n const target = resolveFallbackTarget(fallbackRedirect);\n return NextResponse.redirect(new URL(target, origin), 307);\n } catch (error) {\n console.error(`[casdoor-next-auth-kit] ${options.routePath} handler failed:`, error);\n return new NextResponse('Billing payment handler failed', { status: 500 });\n }\n}\n","export function normalizeOrigin(value: string | null | undefined): string | null {\n if (!value) return null;\n try {\n return new URL(value).origin;\n } catch {\n return null;\n }\n}\n\nexport function getRequestOrigin(request: Request, appUrl?: string): string {\n const configured = normalizeOrigin(appUrl);\n if (configured) return configured;\n\n const referer = normalizeOrigin(request.headers.get('referer'));\n if (referer) return referer;\n\n const origin = normalizeOrigin(request.headers.get('origin'));\n if (origin) return origin;\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 resolvePublicOrigin(request: Request, appUrl?: string): string {\n return getRequestOrigin(request, appUrl);\n}\n","import type { BillingPaymentSuccessHandler, BillingPaymentSuccessRouteOptions } from './types';\nimport { createBillingPaymentRouteResponse } from './payment-route';\n\nexport async function createBillingPaymentSuccessResponse(\n request: Request,\n options: BillingPaymentSuccessRouteOptions = {},\n) {\n return createBillingPaymentRouteResponse(request, {\n ...options,\n routePath: '/auth/payment/success',\n missingHandlerFile: 'lib/billing/payment-success.ts',\n fallbackRedirect: options.fallbackRedirect ?? '/auth/payment/finished',\n });\n}\n\nexport function createBillingPaymentSuccessRouteHandler(options: BillingPaymentSuccessRouteOptions = {}) {\n return async function GET(request: Request) {\n return createBillingPaymentSuccessResponse(request, options);\n };\n}\n\nexport type { BillingPaymentSuccessHandler };\n","import type { BillingPaymentFinishedHandler, BillingPaymentFinishedRouteOptions } from './types';\nimport { createBillingPaymentRouteResponse } from './payment-route';\n\nexport async function createBillingPaymentFinishedResponse(\n request: Request,\n options: BillingPaymentFinishedRouteOptions = {},\n) {\n return createBillingPaymentRouteResponse(request, {\n ...options,\n routePath: '/auth/payment/finished',\n missingHandlerFile: 'lib/billing/payment-finished.ts',\n fallbackRedirect: options.fallbackRedirect ?? '/',\n });\n}\n\nexport function createBillingPaymentFinishedRouteHandler(options: BillingPaymentFinishedRouteOptions = {}) {\n return async function GET(request: Request) {\n return createBillingPaymentFinishedResponse(request, options);\n };\n}\n\nexport type { BillingPaymentFinishedHandler };\n"],"mappings":"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","names":["target"]}
|
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
// src/casdoor/proxy.ts
|
|
2
2
|
import { NextResponse } from "next/server";
|
|
3
|
+
|
|
4
|
+
// src/casdoor/proxy-headers.ts
|
|
5
|
+
function buildCasdoorProxyRequestHeaders(request) {
|
|
6
|
+
const headers = new Headers();
|
|
7
|
+
const allowedHeaderNames = [
|
|
8
|
+
"accept",
|
|
9
|
+
"accept-language",
|
|
10
|
+
"authorization",
|
|
11
|
+
"content-type",
|
|
12
|
+
"x-requested-with"
|
|
13
|
+
];
|
|
14
|
+
for (const headerName of allowedHeaderNames) {
|
|
15
|
+
const value = request.headers.get(headerName);
|
|
16
|
+
if (value) {
|
|
17
|
+
headers.set(headerName, value);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return headers;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// src/casdoor/proxy.ts
|
|
3
24
|
function buildUpstreamUrl(request, baseUrl, localPrefix, upstreamPrefix) {
|
|
4
25
|
const url = new URL(request.url);
|
|
5
26
|
const upstreamPath = url.pathname.startsWith(localPrefix) ? upstreamPrefix + url.pathname.slice(localPrefix.length) : url.pathname;
|
|
@@ -7,20 +28,9 @@ function buildUpstreamUrl(request, baseUrl, localPrefix, upstreamPrefix) {
|
|
|
7
28
|
rewritten.search = url.search;
|
|
8
29
|
return rewritten.toString();
|
|
9
30
|
}
|
|
10
|
-
function cleanProxyRequestHeaders(request, baseUrl) {
|
|
11
|
-
const headers = new Headers(request.headers);
|
|
12
|
-
headers.delete("host");
|
|
13
|
-
headers.delete("origin");
|
|
14
|
-
headers.delete("referer");
|
|
15
|
-
headers.delete("x-forwarded-host");
|
|
16
|
-
headers.delete("x-forwarded-port");
|
|
17
|
-
headers.delete("x-forwarded-proto");
|
|
18
|
-
headers.delete("forwarded");
|
|
19
|
-
return headers;
|
|
20
|
-
}
|
|
21
31
|
async function proxyRequest(request, baseUrl, localPrefix, upstreamPrefix, options = {}) {
|
|
22
32
|
const upstreamUrl = buildUpstreamUrl(request, baseUrl, localPrefix, upstreamPrefix);
|
|
23
|
-
const headers =
|
|
33
|
+
const headers = buildCasdoorProxyRequestHeaders(request);
|
|
24
34
|
const body = request.method === "GET" || request.method === "HEAD" ? void 0 : await request.arrayBuffer();
|
|
25
35
|
const upstream = await fetch(upstreamUrl, {
|
|
26
36
|
method: request.method,
|
|
@@ -63,4 +73,4 @@ export {
|
|
|
63
73
|
createCasdoorPageProxyHandler,
|
|
64
74
|
createCasdoorCommerceProxyHandler
|
|
65
75
|
};
|
|
66
|
-
//# sourceMappingURL=chunk-
|
|
76
|
+
//# sourceMappingURL=chunk-5W4H2IMT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/casdoor/proxy.ts","../src/casdoor/proxy-headers.ts"],"sourcesContent":["import { NextResponse, type NextRequest } from 'next/server';\nimport type { AuthKitConfig } from '../types';\nimport { buildCasdoorProxyRequestHeaders } from './proxy-headers';\n\nfunction buildUpstreamUrl(request: NextRequest, baseUrl: string, localPrefix: string, upstreamPrefix: string): string {\n const url = new URL(request.url);\n const upstreamPath = url.pathname.startsWith(localPrefix)\n ? upstreamPrefix + url.pathname.slice(localPrefix.length)\n : url.pathname;\n const rewritten = new URL(upstreamPath, baseUrl);\n rewritten.search = url.search;\n return rewritten.toString();\n}\n\nasync function proxyRequest(\n request: NextRequest,\n baseUrl: string,\n localPrefix: string,\n upstreamPrefix: string,\n options: { suppressRedirects?: boolean } = {},\n): Promise<NextResponse> {\n const upstreamUrl = buildUpstreamUrl(request, baseUrl, localPrefix, upstreamPrefix);\n const headers = buildCasdoorProxyRequestHeaders(request);\n const body = request.method === 'GET' || request.method === 'HEAD' ? undefined : await request.arrayBuffer();\n const upstream = await fetch(upstreamUrl, {\n method: request.method,\n headers,\n body,\n redirect: options.suppressRedirects ? 'manual' : 'follow',\n });\n\n if (options.suppressRedirects && upstream.status >= 300 && upstream.status < 400) {\n return NextResponse.json(\n {\n status: 'error',\n msg: 'Please login first',\n redirect: upstream.headers.get('location') || null,\n },\n { status: 200 },\n );\n }\n\n const responseHeaders = new Headers(upstream.headers);\n responseHeaders.delete('content-encoding');\n responseHeaders.delete('content-length');\n responseHeaders.delete('transfer-encoding');\n responseHeaders.delete('connection');\n return new NextResponse(upstream.body, {\n status: upstream.status,\n headers: responseHeaders,\n });\n}\n\nexport function createCasdoorApiProxyHandler(\n config: AuthKitConfig,\n prefix = '/auth/api',\n upstreamPrefix = '/api',\n): (request: NextRequest) => Promise<NextResponse> {\n return async (request) => proxyRequest(request, config.casdoor.serverUrl, prefix, upstreamPrefix, { suppressRedirects: true });\n}\n\nexport function createCasdoorPageProxyHandler(\n config: AuthKitConfig,\n prefix = '/auth',\n upstreamPrefix = '',\n): (request: NextRequest) => Promise<NextResponse> {\n return async (request) => proxyRequest(request, config.casdoor.serverUrl, prefix, upstreamPrefix);\n}\n\nexport function createCasdoorCommerceProxyHandler(\n config: AuthKitConfig,\n prefix = '/auth/api/commerce',\n upstreamPrefix = '/api/commerce',\n): (request: NextRequest) => Promise<NextResponse> {\n return async (request) => proxyRequest(request, config.casdoor.serverUrl, prefix, upstreamPrefix, { suppressRedirects: true });\n}\n","export function buildCasdoorProxyRequestHeaders(request: Pick<Request, 'headers'>): Headers {\n const headers = new Headers();\n const allowedHeaderNames = [\n 'accept',\n 'accept-language',\n 'authorization',\n 'content-type',\n 'x-requested-with',\n ];\n\n for (const headerName of allowedHeaderNames) {\n const value = request.headers.get(headerName);\n if (value) {\n headers.set(headerName, value);\n }\n }\n\n return headers;\n}\n"],"mappings":";AAAA,SAAS,oBAAsC;;;ACAxC,SAAS,gCAAgC,SAA4C;AAC1F,QAAM,UAAU,IAAI,QAAQ;AAC5B,QAAM,qBAAqB;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,cAAc,oBAAoB;AAC3C,UAAM,QAAQ,QAAQ,QAAQ,IAAI,UAAU;AAC5C,QAAI,OAAO;AACT,cAAQ,IAAI,YAAY,KAAK;AAAA,IAC/B;AAAA,EACF;AAEA,SAAO;AACT;;;ADdA,SAAS,iBAAiB,SAAsB,SAAiB,aAAqB,gBAAgC;AACpH,QAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,QAAM,eAAe,IAAI,SAAS,WAAW,WAAW,IACpD,iBAAiB,IAAI,SAAS,MAAM,YAAY,MAAM,IACtD,IAAI;AACR,QAAM,YAAY,IAAI,IAAI,cAAc,OAAO;AAC/C,YAAU,SAAS,IAAI;AACvB,SAAO,UAAU,SAAS;AAC5B;AAEA,eAAe,aACb,SACA,SACA,aACA,gBACA,UAA2C,CAAC,GACrB;AACvB,QAAM,cAAc,iBAAiB,SAAS,SAAS,aAAa,cAAc;AAClF,QAAM,UAAU,gCAAgC,OAAO;AACvD,QAAM,OAAO,QAAQ,WAAW,SAAS,QAAQ,WAAW,SAAS,SAAY,MAAM,QAAQ,YAAY;AAC3G,QAAM,WAAW,MAAM,MAAM,aAAa;AAAA,IACxC,QAAQ,QAAQ;AAAA,IAChB;AAAA,IACA;AAAA,IACA,UAAU,QAAQ,oBAAoB,WAAW;AAAA,EACnD,CAAC;AAED,MAAI,QAAQ,qBAAqB,SAAS,UAAU,OAAO,SAAS,SAAS,KAAK;AAChF,WAAO,aAAa;AAAA,MAClB;AAAA,QACE,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,UAAU,SAAS,QAAQ,IAAI,UAAU,KAAK;AAAA,MAChD;AAAA,MACA,EAAE,QAAQ,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,kBAAkB,IAAI,QAAQ,SAAS,OAAO;AACpD,kBAAgB,OAAO,kBAAkB;AACzC,kBAAgB,OAAO,gBAAgB;AACvC,kBAAgB,OAAO,mBAAmB;AAC1C,kBAAgB,OAAO,YAAY;AACnC,SAAO,IAAI,aAAa,SAAS,MAAM;AAAA,IACrC,QAAQ,SAAS;AAAA,IACjB,SAAS;AAAA,EACX,CAAC;AACH;AAEO,SAAS,6BACd,QACA,SAAS,aACT,iBAAiB,QACgC;AACjD,SAAO,OAAO,YAAY,aAAa,SAAS,OAAO,QAAQ,WAAW,QAAQ,gBAAgB,EAAE,mBAAmB,KAAK,CAAC;AAC/H;AAEO,SAAS,8BACd,QACA,SAAS,SACT,iBAAiB,IACgC;AACjD,SAAO,OAAO,YAAY,aAAa,SAAS,OAAO,QAAQ,WAAW,QAAQ,cAAc;AAClG;AAEO,SAAS,kCACd,QACA,SAAS,sBACT,iBAAiB,iBACgC;AACjD,SAAO,OAAO,YAAY,aAAa,SAAS,OAAO,QAAQ,WAAW,QAAQ,gBAAgB,EAAE,mBAAmB,KAAK,CAAC;AAC/H;","names":[]}
|
|
@@ -25,6 +25,12 @@ function normalizeAuthKitConfig(config) {
|
|
|
25
25
|
// src/core/public-origin.ts
|
|
26
26
|
var PUBLIC_ORIGIN_COOKIE_NAME = "auth_origin";
|
|
27
27
|
function getRequestOrigin(request, appUrl) {
|
|
28
|
+
if (appUrl) {
|
|
29
|
+
try {
|
|
30
|
+
return new URL(appUrl).origin;
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
}
|
|
28
34
|
const referer = request.headers.get("referer");
|
|
29
35
|
if (referer) {
|
|
30
36
|
try {
|
|
@@ -39,12 +45,6 @@ function getRequestOrigin(request, appUrl) {
|
|
|
39
45
|
} catch {
|
|
40
46
|
}
|
|
41
47
|
}
|
|
42
|
-
if (appUrl) {
|
|
43
|
-
try {
|
|
44
|
-
return new URL(appUrl).origin;
|
|
45
|
-
} catch {
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
48
|
const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
|
|
49
49
|
const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
|
|
50
50
|
if (forwardedProto && forwardedHost) {
|
|
@@ -906,4 +906,4 @@ export {
|
|
|
906
906
|
createCallbackResponse,
|
|
907
907
|
createCallbackHandler
|
|
908
908
|
};
|
|
909
|
-
//# sourceMappingURL=chunk-
|
|
909
|
+
//# sourceMappingURL=chunk-MWXY4JSL.js.map
|
|
@@ -0,0 +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('&', '&').replaceAll('\"', '"').replaceAll('<', '<').replaceAll('>', '>');\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"]}
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
isSecureRequest,
|
|
11
11
|
normalizeAuthKitConfig,
|
|
12
12
|
pkceCookiePrefix
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-MWXY4JSL.js";
|
|
14
14
|
|
|
15
15
|
// src/next/login.ts
|
|
16
16
|
function createLoginRouteHandler(config) {
|
|
@@ -189,4 +189,4 @@ export {
|
|
|
189
189
|
createNextAuthOptions,
|
|
190
190
|
createNextAuthRouteHandler
|
|
191
191
|
};
|
|
192
|
-
//# sourceMappingURL=chunk-
|
|
192
|
+
//# sourceMappingURL=chunk-QYGC4WNG.js.map
|
package/dist/cli.js
CHANGED
|
@@ -54,6 +54,7 @@ var package_default = {
|
|
|
54
54
|
files: ["dist", "README.md"],
|
|
55
55
|
scripts: {
|
|
56
56
|
build: "tsup && node ./scripts/copy-skill.mjs",
|
|
57
|
+
test: "pnpm build && node --test --experimental-strip-types ./scripts/verify-casdoor-proxy.mjs",
|
|
57
58
|
typecheck: "tsc -p tsconfig.json --noEmit",
|
|
58
59
|
dev: "tsup --watch"
|
|
59
60
|
},
|
|
@@ -166,6 +167,170 @@ export const dynamic = 'force-dynamic';
|
|
|
166
167
|
export const GET = logoutHandler;
|
|
167
168
|
`;
|
|
168
169
|
}
|
|
170
|
+
function callbackErrorPageTemplate() {
|
|
171
|
+
return `import { ClearDomainCookiesButton } from './clear-domain-cookies-button';
|
|
172
|
+
|
|
173
|
+
export const dynamic = 'force-dynamic';
|
|
174
|
+
|
|
175
|
+
export default async function CallbackErrorPage({
|
|
176
|
+
searchParams,
|
|
177
|
+
}: {
|
|
178
|
+
searchParams: Promise<{ title?: string; message?: string; details?: string }>;
|
|
179
|
+
}) {
|
|
180
|
+
const params = await searchParams;
|
|
181
|
+
|
|
182
|
+
return (
|
|
183
|
+
<main style={{ background: '#fff', borderRadius: 24, padding: 28, boxShadow: '0 18px 40px rgba(15, 23, 42, 0.08)' }}>
|
|
184
|
+
<h2 style={{ marginTop: 0 }}>{params.title ?? 'Callback Error'}</h2>
|
|
185
|
+
<p>{params.message ?? 'Unknown callback failure.'}</p>
|
|
186
|
+
{params.details ? <pre style={{ whiteSpace: 'pre-wrap' }}>{params.details}</pre> : null}
|
|
187
|
+
${customBegin}
|
|
188
|
+
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, marginTop: 24 }}>
|
|
189
|
+
<ClearDomainCookiesButton />
|
|
190
|
+
<a href="/" style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', minHeight: 44, padding: '0 16px', borderRadius: 9999, border: '1px solid rgba(148, 163, 184, 0.35)', color: '#0f172a', textDecoration: 'none', background: 'rgba(248, 250, 252, 0.9)' }}>\u8FD4\u56DE\u9996\u9875</a>
|
|
191
|
+
<a href="/auth/login" style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', minHeight: 44, padding: '0 16px', borderRadius: 9999, border: '1px solid rgba(148, 163, 184, 0.35)', color: '#0f172a', textDecoration: 'none', background: 'rgba(248, 250, 252, 0.9)' }}>\u91CD\u65B0\u767B\u5F55</a>
|
|
192
|
+
<a href="/auth/signup" style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', minHeight: 44, padding: '0 16px', borderRadius: 9999, border: '1px solid rgba(148, 163, 184, 0.35)', color: '#0f172a', textDecoration: 'none', background: 'rgba(248, 250, 252, 0.9)' }}>\u53BB\u6CE8\u518C</a>
|
|
193
|
+
</div>
|
|
194
|
+
${customEnd}
|
|
195
|
+
</main>
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
`;
|
|
199
|
+
}
|
|
200
|
+
function callbackErrorClearCookiesButtonTemplate() {
|
|
201
|
+
return `'use client';
|
|
202
|
+
|
|
203
|
+
import { useState } from 'react';
|
|
204
|
+
|
|
205
|
+
const AUTH_COOKIE_NAMES = [
|
|
206
|
+
'auth_origin',
|
|
207
|
+
'auth_redirect',
|
|
208
|
+
'oauth_state',
|
|
209
|
+
'pkce_code_verifier',
|
|
210
|
+
'next-auth.session-token',
|
|
211
|
+
'__Secure-next-auth.session-token',
|
|
212
|
+
'next-auth.csrf-token',
|
|
213
|
+
'__Secure-next-auth.csrf-token',
|
|
214
|
+
'__Host-next-auth.csrf-token',
|
|
215
|
+
];
|
|
216
|
+
|
|
217
|
+
function getPathCandidates(pathname: string): string[] {
|
|
218
|
+
const normalized = pathname.startsWith('/') ? pathname : '/' + pathname;
|
|
219
|
+
const segments = normalized.split('/').filter(Boolean);
|
|
220
|
+
const paths = new Set<string>(['/']);
|
|
221
|
+
|
|
222
|
+
let current = '';
|
|
223
|
+
for (const segment of segments) {
|
|
224
|
+
current += '/' + segment;
|
|
225
|
+
paths.add(current);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return [...paths];
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function getDomainCandidates(hostname: string): string[] {
|
|
232
|
+
const normalized = hostname.toLowerCase();
|
|
233
|
+
if (
|
|
234
|
+
normalized === 'localhost' ||
|
|
235
|
+
normalized.endsWith('.localhost') ||
|
|
236
|
+
/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(normalized) ||
|
|
237
|
+
/^\\[[^\\]]+\\]$/.test(normalized)
|
|
238
|
+
) {
|
|
239
|
+
return [];
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
const parts = normalized.split('.');
|
|
243
|
+
if (parts.length < 2) {
|
|
244
|
+
return [];
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const domains = new Set<string>();
|
|
248
|
+
for (let index = 0; index < parts.length - 1; index++) {
|
|
249
|
+
const suffix = parts.slice(index).join('.');
|
|
250
|
+
domains.add(suffix);
|
|
251
|
+
domains.add('.' + suffix);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return [...domains];
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function expireCookie(name: string, path: string, domain?: string) {
|
|
258
|
+
const pieces = [
|
|
259
|
+
name + '=',
|
|
260
|
+
'Max-Age=0',
|
|
261
|
+
'Expires=Thu, 01 Jan 1970 00:00:00 GMT',
|
|
262
|
+
'Path=' + path,
|
|
263
|
+
'SameSite=Lax',
|
|
264
|
+
];
|
|
265
|
+
|
|
266
|
+
if (domain) {
|
|
267
|
+
pieces.push('Domain=' + domain);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (window.location.protocol === 'https:') {
|
|
271
|
+
pieces.push('Secure');
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
document.cookie = pieces.join('; ');
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
${customBegin}
|
|
278
|
+
export function ClearDomainCookiesButton() {
|
|
279
|
+
const [cleared, setCleared] = useState(false);
|
|
280
|
+
|
|
281
|
+
const handleClick = () => {
|
|
282
|
+
if (typeof document === 'undefined' || typeof window === 'undefined') {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const names = new Set<string>(AUTH_COOKIE_NAMES);
|
|
287
|
+
for (const entry of document.cookie.split(';')) {
|
|
288
|
+
const [rawName] = entry.trim().split('=');
|
|
289
|
+
if (rawName) {
|
|
290
|
+
names.add(rawName);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const pathCandidates = getPathCandidates(window.location.pathname);
|
|
295
|
+
const domainCandidates = getDomainCandidates(window.location.hostname);
|
|
296
|
+
|
|
297
|
+
for (const name of names) {
|
|
298
|
+
for (const path of pathCandidates) {
|
|
299
|
+
expireCookie(name, path);
|
|
300
|
+
for (const domain of domainCandidates) {
|
|
301
|
+
expireCookie(name, path, domain);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
setCleared(true);
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
return (
|
|
310
|
+
<button
|
|
311
|
+
type="button"
|
|
312
|
+
onClick={handleClick}
|
|
313
|
+
disabled={cleared}
|
|
314
|
+
style={{
|
|
315
|
+
display: 'inline-flex',
|
|
316
|
+
alignItems: 'center',
|
|
317
|
+
justifyContent: 'center',
|
|
318
|
+
minHeight: 44,
|
|
319
|
+
padding: '0 16px',
|
|
320
|
+
borderRadius: 9999,
|
|
321
|
+
border: '1px solid rgba(148, 163, 184, 0.35)',
|
|
322
|
+
color: '#0f172a',
|
|
323
|
+
background: cleared ? 'rgba(220, 252, 231, 0.92)' : 'rgba(248, 250, 252, 0.9)',
|
|
324
|
+
cursor: cleared ? 'default' : 'pointer',
|
|
325
|
+
}}
|
|
326
|
+
>
|
|
327
|
+
{cleared ? '\u5DF2\u6E05\u7A7A' : '\u6E05\u7A7A\u5F53\u524D\u57DF Cookie'}
|
|
328
|
+
</button>
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
${customEnd}
|
|
332
|
+
`;
|
|
333
|
+
}
|
|
169
334
|
function authConfigTemplate() {
|
|
170
335
|
return `import {
|
|
171
336
|
createCallbackHandler,
|
|
@@ -366,6 +531,8 @@ var targets = [
|
|
|
366
531
|
["app/(auth-kit)/auth/payment/success/route.ts", paymentSuccessRouteTemplate],
|
|
367
532
|
["app/(auth-kit)/auth/payment/finished/route.ts", paymentFinishedRouteTemplate],
|
|
368
533
|
["app/(auth-kit)/callback/route.ts", callbackRouteTemplate],
|
|
534
|
+
["app/(auth-kit)/callback/error/page.tsx", callbackErrorPageTemplate],
|
|
535
|
+
["app/(auth-kit)/callback/error/clear-domain-cookies-button.tsx", callbackErrorClearCookiesButtonTemplate],
|
|
369
536
|
["app/(auth-kit)/logout/route.ts", logoutRouteTemplate],
|
|
370
537
|
["app/(auth-kit)/auth/api/commerce/[...path]/route.ts", commerceProxyRouteTemplate],
|
|
371
538
|
["lib/billing/payment-success.ts", billingPaymentSuccessHandlerTemplate],
|
|
@@ -383,6 +550,7 @@ var deprecatedTargets = [
|
|
|
383
550
|
"app/(auth-kit)/signup/oauth/authorize/route.ts",
|
|
384
551
|
"app/(auth-kit)/auth/payment-success/route.ts",
|
|
385
552
|
"app/(auth-kit)/auth/payment/finished/page.tsx",
|
|
553
|
+
"app/(auth-kit)/callback/error/page.tsx",
|
|
386
554
|
"app/auth/index-html.ts",
|
|
387
555
|
"app/auth/libs/index.ts",
|
|
388
556
|
"app/auth/libs/auth-config.ts",
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json","../src/cli/operations.ts","../src/cli/fs.ts","../src/cli/templates.ts","../src/cli/index.ts","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"@foldspace-fe/casdoor-next-auth-kit\",\n \"version\": \"0.1.0\",\n \"private\": false,\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/foldspace-stack/casdoor-next-auth-kit\"\n },\n \"homepage\": \"https://github.com/foldspace-stack/casdoor-next-auth-kit#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/foldspace-stack/casdoor-next-auth-kit/issues\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./casdoor\": {\n \"types\": \"./dist/casdoor/index.d.ts\",\n \"default\": \"./dist/casdoor/index.js\"\n },\n \"./next\": {\n \"types\": \"./dist/next/index.d.ts\",\n \"default\": \"./dist/next/index.js\"\n },\n \"./billing\": {\n \"types\": \"./dist/billing/index.d.ts\",\n \"default\": \"./dist/billing/index.js\"\n },\n \"./react\": {\n \"types\": \"./dist/react/index.d.ts\",\n \"default\": \"./dist/react/index.js\"\n }\n },\n \"bin\": {\n \"casdoor-next-auth-kit\": \"./dist/cli.js\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"files\": [\"dist\", \"README.md\"],\n \"scripts\": {\n \"build\": \"tsup && node ./scripts/copy-skill.mjs\",\n \"typecheck\": \"tsc -p tsconfig.json --noEmit\",\n \"dev\": \"tsup --watch\"\n },\n \"peerDependencies\": {\n \"next\": \">=16\",\n \"next-auth\": \"^4.24.0\",\n \"react\": \">=19\",\n \"react-dom\": \">=19\"\n },\n \"dependencies\": {\n \"jose\": \"^6.1.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.15.0\",\n \"@types/react\": \"^19.2.0\",\n \"@types/react-dom\": \"^19.2.0\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.6.3\"\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { AUTH_KIT_ENV_FILES, getMissingManagedEnvKeys } from '../core/env';\nimport { exists, preserveCustomBlock, read, removePath, writeGeneratedFile, writeTextFile } from './fs';\nimport {\n apiProxyRouteTemplate,\n authConfigTemplate,\n authIndexHtmlTemplate,\n authLoginRouteTemplate,\n authSignupRouteTemplate,\n authorizeRouteTemplate,\n callbackRouteTemplate,\n billingPaymentFinishedHandlerTemplate,\n billingPaymentSuccessHandlerTemplate,\n commerceProxyRouteTemplate,\n envTemplate,\n logoutRouteTemplate,\n nextAuthRouteTemplate,\n paymentFinishedRouteTemplate,\n paymentSuccessRouteTemplate,\n prismaSchemaTemplate,\n signupAuthorizeRouteTemplate,\n} from './templates';\n\nconst projectRoot = process.cwd();\nconst distRoot = path.dirname(fileURLToPath(import.meta.url));\nconst canonicalSkillPaths = [\n path.join(distRoot, 'skills/casdoor-next-auth-kit'),\n path.resolve(distRoot, '..', '..', '..', 'skills/casdoor-next-auth-kit'),\n];\nconst skillTarget = '.agents/skills/casdoor-next-auth-kit';\n\nconst targets = [\n ['app/(auth-kit)/auth-config.ts', authConfigTemplate],\n ['app/(auth-kit)/auth/login/route.ts', authLoginRouteTemplate],\n ['app/(auth-kit)/auth/signup/route.ts', authSignupRouteTemplate],\n ['app/(auth-kit)/login/oauth/authorize/route.ts', authorizeRouteTemplate],\n ['app/(auth-kit)/signup/oauth/authorize/route.ts', signupAuthorizeRouteTemplate],\n ['app/(auth-kit)/auth/api/[...path]/route.ts', apiProxyRouteTemplate],\n ['app/(auth-kit)/api/auth/[...nextauth]/route.ts', nextAuthRouteTemplate],\n ['app/(auth-kit)/auth/payment/success/route.ts', paymentSuccessRouteTemplate],\n ['app/(auth-kit)/auth/payment/finished/route.ts', paymentFinishedRouteTemplate],\n ['app/(auth-kit)/callback/route.ts', callbackRouteTemplate],\n ['app/(auth-kit)/logout/route.ts', logoutRouteTemplate],\n ['app/(auth-kit)/auth/api/commerce/[...path]/route.ts', commerceProxyRouteTemplate],\n ['lib/billing/payment-success.ts', billingPaymentSuccessHandlerTemplate],\n ['lib/billing/payment-finished.ts', billingPaymentFinishedHandlerTemplate],\n ['app/(auth-kit)/index-html.ts', authIndexHtmlTemplate],\n ['prisma/auth-kit.prisma', prismaSchemaTemplate],\n] as const;\n\nconst deprecatedTargets = [\n 'app/(auth-kit)/api/casdoor/[...path]/route.ts',\n 'app/(auth-kit)/api/casdoor/commerce/[...path]/route.ts',\n 'app/(auth-kit)/auth/api/casdoor/[...path]/route.ts',\n 'app/(auth-kit)/auth/api/casdoor/commerce/[...path]/route.ts',\n 'app/(auth-kit)/login/route.ts',\n 'app/(auth-kit)/signup/route.ts',\n 'app/(auth-kit)/signup/oauth/authorize/route.ts',\n 'app/(auth-kit)/auth/payment-success/route.ts',\n 'app/(auth-kit)/auth/payment/finished/page.tsx',\n 'app/auth/index-html.ts',\n 'app/auth/libs/index.ts',\n 'app/auth/libs/auth-config.ts',\n 'app/auth/libs/casdoor-config.ts',\n 'app/auth/libs/session-token.ts',\n 'app/auth/libs/oauth-state.ts',\n 'app/auth/libs/page-proxy.ts',\n 'app/auth/libs/api-proxy.ts',\n 'app/auth/libs/casdoor-oauth.ts',\n 'app/auth/libs/nextauth-route.ts',\n 'app/auth/libs',\n 'lib/auth-kit/index.ts',\n 'lib/auth-kit/index-html.ts',\n 'lib/auth-kit',\n 'lib/casdoor-entry.ts',\n 'lib/auth.ts',\n 'lib/public-origin.ts',\n 'lib/request-security.ts',\n 'lib/auth-redirect.ts',\n] as const;\n\nfunction logCreated(filePath: string) {\n console.log(`+ ${path.relative(projectRoot, filePath)}`);\n}\n\nfunction logUpdated(filePath: string) {\n console.log(`~ ${path.relative(projectRoot, filePath)}`);\n}\n\nfunction logRemoved(filePath: string) {\n console.log(`- ${path.relative(projectRoot, filePath)}`);\n}\n\nfunction syncManagedEnvFiles() {\n for (const file of AUTH_KIT_ENV_FILES) {\n const filePath = path.join(projectRoot, file);\n const existed = exists(filePath);\n const current = existed ? read(filePath) : '';\n const next = envTemplate(file, current);\n if (!existed || current !== next) {\n writeTextFile(filePath, next);\n if (!existed) {\n logCreated(filePath);\n } else {\n logUpdated(filePath);\n }\n }\n }\n}\n\nfunction syncManagedSkillFile() {\n const filePath = path.join(projectRoot, skillTarget);\n try {\n const sourcePath = canonicalSkillPaths.find((candidate) => fs.existsSync(candidate));\n if (!sourcePath) {\n throw new Error(`Unable to locate canonical skill directory. Checked: ${canonicalSkillPaths.join(', ')}`);\n }\n removePath(filePath);\n fs.mkdirSync(filePath, { recursive: true });\n logCreated(filePath);\n for (const entry of fs.readdirSync(sourcePath, { withFileTypes: true })) {\n const sourceEntry = path.join(sourcePath, entry.name);\n const targetEntry = path.join(filePath, entry.name);\n if (entry.isDirectory()) {\n fs.cpSync(sourceEntry, targetEntry, { recursive: true });\n console.log(`+ ${path.relative(projectRoot, targetEntry)}/`);\n continue;\n }\n fs.copyFileSync(sourceEntry, targetEntry);\n console.log(`+ ${path.relative(projectRoot, targetEntry)}`);\n }\n } catch (error) {\n console.warn(`Skipped skill sync for ${skillTarget}: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\nexport async function initProject() {\n for (const [rel, factory] of targets) {\n const filePath = path.join(projectRoot, rel);\n if (!exists(filePath)) {\n writeGeneratedFile(filePath, factory());\n logCreated(filePath);\n }\n }\n\n syncManagedEnvFiles();\n syncManagedSkillFile();\n console.log('Initialized casdoor-next-auth-kit managed files.');\n}\n\nexport async function updateProject() {\n for (const rel of deprecatedTargets) {\n const filePath = path.join(projectRoot, rel);\n if (exists(filePath)) {\n removePath(filePath);\n logRemoved(filePath);\n }\n }\n\n for (const [rel, factory] of targets) {\n const filePath = path.join(projectRoot, rel);\n const next = '// generated by @foldspace-fe/casdoor-next-auth-kit\\n' + factory();\n if (!exists(filePath)) {\n writeGeneratedFile(filePath, factory());\n logCreated(filePath);\n continue;\n }\n\n if (rel === 'app/(auth-kit)/auth-config.ts') {\n const current = read(filePath);\n if (current !== next) {\n writeTextFile(filePath, next);\n logUpdated(filePath);\n }\n continue;\n }\n\n const current = read(filePath);\n const updated = preserveCustomBlock(current, next);\n if (current !== updated) {\n writeTextFile(filePath, updated);\n logUpdated(filePath);\n }\n }\n\n syncManagedEnvFiles();\n syncManagedSkillFile();\n console.log('Updated managed route shells, env files, and skill file.');\n}\n\nexport async function checkProject() {\n const missingRoutes = targets.filter(([rel]) => !exists(path.join(projectRoot, rel))).map(([rel]) => rel);\n const missingEnv = AUTH_KIT_ENV_FILES.filter((file) => {\n const filePath = path.join(projectRoot, file);\n if (!exists(filePath)) {\n return true;\n }\n return getMissingManagedEnvKeys(read(filePath)).length > 0;\n });\n const skillDir = path.join(projectRoot, skillTarget);\n const missingSkill = exists(path.join(skillDir, 'SKILL.md')) ? [] : [path.join(skillTarget, 'SKILL.md')];\n const missing = [...missingRoutes, ...missingEnv, ...missingSkill];\n\n if (missing.length > 0) {\n console.error('Missing generated files:');\n for (const rel of missing) {\n console.error('- ' + rel);\n }\n process.exitCode = 1;\n return;\n }\n\n console.log('All managed files are present.');\n}\n"," import fs from 'node:fs';\n import path from 'node:path';\n\n export const generatedHeader = '// generated by @foldspace-fe/casdoor-next-auth-kit\\n';\n export const customBegin = '// @foldspace-fe/casdoor-next-auth-kit:begin custom';\n export const customEnd = '// @foldspace-fe/casdoor-next-auth-kit:end custom';\n\nexport function ensureDir(filePath: string) {\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n}\n\nexport function writeGeneratedFile(filePath: string, content: string) {\n ensureDir(filePath);\n fs.writeFileSync(filePath, generatedHeader + content, 'utf8');\n}\n\nexport function writeTextFile(filePath: string, content: string) {\n ensureDir(filePath);\n fs.writeFileSync(filePath, content, 'utf8');\n}\n\nexport function exists(filePath: string) {\n return fs.existsSync(filePath);\n}\n\n export function read(filePath: string) {\n return fs.readFileSync(filePath, 'utf8');\n }\n\nexport function preserveCustomBlock(existing: string, next: string) {\n const begin = existing.indexOf(customBegin);\n const end = existing.indexOf(customEnd);\n if (begin === -1 || end === -1 || end <= begin) return next;\n const custom = existing.slice(begin, end + customEnd.length);\n const targetBegin = next.indexOf(customBegin);\n const targetEnd = next.indexOf(customEnd);\n if (targetBegin === -1 || targetEnd === -1 || targetEnd <= targetBegin) return next;\n return next.slice(0, targetBegin) + custom + next.slice(targetEnd + customEnd.length);\n}\n\nexport function removePath(filePath: string) {\n fs.rmSync(filePath, { force: true, recursive: true });\n}\n","import { customBegin, customEnd } from './fs';\nimport { buildAuthPrismaSchemaTemplate } from '../prisma/schema-template';\nimport { AUTH_KIT_ENV_FILES, buildManagedEnvTemplate } from '../core/env';\n\nexport function authLoginRouteTemplate() {\n return `import { loginHandler } from '../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = loginHandler;\n`;\n}\n\nexport function authSignupRouteTemplate() {\n return `import { signupHandler } from '../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = signupHandler;\n`;\n}\n\nexport function authorizeRouteTemplate() {\n return `import { authorizeHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = authorizeHandler;\n`;\n}\n\nexport function signupAuthorizeRouteTemplate() {\n return `import { authorizeHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = authorizeHandler;\n`;\n}\n\nexport function callbackRouteTemplate() {\n return `import { callbackHandler } from '../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = callbackHandler;\n`;\n}\n\nexport function logoutRouteTemplate() {\n return `import { logoutHandler } from '../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = logoutHandler;\n`;\n}\n\nexport function authConfigTemplate() {\n return `import {\n createCallbackHandler,\n createCasdoorApiProxyHandler,\n createCasdoorCommerceProxyHandler,\n createAuthorizeRouteHandler,\n createLoginRouteHandler,\n createLogoutHandler,\n createNextAuthOptions,\n createSignupRouteHandler,\n type AuthBusinessAdapter,\n type AuthKitConfig,\n type AuthPersistenceAdapter,\n} from '@foldspace-fe/casdoor-next-auth-kit';\nimport { isGlobalAdminEmail } from '@foldspace-fe/casdoor-next-auth-kit';\nimport { paymentSuccessHandler as billingPaymentSuccessHandler } from '@/lib/billing/payment-success';\nimport { paymentFinishedHandler as billingPaymentFinishedHandler } from '@/lib/billing/payment-finished';\n\nexport function createAuthKitConfig(): AuthKitConfig {\n return {\n appUrl: process.env.APP_URL || '',\n nextauthSecret: process.env.NEXTAUTH_SECRET || 'dev-nextauth-secret',\n casdoor: {\n serverUrl: process.env.NEXT_PUBLIC_CASDOOR_SERVER_URL || process.env.CASDOOR_SERVER_URL || '',\n clientId: process.env.NEXT_PUBLIC_CASDOOR_CLIENT_ID || process.env.CASDOOR_CLIENT_ID || '',\n clientSecret: process.env.CASDOOR_CLIENT_SECRET || '',\n appName: process.env.NEXT_PUBLIC_CASDOOR_APP_NAME || '',\n organizationName: process.env.NEXT_PUBLIC_CASDOOR_ORGANIZATION_NAME || '',\n redirectPath: process.env.NEXT_PUBLIC_CASDOOR_REDIRECT_PATH || '/callback',\n signinPath: process.env.NEXT_PUBLIC_CASDOOR_SIGNIN_PATH || '/login/oauth/authorize',\n },\n };\n}\n\nexport const authKitConfig = createAuthKitConfig();\n\nexport const adapter: AuthBusinessAdapter = {\n isAdminEmail: isGlobalAdminEmail,\n};\n\nexport const persistence: AuthPersistenceAdapter = {\n async syncAuthUser() {\n return;\n },\n async findAuthUser() {\n return null;\n },\n};\n\nexport const paymentSuccessHandler = billingPaymentSuccessHandler;\nexport const paymentFinishedHandler = billingPaymentFinishedHandler;\n\nexport const loginHandler = createLoginRouteHandler(authKitConfig);\nexport const signupHandler = createSignupRouteHandler(authKitConfig);\nexport const authorizeHandler = createAuthorizeRouteHandler(authKitConfig);\nexport const callbackHandler = createCallbackHandler({\n config: authKitConfig,\n adapter,\n persistence,\n});\nexport const logoutHandler = createLogoutHandler(authKitConfig);\nexport const authOptions = createNextAuthOptions({\n config: authKitConfig,\n adapter,\n persistence,\n});\nexport const apiProxyHandler = createCasdoorApiProxyHandler(authKitConfig, '/auth/api', '/api');\nexport const commerceProxyHandler = createCasdoorCommerceProxyHandler(authKitConfig, '/auth/api/commerce', '/api/commerce');\n`;\n}\n\nexport function nextAuthRouteTemplate() {\n return `import NextAuth from 'next-auth';\nimport { createNextAuthOptions } from '@foldspace-fe/casdoor-next-auth-kit';\nimport { adapter, authKitConfig, persistence } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\nexport const runtime = 'nodejs';\n\nconst handler = NextAuth(\n createNextAuthOptions({\n config: authKitConfig,\n adapter,\n persistence,\n }),\n);\n\nexport const GET = handler;\nexport const POST = handler;\n`;\n}\n\nexport function paymentSuccessRouteTemplate() {\n return `import { createBillingPaymentSuccessRouteHandler } from '@foldspace-fe/casdoor-next-auth-kit';\nimport { authKitConfig, paymentSuccessHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\nexport const runtime = 'nodejs';\n\nexport const GET = createBillingPaymentSuccessRouteHandler({\n appUrl: authKitConfig.appUrl,\n fallbackRedirect: '/auth/payment/finished',\n handler: paymentSuccessHandler,\n});\n`;\n}\n\nexport function paymentFinishedRouteTemplate() {\n return `import { createBillingPaymentFinishedRouteHandler } from '@foldspace-fe/casdoor-next-auth-kit';\nimport { authKitConfig, paymentFinishedHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\nexport const runtime = 'nodejs';\n\nexport const GET = createBillingPaymentFinishedRouteHandler({\n appUrl: authKitConfig.appUrl,\n fallbackRedirect: '/',\n handler: paymentFinishedHandler,\n});\n`;\n}\n\nexport function billingPaymentSuccessHandlerTemplate() {\n return `import type { BillingPaymentSuccessHandler } from '@foldspace-fe/casdoor-next-auth-kit/billing';\n\n${customBegin}\nconst paymentSuccessHandlerImpl: BillingPaymentSuccessHandler = async () => {\n return;\n};\n${customEnd}\n\nexport const paymentSuccessHandler: BillingPaymentSuccessHandler = paymentSuccessHandlerImpl;\n`;\n}\n\nexport function billingPaymentFinishedHandlerTemplate() {\n return `import type { BillingPaymentFinishedHandler } from '@foldspace-fe/casdoor-next-auth-kit/billing';\n\n${customBegin}\nconst paymentFinishedHandlerImpl: BillingPaymentFinishedHandler = async () => {\n return;\n};\n${customEnd}\n\nexport const paymentFinishedHandler: BillingPaymentFinishedHandler = paymentFinishedHandlerImpl;\n`;\n}\n\n export function authIndexHtmlTemplate() {\n return `export { AUTH_INDEX_HTML, createAuthIndexHtml } from '@foldspace-fe/casdoor-next-auth-kit';\n`;\n }\n\n export function prismaSchemaTemplate() {\n return buildAuthPrismaSchemaTemplate();\n }\n\nexport function apiProxyRouteTemplate() {\n return `import { apiProxyHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = apiProxyHandler;\nexport const HEAD = apiProxyHandler;\nexport const POST = apiProxyHandler;\nexport const PUT = apiProxyHandler;\nexport const PATCH = apiProxyHandler;\nexport const DELETE = apiProxyHandler;\nexport const OPTIONS = apiProxyHandler;\n`;\n}\n\nexport function commerceProxyRouteTemplate() {\n return `import { commerceProxyHandler } from '../../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = commerceProxyHandler;\nexport const HEAD = commerceProxyHandler;\nexport const POST = commerceProxyHandler;\nexport const PUT = commerceProxyHandler;\nexport const PATCH = commerceProxyHandler;\nexport const DELETE = commerceProxyHandler;\nexport const OPTIONS = commerceProxyHandler;\n`;\n}\n\n export function envTemplate(file: typeof AUTH_KIT_ENV_FILES[number], existingContent = '') {\n return buildManagedEnvTemplate(file, existingContent);\n }\n","import packageJson from '../../package.json';\n\nimport { initProject, checkProject, updateProject } from './operations';\n\nfunction printUsage() {\n console.log('Usage: npx @foldspace-fe/casdoor-next-auth-kit@latest <init|update|check>');\n console.log(' npx @foldspace-fe/casdoor-next-auth-kit@latest --help');\n console.log(' npx @foldspace-fe/casdoor-next-auth-kit@latest --version');\n}\n\nexport async function runCli(argv: string[]) {\n const command = argv[0] ?? 'help';\n if (command === '--help' || command === '-h' || command === 'help') {\n printUsage();\n return;\n }\n if (command === '--version' || command === '-v') {\n console.log(packageJson.version);\n return;\n }\n if (command === 'init') return initProject();\n if (command === 'update') return updateProject();\n if (command === 'check') return checkProject();\n printUsage();\n}\n","#!/usr/bin/env node\nimport { runCli } from './cli/index';\n\nrunCli(process.argv.slice(2)).catch((error) => {\n console.error(error instanceof Error ? error.message : error);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path","path","fs","current"]}
|
|
1
|
+
{"version":3,"sources":["../package.json","../src/cli/operations.ts","../src/cli/fs.ts","../src/cli/templates.ts","../src/cli/index.ts","../src/cli.ts"],"sourcesContent":["{\n \"name\": \"@foldspace-fe/casdoor-next-auth-kit\",\n \"version\": \"0.1.0\",\n \"private\": false,\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/foldspace-stack/casdoor-next-auth-kit\"\n },\n \"homepage\": \"https://github.com/foldspace-stack/casdoor-next-auth-kit#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/foldspace-stack/casdoor-next-auth-kit/issues\"\n },\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./casdoor\": {\n \"types\": \"./dist/casdoor/index.d.ts\",\n \"default\": \"./dist/casdoor/index.js\"\n },\n \"./next\": {\n \"types\": \"./dist/next/index.d.ts\",\n \"default\": \"./dist/next/index.js\"\n },\n \"./billing\": {\n \"types\": \"./dist/billing/index.d.ts\",\n \"default\": \"./dist/billing/index.js\"\n },\n \"./react\": {\n \"types\": \"./dist/react/index.d.ts\",\n \"default\": \"./dist/react/index.js\"\n }\n },\n \"bin\": {\n \"casdoor-next-auth-kit\": \"./dist/cli.js\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"provenance\": true\n },\n \"files\": [\"dist\", \"README.md\"],\n \"scripts\": {\n \"build\": \"tsup && node ./scripts/copy-skill.mjs\",\n \"test\": \"pnpm build && node --test --experimental-strip-types ./scripts/verify-casdoor-proxy.mjs\",\n \"typecheck\": \"tsc -p tsconfig.json --noEmit\",\n \"dev\": \"tsup --watch\"\n },\n \"peerDependencies\": {\n \"next\": \">=16\",\n \"next-auth\": \"^4.24.0\",\n \"react\": \">=19\",\n \"react-dom\": \">=19\"\n },\n \"dependencies\": {\n \"jose\": \"^6.1.0\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^22.15.0\",\n \"@types/react\": \"^19.2.0\",\n \"@types/react-dom\": \"^19.2.0\",\n \"tsup\": \"^8.5.0\",\n \"typescript\": \"^5.6.3\"\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { AUTH_KIT_ENV_FILES, getMissingManagedEnvKeys } from '../core/env';\nimport { exists, preserveCustomBlock, read, removePath, writeGeneratedFile, writeTextFile } from './fs';\nimport {\n apiProxyRouteTemplate,\n authConfigTemplate,\n authIndexHtmlTemplate,\n authLoginRouteTemplate,\n authSignupRouteTemplate,\n callbackErrorClearCookiesButtonTemplate,\n callbackErrorPageTemplate,\n authorizeRouteTemplate,\n callbackRouteTemplate,\n billingPaymentFinishedHandlerTemplate,\n billingPaymentSuccessHandlerTemplate,\n commerceProxyRouteTemplate,\n envTemplate,\n logoutRouteTemplate,\n nextAuthRouteTemplate,\n paymentFinishedRouteTemplate,\n paymentSuccessRouteTemplate,\n prismaSchemaTemplate,\n signupAuthorizeRouteTemplate,\n} from './templates';\n\nconst projectRoot = process.cwd();\nconst distRoot = path.dirname(fileURLToPath(import.meta.url));\nconst canonicalSkillPaths = [\n path.join(distRoot, 'skills/casdoor-next-auth-kit'),\n path.resolve(distRoot, '..', '..', '..', 'skills/casdoor-next-auth-kit'),\n];\nconst skillTarget = '.agents/skills/casdoor-next-auth-kit';\n\nconst targets = [\n ['app/(auth-kit)/auth-config.ts', authConfigTemplate],\n ['app/(auth-kit)/auth/login/route.ts', authLoginRouteTemplate],\n ['app/(auth-kit)/auth/signup/route.ts', authSignupRouteTemplate],\n ['app/(auth-kit)/login/oauth/authorize/route.ts', authorizeRouteTemplate],\n ['app/(auth-kit)/signup/oauth/authorize/route.ts', signupAuthorizeRouteTemplate],\n ['app/(auth-kit)/auth/api/[...path]/route.ts', apiProxyRouteTemplate],\n ['app/(auth-kit)/api/auth/[...nextauth]/route.ts', nextAuthRouteTemplate],\n ['app/(auth-kit)/auth/payment/success/route.ts', paymentSuccessRouteTemplate],\n ['app/(auth-kit)/auth/payment/finished/route.ts', paymentFinishedRouteTemplate],\n ['app/(auth-kit)/callback/route.ts', callbackRouteTemplate],\n ['app/(auth-kit)/callback/error/page.tsx', callbackErrorPageTemplate],\n ['app/(auth-kit)/callback/error/clear-domain-cookies-button.tsx', callbackErrorClearCookiesButtonTemplate],\n ['app/(auth-kit)/logout/route.ts', logoutRouteTemplate],\n ['app/(auth-kit)/auth/api/commerce/[...path]/route.ts', commerceProxyRouteTemplate],\n ['lib/billing/payment-success.ts', billingPaymentSuccessHandlerTemplate],\n ['lib/billing/payment-finished.ts', billingPaymentFinishedHandlerTemplate],\n ['app/(auth-kit)/index-html.ts', authIndexHtmlTemplate],\n ['prisma/auth-kit.prisma', prismaSchemaTemplate],\n] as const;\n\nconst deprecatedTargets = [\n 'app/(auth-kit)/api/casdoor/[...path]/route.ts',\n 'app/(auth-kit)/api/casdoor/commerce/[...path]/route.ts',\n 'app/(auth-kit)/auth/api/casdoor/[...path]/route.ts',\n 'app/(auth-kit)/auth/api/casdoor/commerce/[...path]/route.ts',\n 'app/(auth-kit)/login/route.ts',\n 'app/(auth-kit)/signup/route.ts',\n 'app/(auth-kit)/signup/oauth/authorize/route.ts',\n 'app/(auth-kit)/auth/payment-success/route.ts',\n 'app/(auth-kit)/auth/payment/finished/page.tsx',\n 'app/(auth-kit)/callback/error/page.tsx',\n 'app/auth/index-html.ts',\n 'app/auth/libs/index.ts',\n 'app/auth/libs/auth-config.ts',\n 'app/auth/libs/casdoor-config.ts',\n 'app/auth/libs/session-token.ts',\n 'app/auth/libs/oauth-state.ts',\n 'app/auth/libs/page-proxy.ts',\n 'app/auth/libs/api-proxy.ts',\n 'app/auth/libs/casdoor-oauth.ts',\n 'app/auth/libs/nextauth-route.ts',\n 'app/auth/libs',\n 'lib/auth-kit/index.ts',\n 'lib/auth-kit/index-html.ts',\n 'lib/auth-kit',\n 'lib/casdoor-entry.ts',\n 'lib/auth.ts',\n 'lib/public-origin.ts',\n 'lib/request-security.ts',\n 'lib/auth-redirect.ts',\n] as const;\n\nfunction logCreated(filePath: string) {\n console.log(`+ ${path.relative(projectRoot, filePath)}`);\n}\n\nfunction logUpdated(filePath: string) {\n console.log(`~ ${path.relative(projectRoot, filePath)}`);\n}\n\nfunction logRemoved(filePath: string) {\n console.log(`- ${path.relative(projectRoot, filePath)}`);\n}\n\nfunction syncManagedEnvFiles() {\n for (const file of AUTH_KIT_ENV_FILES) {\n const filePath = path.join(projectRoot, file);\n const existed = exists(filePath);\n const current = existed ? read(filePath) : '';\n const next = envTemplate(file, current);\n if (!existed || current !== next) {\n writeTextFile(filePath, next);\n if (!existed) {\n logCreated(filePath);\n } else {\n logUpdated(filePath);\n }\n }\n }\n}\n\nfunction syncManagedSkillFile() {\n const filePath = path.join(projectRoot, skillTarget);\n try {\n const sourcePath = canonicalSkillPaths.find((candidate) => fs.existsSync(candidate));\n if (!sourcePath) {\n throw new Error(`Unable to locate canonical skill directory. Checked: ${canonicalSkillPaths.join(', ')}`);\n }\n removePath(filePath);\n fs.mkdirSync(filePath, { recursive: true });\n logCreated(filePath);\n for (const entry of fs.readdirSync(sourcePath, { withFileTypes: true })) {\n const sourceEntry = path.join(sourcePath, entry.name);\n const targetEntry = path.join(filePath, entry.name);\n if (entry.isDirectory()) {\n fs.cpSync(sourceEntry, targetEntry, { recursive: true });\n console.log(`+ ${path.relative(projectRoot, targetEntry)}/`);\n continue;\n }\n fs.copyFileSync(sourceEntry, targetEntry);\n console.log(`+ ${path.relative(projectRoot, targetEntry)}`);\n }\n } catch (error) {\n console.warn(`Skipped skill sync for ${skillTarget}: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\nexport async function initProject() {\n for (const [rel, factory] of targets) {\n const filePath = path.join(projectRoot, rel);\n if (!exists(filePath)) {\n writeGeneratedFile(filePath, factory());\n logCreated(filePath);\n }\n }\n\n syncManagedEnvFiles();\n syncManagedSkillFile();\n console.log('Initialized casdoor-next-auth-kit managed files.');\n}\n\nexport async function updateProject() {\n for (const rel of deprecatedTargets) {\n const filePath = path.join(projectRoot, rel);\n if (exists(filePath)) {\n removePath(filePath);\n logRemoved(filePath);\n }\n }\n\n for (const [rel, factory] of targets) {\n const filePath = path.join(projectRoot, rel);\n const next = '// generated by @foldspace-fe/casdoor-next-auth-kit\\n' + factory();\n if (!exists(filePath)) {\n writeGeneratedFile(filePath, factory());\n logCreated(filePath);\n continue;\n }\n\n if (rel === 'app/(auth-kit)/auth-config.ts') {\n const current = read(filePath);\n if (current !== next) {\n writeTextFile(filePath, next);\n logUpdated(filePath);\n }\n continue;\n }\n\n const current = read(filePath);\n const updated = preserveCustomBlock(current, next);\n if (current !== updated) {\n writeTextFile(filePath, updated);\n logUpdated(filePath);\n }\n }\n\n syncManagedEnvFiles();\n syncManagedSkillFile();\n console.log('Updated managed route shells, env files, and skill file.');\n}\n\nexport async function checkProject() {\n const missingRoutes = targets.filter(([rel]) => !exists(path.join(projectRoot, rel))).map(([rel]) => rel);\n const missingEnv = AUTH_KIT_ENV_FILES.filter((file) => {\n const filePath = path.join(projectRoot, file);\n if (!exists(filePath)) {\n return true;\n }\n return getMissingManagedEnvKeys(read(filePath)).length > 0;\n });\n const skillDir = path.join(projectRoot, skillTarget);\n const missingSkill = exists(path.join(skillDir, 'SKILL.md')) ? [] : [path.join(skillTarget, 'SKILL.md')];\n const missing = [...missingRoutes, ...missingEnv, ...missingSkill];\n\n if (missing.length > 0) {\n console.error('Missing generated files:');\n for (const rel of missing) {\n console.error('- ' + rel);\n }\n process.exitCode = 1;\n return;\n }\n\n console.log('All managed files are present.');\n}\n"," import fs from 'node:fs';\n import path from 'node:path';\n\n export const generatedHeader = '// generated by @foldspace-fe/casdoor-next-auth-kit\\n';\n export const customBegin = '// @foldspace-fe/casdoor-next-auth-kit:begin custom';\n export const customEnd = '// @foldspace-fe/casdoor-next-auth-kit:end custom';\n\nexport function ensureDir(filePath: string) {\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n}\n\nexport function writeGeneratedFile(filePath: string, content: string) {\n ensureDir(filePath);\n fs.writeFileSync(filePath, generatedHeader + content, 'utf8');\n}\n\nexport function writeTextFile(filePath: string, content: string) {\n ensureDir(filePath);\n fs.writeFileSync(filePath, content, 'utf8');\n}\n\nexport function exists(filePath: string) {\n return fs.existsSync(filePath);\n}\n\n export function read(filePath: string) {\n return fs.readFileSync(filePath, 'utf8');\n }\n\nexport function preserveCustomBlock(existing: string, next: string) {\n const begin = existing.indexOf(customBegin);\n const end = existing.indexOf(customEnd);\n if (begin === -1 || end === -1 || end <= begin) return next;\n const custom = existing.slice(begin, end + customEnd.length);\n const targetBegin = next.indexOf(customBegin);\n const targetEnd = next.indexOf(customEnd);\n if (targetBegin === -1 || targetEnd === -1 || targetEnd <= targetBegin) return next;\n return next.slice(0, targetBegin) + custom + next.slice(targetEnd + customEnd.length);\n}\n\nexport function removePath(filePath: string) {\n fs.rmSync(filePath, { force: true, recursive: true });\n}\n","import { customBegin, customEnd } from './fs';\nimport { buildAuthPrismaSchemaTemplate } from '../prisma/schema-template';\nimport { AUTH_KIT_ENV_FILES, buildManagedEnvTemplate } from '../core/env';\n\nexport function authLoginRouteTemplate() {\n return `import { loginHandler } from '../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = loginHandler;\n`;\n}\n\nexport function authSignupRouteTemplate() {\n return `import { signupHandler } from '../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = signupHandler;\n`;\n}\n\nexport function authorizeRouteTemplate() {\n return `import { authorizeHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = authorizeHandler;\n`;\n}\n\nexport function signupAuthorizeRouteTemplate() {\n return `import { authorizeHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = authorizeHandler;\n`;\n}\n\nexport function callbackRouteTemplate() {\n return `import { callbackHandler } from '../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = callbackHandler;\n`;\n}\n\nexport function logoutRouteTemplate() {\n return `import { logoutHandler } from '../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = logoutHandler;\n`;\n}\n\nexport function callbackErrorPageTemplate() {\n return `import { ClearDomainCookiesButton } from './clear-domain-cookies-button';\n\nexport const dynamic = 'force-dynamic';\n\nexport default async function CallbackErrorPage({\n searchParams,\n}: {\n searchParams: Promise<{ title?: string; message?: string; details?: string }>;\n}) {\n const params = await searchParams;\n\n return (\n <main style={{ background: '#fff', borderRadius: 24, padding: 28, boxShadow: '0 18px 40px rgba(15, 23, 42, 0.08)' }}>\n <h2 style={{ marginTop: 0 }}>{params.title ?? 'Callback Error'}</h2>\n <p>{params.message ?? 'Unknown callback failure.'}</p>\n {params.details ? <pre style={{ whiteSpace: 'pre-wrap' }}>{params.details}</pre> : null}\n${customBegin}\n <div style={{ display: 'flex', flexWrap: 'wrap', gap: 12, marginTop: 24 }}>\n <ClearDomainCookiesButton />\n <a href=\"/\" style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', minHeight: 44, padding: '0 16px', borderRadius: 9999, border: '1px solid rgba(148, 163, 184, 0.35)', color: '#0f172a', textDecoration: 'none', background: 'rgba(248, 250, 252, 0.9)' }}>返回首页</a>\n <a href=\"/auth/login\" style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', minHeight: 44, padding: '0 16px', borderRadius: 9999, border: '1px solid rgba(148, 163, 184, 0.35)', color: '#0f172a', textDecoration: 'none', background: 'rgba(248, 250, 252, 0.9)' }}>重新登录</a>\n <a href=\"/auth/signup\" style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', minHeight: 44, padding: '0 16px', borderRadius: 9999, border: '1px solid rgba(148, 163, 184, 0.35)', color: '#0f172a', textDecoration: 'none', background: 'rgba(248, 250, 252, 0.9)' }}>去注册</a>\n </div>\n${customEnd}\n </main>\n );\n}\n`;\n}\n\nexport function callbackErrorClearCookiesButtonTemplate() {\n return `'use client';\n\nimport { useState } from 'react';\n\nconst AUTH_COOKIE_NAMES = [\n 'auth_origin',\n 'auth_redirect',\n 'oauth_state',\n 'pkce_code_verifier',\n 'next-auth.session-token',\n '__Secure-next-auth.session-token',\n 'next-auth.csrf-token',\n '__Secure-next-auth.csrf-token',\n '__Host-next-auth.csrf-token',\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 getDomainCandidates(hostname: string): string[] {\n const normalized = hostname.toLowerCase();\n if (\n normalized === 'localhost' ||\n normalized.endsWith('.localhost') ||\n /^\\\\d+\\\\.\\\\d+\\\\.\\\\d+\\\\.\\\\d+$/.test(normalized) ||\n /^\\\\[[^\\\\]]+\\\\]$/.test(normalized)\n ) {\n return [];\n }\n\n const parts = normalized.split('.');\n if (parts.length < 2) {\n return [];\n }\n\n const domains = new Set<string>();\n for (let index = 0; index < parts.length - 1; index++) {\n const suffix = parts.slice(index).join('.');\n domains.add(suffix);\n domains.add('.' + suffix);\n }\n\n return [...domains];\n}\n\nfunction expireCookie(name: string, path: string, domain?: string) {\n const pieces = [\n name + '=',\n 'Max-Age=0',\n 'Expires=Thu, 01 Jan 1970 00:00:00 GMT',\n 'Path=' + path,\n 'SameSite=Lax',\n ];\n\n if (domain) {\n pieces.push('Domain=' + domain);\n }\n\n if (window.location.protocol === 'https:') {\n pieces.push('Secure');\n }\n\n document.cookie = pieces.join('; ');\n}\n\n${customBegin}\nexport function ClearDomainCookiesButton() {\n const [cleared, setCleared] = useState(false);\n\n const handleClick = () => {\n if (typeof document === 'undefined' || typeof window === 'undefined') {\n return;\n }\n\n const names = new Set<string>(AUTH_COOKIE_NAMES);\n for (const entry of document.cookie.split(';')) {\n const [rawName] = entry.trim().split('=');\n if (rawName) {\n names.add(rawName);\n }\n }\n\n const pathCandidates = getPathCandidates(window.location.pathname);\n const domainCandidates = getDomainCandidates(window.location.hostname);\n\n for (const name of names) {\n for (const path of pathCandidates) {\n expireCookie(name, path);\n for (const domain of domainCandidates) {\n expireCookie(name, path, domain);\n }\n }\n }\n\n setCleared(true);\n };\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n disabled={cleared}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n minHeight: 44,\n padding: '0 16px',\n borderRadius: 9999,\n border: '1px solid rgba(148, 163, 184, 0.35)',\n color: '#0f172a',\n background: cleared ? 'rgba(220, 252, 231, 0.92)' : 'rgba(248, 250, 252, 0.9)',\n cursor: cleared ? 'default' : 'pointer',\n }}\n >\n {cleared ? '已清空' : '清空当前域 Cookie'}\n </button>\n );\n}\n${customEnd}\n`;\n}\n\nexport function authConfigTemplate() {\n return `import {\n createCallbackHandler,\n createCasdoorApiProxyHandler,\n createCasdoorCommerceProxyHandler,\n createAuthorizeRouteHandler,\n createLoginRouteHandler,\n createLogoutHandler,\n createNextAuthOptions,\n createSignupRouteHandler,\n type AuthBusinessAdapter,\n type AuthKitConfig,\n type AuthPersistenceAdapter,\n} from '@foldspace-fe/casdoor-next-auth-kit';\nimport { isGlobalAdminEmail } from '@foldspace-fe/casdoor-next-auth-kit';\nimport { paymentSuccessHandler as billingPaymentSuccessHandler } from '@/lib/billing/payment-success';\nimport { paymentFinishedHandler as billingPaymentFinishedHandler } from '@/lib/billing/payment-finished';\n\nexport function createAuthKitConfig(): AuthKitConfig {\n return {\n appUrl: process.env.APP_URL || '',\n nextauthSecret: process.env.NEXTAUTH_SECRET || 'dev-nextauth-secret',\n casdoor: {\n serverUrl: process.env.NEXT_PUBLIC_CASDOOR_SERVER_URL || process.env.CASDOOR_SERVER_URL || '',\n clientId: process.env.NEXT_PUBLIC_CASDOOR_CLIENT_ID || process.env.CASDOOR_CLIENT_ID || '',\n clientSecret: process.env.CASDOOR_CLIENT_SECRET || '',\n appName: process.env.NEXT_PUBLIC_CASDOOR_APP_NAME || '',\n organizationName: process.env.NEXT_PUBLIC_CASDOOR_ORGANIZATION_NAME || '',\n redirectPath: process.env.NEXT_PUBLIC_CASDOOR_REDIRECT_PATH || '/callback',\n signinPath: process.env.NEXT_PUBLIC_CASDOOR_SIGNIN_PATH || '/login/oauth/authorize',\n },\n };\n}\n\nexport const authKitConfig = createAuthKitConfig();\n\nexport const adapter: AuthBusinessAdapter = {\n isAdminEmail: isGlobalAdminEmail,\n};\n\nexport const persistence: AuthPersistenceAdapter = {\n async syncAuthUser() {\n return;\n },\n async findAuthUser() {\n return null;\n },\n};\n\nexport const paymentSuccessHandler = billingPaymentSuccessHandler;\nexport const paymentFinishedHandler = billingPaymentFinishedHandler;\n\nexport const loginHandler = createLoginRouteHandler(authKitConfig);\nexport const signupHandler = createSignupRouteHandler(authKitConfig);\nexport const authorizeHandler = createAuthorizeRouteHandler(authKitConfig);\nexport const callbackHandler = createCallbackHandler({\n config: authKitConfig,\n adapter,\n persistence,\n});\nexport const logoutHandler = createLogoutHandler(authKitConfig);\nexport const authOptions = createNextAuthOptions({\n config: authKitConfig,\n adapter,\n persistence,\n});\nexport const apiProxyHandler = createCasdoorApiProxyHandler(authKitConfig, '/auth/api', '/api');\nexport const commerceProxyHandler = createCasdoorCommerceProxyHandler(authKitConfig, '/auth/api/commerce', '/api/commerce');\n`;\n}\n\nexport function nextAuthRouteTemplate() {\n return `import NextAuth from 'next-auth';\nimport { createNextAuthOptions } from '@foldspace-fe/casdoor-next-auth-kit';\nimport { adapter, authKitConfig, persistence } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\nexport const runtime = 'nodejs';\n\nconst handler = NextAuth(\n createNextAuthOptions({\n config: authKitConfig,\n adapter,\n persistence,\n }),\n);\n\nexport const GET = handler;\nexport const POST = handler;\n`;\n}\n\nexport function paymentSuccessRouteTemplate() {\n return `import { createBillingPaymentSuccessRouteHandler } from '@foldspace-fe/casdoor-next-auth-kit';\nimport { authKitConfig, paymentSuccessHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\nexport const runtime = 'nodejs';\n\nexport const GET = createBillingPaymentSuccessRouteHandler({\n appUrl: authKitConfig.appUrl,\n fallbackRedirect: '/auth/payment/finished',\n handler: paymentSuccessHandler,\n});\n`;\n}\n\nexport function paymentFinishedRouteTemplate() {\n return `import { createBillingPaymentFinishedRouteHandler } from '@foldspace-fe/casdoor-next-auth-kit';\nimport { authKitConfig, paymentFinishedHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\nexport const runtime = 'nodejs';\n\nexport const GET = createBillingPaymentFinishedRouteHandler({\n appUrl: authKitConfig.appUrl,\n fallbackRedirect: '/',\n handler: paymentFinishedHandler,\n});\n`;\n}\n\nexport function billingPaymentSuccessHandlerTemplate() {\n return `import type { BillingPaymentSuccessHandler } from '@foldspace-fe/casdoor-next-auth-kit/billing';\n\n${customBegin}\nconst paymentSuccessHandlerImpl: BillingPaymentSuccessHandler = async () => {\n return;\n};\n${customEnd}\n\nexport const paymentSuccessHandler: BillingPaymentSuccessHandler = paymentSuccessHandlerImpl;\n`;\n}\n\nexport function billingPaymentFinishedHandlerTemplate() {\n return `import type { BillingPaymentFinishedHandler } from '@foldspace-fe/casdoor-next-auth-kit/billing';\n\n${customBegin}\nconst paymentFinishedHandlerImpl: BillingPaymentFinishedHandler = async () => {\n return;\n};\n${customEnd}\n\nexport const paymentFinishedHandler: BillingPaymentFinishedHandler = paymentFinishedHandlerImpl;\n`;\n}\n\n export function authIndexHtmlTemplate() {\n return `export { AUTH_INDEX_HTML, createAuthIndexHtml } from '@foldspace-fe/casdoor-next-auth-kit';\n`;\n }\n\n export function prismaSchemaTemplate() {\n return buildAuthPrismaSchemaTemplate();\n }\n\nexport function apiProxyRouteTemplate() {\n return `import { apiProxyHandler } from '../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = apiProxyHandler;\nexport const HEAD = apiProxyHandler;\nexport const POST = apiProxyHandler;\nexport const PUT = apiProxyHandler;\nexport const PATCH = apiProxyHandler;\nexport const DELETE = apiProxyHandler;\nexport const OPTIONS = apiProxyHandler;\n`;\n}\n\nexport function commerceProxyRouteTemplate() {\n return `import { commerceProxyHandler } from '../../../../auth-config';\n\nexport const dynamic = 'force-dynamic';\n\nexport const GET = commerceProxyHandler;\nexport const HEAD = commerceProxyHandler;\nexport const POST = commerceProxyHandler;\nexport const PUT = commerceProxyHandler;\nexport const PATCH = commerceProxyHandler;\nexport const DELETE = commerceProxyHandler;\nexport const OPTIONS = commerceProxyHandler;\n`;\n}\n\n export function envTemplate(file: typeof AUTH_KIT_ENV_FILES[number], existingContent = '') {\n return buildManagedEnvTemplate(file, existingContent);\n }\n","import packageJson from '../../package.json';\n\nimport { initProject, checkProject, updateProject } from './operations';\n\nfunction printUsage() {\n console.log('Usage: npx @foldspace-fe/casdoor-next-auth-kit@latest <init|update|check>');\n console.log(' npx @foldspace-fe/casdoor-next-auth-kit@latest --help');\n console.log(' npx @foldspace-fe/casdoor-next-auth-kit@latest --version');\n}\n\nexport async function runCli(argv: string[]) {\n const command = argv[0] ?? 'help';\n if (command === '--help' || command === '-h' || command === 'help') {\n printUsage();\n return;\n }\n if (command === '--version' || command === '-v') {\n console.log(packageJson.version);\n return;\n }\n if (command === 'init') return initProject();\n if (command === 'update') return updateProject();\n if (command === 'check') return checkProject();\n printUsage();\n}\n","#!/usr/bin/env node\nimport { runCli } from './cli/index';\n\nrunCli(process.argv.slice(2)).catch((error) => {\n console.error(error instanceof Error ? error.message : error);\n process.exit(1);\n});\n"],"mappings":"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","names":["fs","path","path","fs","current"]}
|
package/dist/index.js
CHANGED
|
@@ -14,24 +14,12 @@ import {
|
|
|
14
14
|
createBillingPaymentFinishedRouteHandler,
|
|
15
15
|
createBillingPaymentSuccessResponse,
|
|
16
16
|
createBillingPaymentSuccessRouteHandler
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-5ISF7ZAG.js";
|
|
18
18
|
import {
|
|
19
19
|
createCasdoorApiProxyHandler,
|
|
20
20
|
createCasdoorCommerceProxyHandler,
|
|
21
21
|
createCasdoorPageProxyHandler
|
|
22
|
-
} from "./chunk-
|
|
23
|
-
import {
|
|
24
|
-
buildBillingActionPayload,
|
|
25
|
-
deriveBillingCreditsState,
|
|
26
|
-
deriveBillingEntitlements,
|
|
27
|
-
normalizeBillingCatalogConfig,
|
|
28
|
-
normalizeBillingPurchaseStatus,
|
|
29
|
-
normalizeBillingRuntimeConfig,
|
|
30
|
-
resolveBillingInterval,
|
|
31
|
-
resolveBillingItem,
|
|
32
|
-
resolveBillingProductSnapshot,
|
|
33
|
-
resolveBillingSubscriptionProduct
|
|
34
|
-
} from "./chunk-O3FKI5NT.js";
|
|
22
|
+
} from "./chunk-5W4H2IMT.js";
|
|
35
23
|
import {
|
|
36
24
|
createAuthorizeRouteHandler,
|
|
37
25
|
createLoginRouteHandler,
|
|
@@ -39,7 +27,7 @@ import {
|
|
|
39
27
|
createNextAuthOptions,
|
|
40
28
|
createNextAuthRouteHandler,
|
|
41
29
|
createSignupRouteHandler
|
|
42
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-QYGC4WNG.js";
|
|
43
31
|
import {
|
|
44
32
|
AUTH_INDEX_HTML,
|
|
45
33
|
AUTH_REDIRECT_COOKIE_NAME,
|
|
@@ -77,7 +65,19 @@ import {
|
|
|
77
65
|
setPublicOriginCookie,
|
|
78
66
|
verifyState,
|
|
79
67
|
verifyStateToken
|
|
80
|
-
} from "./chunk-
|
|
68
|
+
} from "./chunk-MWXY4JSL.js";
|
|
69
|
+
import {
|
|
70
|
+
buildBillingActionPayload,
|
|
71
|
+
deriveBillingCreditsState,
|
|
72
|
+
deriveBillingEntitlements,
|
|
73
|
+
normalizeBillingCatalogConfig,
|
|
74
|
+
normalizeBillingPurchaseStatus,
|
|
75
|
+
normalizeBillingRuntimeConfig,
|
|
76
|
+
resolveBillingInterval,
|
|
77
|
+
resolveBillingItem,
|
|
78
|
+
resolveBillingProductSnapshot,
|
|
79
|
+
resolveBillingSubscriptionProduct
|
|
80
|
+
} from "./chunk-O3FKI5NT.js";
|
|
81
81
|
import {
|
|
82
82
|
buildAuthJumpHref,
|
|
83
83
|
resolvePostLoginRedirect
|
package/dist/next/index.js
CHANGED
|
@@ -5,11 +5,11 @@ import {
|
|
|
5
5
|
createNextAuthOptions,
|
|
6
6
|
createNextAuthRouteHandler,
|
|
7
7
|
createSignupRouteHandler
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-QYGC4WNG.js";
|
|
9
9
|
import {
|
|
10
10
|
createCallbackHandler,
|
|
11
11
|
createCallbackResponse
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-MWXY4JSL.js";
|
|
13
13
|
import "../chunk-T2M5MVPE.js";
|
|
14
14
|
export {
|
|
15
15
|
createAuthorizeRouteHandler,
|
|
@@ -92,6 +92,7 @@ npx @foldspace-fe/casdoor-next-auth-kit@latest check
|
|
|
92
92
|
- `/login/oauth/authorize` — 同源登录授权壳,宿主项目渲染 Casdoor 的登录表单界面
|
|
93
93
|
- `/signup/oauth/authorize` — 同源注册授权壳,宿主项目渲染 Casdoor 的注册表单界面
|
|
94
94
|
- `/callback` — OAuth 回调路由,处理 Casdoor 认证成功后的回调
|
|
95
|
+
- `/callback/error` — 回调错误提示页,默认会提供“清空当前域 Cookie”按钮,帮助用户清理残留认证 cookie 后重新登录
|
|
95
96
|
- `/logout` — 注销路由,清除会话并跳转
|
|
96
97
|
- `/auth/api/*` — Casdoor API 代理,所有个人操作的 API 请求通过此路径转发
|
|
97
98
|
|
|
@@ -404,6 +405,8 @@ Billing 支付成功后,Casdoor 会回跳到宿主站内的两个固定回调
|
|
|
404
405
|
|
|
405
406
|
默认生成的 billing handler 文件必须保持“拿来就能编译”,文件里如果没有业务逻辑,也要保留可运行的空实现和明确日志,不允许生成只写注释或只留导入的半成品。
|
|
406
407
|
|
|
408
|
+
默认生成的 callback error page 也必须保持可编译,并在错误提示外额外提供本地清 cookie 按钮;按钮逻辑必须只在浏览器端执行,不能依赖服务端接口。
|
|
409
|
+
|
|
407
410
|
`app/(auth-kit)/auth-config.ts` 必须显式导出 `authKitConfig`、`adapter`、`persistence`、`paymentSuccessHandler` 和 `paymentFinishedHandler`,route 文件必须能直接从这个文件拿到所需配置和 handler,不要只保留局部变量让 route 间接取值。
|
|
408
411
|
|
|
409
412
|
billing 默认就是受管内容,CLI 必须同时生成 `lib/billing/payment-success.ts` 和 `lib/billing/payment-finished.ts`,`auth-config.ts` 直接导入这两个默认文件,不要要求宿主手工创建 `@/lib/billing/*`。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@foldspace-fe/casdoor-next-auth-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.14",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
],
|
|
49
49
|
"scripts": {
|
|
50
50
|
"build": "tsup && node ./scripts/copy-skill.mjs",
|
|
51
|
+
"test": "pnpm build && node --test --experimental-strip-types ./scripts/verify-casdoor-proxy.mjs",
|
|
51
52
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
52
53
|
"dev": "tsup --watch"
|
|
53
54
|
},
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/billing/payment-route.ts","../src/core/origin.ts","../src/billing/payment-success.ts","../src/billing/payment-finished.ts"],"sourcesContent":["import { NextResponse } from 'next/server';\n\nimport { resolvePublicOrigin } from '../core/origin';\nimport type {\n BillingPaymentSuccessContext,\n BillingPaymentSuccessHandlerResult,\n BillingPaymentSuccessRouteOptions,\n} from './types';\n\nexport interface BillingPaymentRouteOptions extends BillingPaymentSuccessRouteOptions {\n routePath: string;\n missingHandlerFile: string;\n}\n\nfunction sanitizeRedirectPath(value: string | null | undefined, fallback: string): string {\n if (!value || !value.startsWith('/') || value.startsWith('//')) {\n return fallback;\n }\n\n return value;\n}\n\nfunction isDebugEnabled(): boolean {\n const value = process.env.BILLING_PAYMENT_SUCCESS_DEBUG;\n if (!value) {\n return false;\n }\n\n return ['1', 'true', 'yes', 'on'].includes(value.toLowerCase());\n}\n\nasync function readRequestBody(request: Request): Promise<unknown> {\n if (request.method === 'GET' || request.method === 'HEAD') {\n return null;\n }\n\n const rawBody = await request.clone().text();\n if (!rawBody) {\n return null;\n }\n\n const contentType = request.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n try {\n return JSON.parse(rawBody);\n } catch {\n return rawBody;\n }\n }\n\n if (contentType.includes('application/x-www-form-urlencoded')) {\n return Object.fromEntries(new URLSearchParams(rawBody).entries());\n }\n\n return rawBody;\n}\n\nasync function buildContext(request: Request): Promise<BillingPaymentSuccessContext> {\n const url = new URL(request.url);\n const params: Record<string, string> = {};\n\n for (const [key, value] of url.searchParams.entries()) {\n params[key] = value;\n }\n\n return {\n request,\n url,\n searchParams: url.searchParams,\n params,\n paymentId: url.searchParams.get('paymentId'),\n orderId: url.searchParams.get('orderId'),\n redirectTo: url.searchParams.get('redirect') ?? url.searchParams.get('returnTo'),\n body: await readRequestBody(request),\n };\n}\n\nfunction resolveRedirectTarget(\n result: BillingPaymentSuccessHandlerResult | undefined,\n context: BillingPaymentSuccessContext,\n fallbackRedirect: string,\n): string {\n if (typeof result === 'string') {\n return sanitizeRedirectPath(result, fallbackRedirect);\n }\n\n if (result && typeof result === 'object' && 'redirectTo' in result) {\n return sanitizeRedirectPath(result.redirectTo ?? null, fallbackRedirect);\n }\n\n return sanitizeRedirectPath(context.redirectTo, fallbackRedirect);\n}\n\nfunction resolveFallbackTarget(fallbackRedirect: string): string {\n return sanitizeRedirectPath(fallbackRedirect, '/');\n}\n\nfunction logMissingPaymentHandler(\n context: BillingPaymentSuccessContext,\n fallbackRedirect: string,\n missingHandlerFile: string,\n routePath: string,\n): void {\n console.warn(\n `[casdoor-next-auth-kit] default billing handler at ${missingHandlerFile} has no business logic. ` +\n `Edit this file to handle ${routePath} with order/payment enrichment before redirecting. ` +\n `Falling back to ${fallbackRedirect}.`,\n {\n paymentId: context.paymentId,\n orderId: context.orderId,\n params: context.params,\n },\n );\n}\n\nexport async function createBillingPaymentRouteResponse(\n request: Request,\n options: BillingPaymentRouteOptions,\n) {\n const origin = resolvePublicOrigin(request, options.appUrl);\n const fallbackRedirect = options.fallbackRedirect ?? '/';\n const context = await buildContext(request);\n\n if (isDebugEnabled()) {\n console.info(`[casdoor-next-auth-kit] ${options.routePath} request`, {\n method: request.method,\n path: context.url.pathname,\n query: context.params,\n body: context.body,\n });\n }\n\n try {\n if (options.handler) {\n const result = await options.handler(context);\n if (result instanceof Response) {\n return result;\n }\n\n const target = resolveRedirectTarget(result, context, fallbackRedirect);\n return NextResponse.redirect(new URL(target, origin), 307);\n }\n\n logMissingPaymentHandler(context, fallbackRedirect, options.missingHandlerFile, options.routePath);\n const target = resolveFallbackTarget(fallbackRedirect);\n return NextResponse.redirect(new URL(target, origin), 307);\n } catch (error) {\n console.error(`[casdoor-next-auth-kit] ${options.routePath} handler failed:`, error);\n return new NextResponse('Billing payment handler failed', { status: 500 });\n }\n}\n","export function normalizeOrigin(value: string | null | undefined): string | null {\n if (!value) return null;\n try {\n return new URL(value).origin;\n } catch {\n return null;\n }\n}\n\nexport function getRequestOrigin(request: Request, appUrl?: string): string {\n const referer = normalizeOrigin(request.headers.get('referer'));\n if (referer) return referer;\n\n const origin = normalizeOrigin(request.headers.get('origin'));\n if (origin) return origin;\n\n if (appUrl) {\n const normalized = normalizeOrigin(appUrl);\n if (normalized) return normalized;\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 resolvePublicOrigin(request: Request, appUrl?: string): string {\n return getRequestOrigin(request, appUrl);\n}\n","import type { BillingPaymentSuccessHandler, BillingPaymentSuccessRouteOptions } from './types';\nimport { createBillingPaymentRouteResponse } from './payment-route';\n\nexport async function createBillingPaymentSuccessResponse(\n request: Request,\n options: BillingPaymentSuccessRouteOptions = {},\n) {\n return createBillingPaymentRouteResponse(request, {\n ...options,\n routePath: '/auth/payment/success',\n missingHandlerFile: 'lib/billing/payment-success.ts',\n fallbackRedirect: options.fallbackRedirect ?? '/auth/payment/finished',\n });\n}\n\nexport function createBillingPaymentSuccessRouteHandler(options: BillingPaymentSuccessRouteOptions = {}) {\n return async function GET(request: Request) {\n return createBillingPaymentSuccessResponse(request, options);\n };\n}\n\nexport type { BillingPaymentSuccessHandler };\n","import type { BillingPaymentFinishedHandler, BillingPaymentFinishedRouteOptions } from './types';\nimport { createBillingPaymentRouteResponse } from './payment-route';\n\nexport async function createBillingPaymentFinishedResponse(\n request: Request,\n options: BillingPaymentFinishedRouteOptions = {},\n) {\n return createBillingPaymentRouteResponse(request, {\n ...options,\n routePath: '/auth/payment/finished',\n missingHandlerFile: 'lib/billing/payment-finished.ts',\n fallbackRedirect: options.fallbackRedirect ?? '/',\n });\n}\n\nexport function createBillingPaymentFinishedRouteHandler(options: BillingPaymentFinishedRouteOptions = {}) {\n return async function GET(request: Request) {\n return createBillingPaymentFinishedResponse(request, options);\n };\n}\n\nexport type { BillingPaymentFinishedHandler };\n"],"mappings":"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","names":["target"]}
|
|
@@ -1 +0,0 @@
|
|
|
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 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 if (appUrl) {\n try {\n return new URL(appUrl).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('&', '&').replaceAll('\"', '"').replaceAll('<', '<').replaceAll('>', '>');\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 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/casdoor/proxy.ts"],"sourcesContent":["import { NextResponse, type NextRequest } from 'next/server';\nimport type { AuthKitConfig } from '../types';\n\nfunction buildUpstreamUrl(request: NextRequest, baseUrl: string, localPrefix: string, upstreamPrefix: string): string {\n const url = new URL(request.url);\n const upstreamPath = url.pathname.startsWith(localPrefix)\n ? upstreamPrefix + url.pathname.slice(localPrefix.length)\n : url.pathname;\n const rewritten = new URL(upstreamPath, baseUrl);\n rewritten.search = url.search;\n return rewritten.toString();\n}\n\nfunction cleanProxyRequestHeaders(request: NextRequest, baseUrl: string): Headers {\n const headers = new Headers(request.headers);\n // 让 fetch 自动设为上游 host\n headers.delete('host');\n // 删掉浏览器侧 origin/referer,避免把宿主的 http origin 暴露给 Casdoor\n headers.delete('origin');\n headers.delete('referer');\n // 删掉反向代理注入的 forwarded 系列头,避免 Casdoor 看到 http 内网地址\n headers.delete('x-forwarded-host');\n headers.delete('x-forwarded-port');\n headers.delete('x-forwarded-proto');\n headers.delete('forwarded');\n return headers;\n}\n\nasync function proxyRequest(\n request: NextRequest,\n baseUrl: string,\n localPrefix: string,\n upstreamPrefix: string,\n options: { suppressRedirects?: boolean } = {},\n): Promise<NextResponse> {\n const upstreamUrl = buildUpstreamUrl(request, baseUrl, localPrefix, upstreamPrefix);\n const headers = cleanProxyRequestHeaders(request, baseUrl);\n const body = request.method === 'GET' || request.method === 'HEAD' ? undefined : await request.arrayBuffer();\n const upstream = await fetch(upstreamUrl, {\n method: request.method,\n headers,\n body,\n redirect: options.suppressRedirects ? 'manual' : 'follow',\n });\n\n if (options.suppressRedirects && upstream.status >= 300 && upstream.status < 400) {\n return NextResponse.json(\n {\n status: 'error',\n msg: 'Please login first',\n redirect: upstream.headers.get('location') || null,\n },\n { status: 200 },\n );\n }\n\n const responseHeaders = new Headers(upstream.headers);\n responseHeaders.delete('content-encoding');\n responseHeaders.delete('content-length');\n responseHeaders.delete('transfer-encoding');\n responseHeaders.delete('connection');\n return new NextResponse(upstream.body, {\n status: upstream.status,\n headers: responseHeaders,\n });\n}\n\nexport function createCasdoorApiProxyHandler(\n config: AuthKitConfig,\n prefix = '/auth/api',\n upstreamPrefix = '/api',\n): (request: NextRequest) => Promise<NextResponse> {\n return async (request) => proxyRequest(request, config.casdoor.serverUrl, prefix, upstreamPrefix, { suppressRedirects: true });\n}\n\nexport function createCasdoorPageProxyHandler(\n config: AuthKitConfig,\n prefix = '/auth',\n upstreamPrefix = '',\n): (request: NextRequest) => Promise<NextResponse> {\n return async (request) => proxyRequest(request, config.casdoor.serverUrl, prefix, upstreamPrefix);\n}\n\nexport function createCasdoorCommerceProxyHandler(\n config: AuthKitConfig,\n prefix = '/auth/api/commerce',\n upstreamPrefix = '/api/commerce',\n): (request: NextRequest) => Promise<NextResponse> {\n return async (request) => proxyRequest(request, config.casdoor.serverUrl, prefix, upstreamPrefix, { suppressRedirects: true });\n}\n"],"mappings":";AAAA,SAAS,oBAAsC;AAG/C,SAAS,iBAAiB,SAAsB,SAAiB,aAAqB,gBAAgC;AACpH,QAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,QAAM,eAAe,IAAI,SAAS,WAAW,WAAW,IACpD,iBAAiB,IAAI,SAAS,MAAM,YAAY,MAAM,IACtD,IAAI;AACR,QAAM,YAAY,IAAI,IAAI,cAAc,OAAO;AAC/C,YAAU,SAAS,IAAI;AACvB,SAAO,UAAU,SAAS;AAC5B;AAEA,SAAS,yBAAyB,SAAsB,SAA0B;AAChF,QAAM,UAAU,IAAI,QAAQ,QAAQ,OAAO;AAE3C,UAAQ,OAAO,MAAM;AAErB,UAAQ,OAAO,QAAQ;AACvB,UAAQ,OAAO,SAAS;AAExB,UAAQ,OAAO,kBAAkB;AACjC,UAAQ,OAAO,kBAAkB;AACjC,UAAQ,OAAO,mBAAmB;AAClC,UAAQ,OAAO,WAAW;AAC1B,SAAO;AACT;AAEA,eAAe,aACb,SACA,SACA,aACA,gBACA,UAA2C,CAAC,GACrB;AACvB,QAAM,cAAc,iBAAiB,SAAS,SAAS,aAAa,cAAc;AAClF,QAAM,UAAU,yBAAyB,SAAS,OAAO;AACzD,QAAM,OAAO,QAAQ,WAAW,SAAS,QAAQ,WAAW,SAAS,SAAY,MAAM,QAAQ,YAAY;AAC3G,QAAM,WAAW,MAAM,MAAM,aAAa;AAAA,IACxC,QAAQ,QAAQ;AAAA,IAChB;AAAA,IACA;AAAA,IACA,UAAU,QAAQ,oBAAoB,WAAW;AAAA,EACnD,CAAC;AAED,MAAI,QAAQ,qBAAqB,SAAS,UAAU,OAAO,SAAS,SAAS,KAAK;AAChF,WAAO,aAAa;AAAA,MAClB;AAAA,QACE,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,UAAU,SAAS,QAAQ,IAAI,UAAU,KAAK;AAAA,MAChD;AAAA,MACA,EAAE,QAAQ,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,QAAM,kBAAkB,IAAI,QAAQ,SAAS,OAAO;AACpD,kBAAgB,OAAO,kBAAkB;AACzC,kBAAgB,OAAO,gBAAgB;AACvC,kBAAgB,OAAO,mBAAmB;AAC1C,kBAAgB,OAAO,YAAY;AACnC,SAAO,IAAI,aAAa,SAAS,MAAM;AAAA,IACrC,QAAQ,SAAS;AAAA,IACjB,SAAS;AAAA,EACX,CAAC;AACH;AAEO,SAAS,6BACd,QACA,SAAS,aACT,iBAAiB,QACgC;AACjD,SAAO,OAAO,YAAY,aAAa,SAAS,OAAO,QAAQ,WAAW,QAAQ,gBAAgB,EAAE,mBAAmB,KAAK,CAAC;AAC/H;AAEO,SAAS,8BACd,QACA,SAAS,SACT,iBAAiB,IACgC;AACjD,SAAO,OAAO,YAAY,aAAa,SAAS,OAAO,QAAQ,WAAW,QAAQ,cAAc;AAClG;AAEO,SAAS,kCACd,QACA,SAAS,sBACT,iBAAiB,iBACgC;AACjD,SAAO,OAAO,YAAY,aAAa,SAAS,OAAO,QAAQ,WAAW,QAAQ,gBAAgB,EAAE,mBAAmB,KAAK,CAAC;AAC/H;","names":[]}
|
|
File without changes
|