@foldspace-fe/casdoor-next-auth-kit 0.1.6 → 0.1.8

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/README.md CHANGED
@@ -63,7 +63,6 @@ import { BillingProvider } from '@foldspace-fe/casdoor-next-auth-kit/react';
63
63
  import {
64
64
  useSubscribePlan,
65
65
  usePurchaseProduct,
66
- usePurchaseCredits,
67
66
  } from '@foldspace-fe/casdoor-next-auth-kit/react';
68
67
  ```
69
68
 
@@ -1,5 +1,5 @@
1
- import { B as BillingActionPayload, b as BillingRuntimeConfig, m as BillingCreditsState, j as BillingProductState, h as BillingSubscriptionState, n as BillingEntitlementState, c as BillingCatalogConfig, p as BillingPurchaseStatus, k as BillingOrderHistoryItem, l as BillingPaymentHistoryItem, v as BillingInterval, a as BillingItem, q as BillingProductSnapshot } from '../types-BPsPs5Rv.js';
2
- export { f as BillingActionExecutor, s as BillingActionKind, d as BillingApiClient, t as BillingConversionRule, r as BillingCoreContextValue, u as BillingCreditsContextValue, g as BillingDefaults, w as BillingItemKind, e as BillingLoaders, x as BillingProductContextValue, y as BillingProductPurchaseConfig, o as BillingStatusState, z as BillingSubscriptionContextValue, i as BillingSubscriptionHistoryItem, A as BillingSubscriptionPurchaseConfig } from '../types-BPsPs5Rv.js';
1
+ import { B as BillingActionPayload, b as BillingRuntimeConfig, m as BillingCreditsState, j as BillingProductState, h as BillingSubscriptionState, n as BillingEntitlementState, c as BillingCatalogConfig, p as BillingPurchaseStatus, k as BillingOrderHistoryItem, l as BillingPaymentHistoryItem, v as BillingInterval, a as BillingItem, q as BillingProductSnapshot, D as BillingPaymentSuccessRouteOptions, y as BillingPaymentFinishedRouteOptions } from '../types-DwThfdu-.js';
2
+ export { f as BillingActionExecutor, s as BillingActionKind, d as BillingApiClient, t as BillingConversionRule, r as BillingCoreContextValue, u as BillingCreditsContextValue, g as BillingDefaults, w as BillingItemKind, e as BillingLoaders, x as BillingPaymentFinishedHandler, z as BillingPaymentSuccessContext, A as BillingPaymentSuccessHandler, C as BillingPaymentSuccessHandlerResult, E as BillingProductContextValue, F as BillingProductPurchaseConfig, o as BillingStatusState, G as BillingSubscriptionContextValue, i as BillingSubscriptionHistoryItem, H as BillingSubscriptionPurchaseConfig } from '../types-DwThfdu-.js';
3
3
 
4
4
  declare function normalizeBillingRuntimeConfig(config?: Partial<BillingRuntimeConfig> | null): BillingRuntimeConfig;
5
5
  declare function normalizeBillingCatalogConfig(config?: Partial<BillingCatalogConfig> | null): BillingCatalogConfig;
@@ -9,8 +9,13 @@ declare function resolveBillingProductSnapshot(item?: BillingItem | null): Billi
9
9
  declare function deriveBillingCreditsState(credits?: BillingCreditsState | null, products?: BillingProductState[] | null, conversionRules?: BillingRuntimeConfig['conversionRules']): BillingCreditsState;
10
10
  declare function deriveBillingEntitlements(subscription: BillingSubscriptionState | undefined, products: BillingProductState[] | undefined, credits: BillingCreditsState | undefined, runtimeConfig: BillingRuntimeConfig | undefined): BillingEntitlementState;
11
11
  declare function normalizeBillingPurchaseStatus(status?: Partial<BillingPurchaseStatus> | null, order?: BillingOrderHistoryItem | null, payment?: BillingPaymentHistoryItem | null): BillingPurchaseStatus;
12
- declare function filterProductsByKind(products: BillingProductState[] | undefined, kind?: 'product' | 'credits'): BillingProductState[];
13
12
  declare function resolveBillingInterval(interval?: BillingInterval | null): BillingInterval | undefined;
14
13
  declare function buildBillingActionPayload(payload: BillingActionPayload, runtimeConfig?: BillingRuntimeConfig | null): BillingActionPayload;
15
14
 
16
- export { BillingActionPayload, BillingCatalogConfig, BillingCreditsState, BillingEntitlementState, BillingInterval, BillingItem, BillingOrderHistoryItem, BillingPaymentHistoryItem, BillingProductSnapshot, BillingProductState, BillingPurchaseStatus, BillingRuntimeConfig, BillingSubscriptionState, buildBillingActionPayload, deriveBillingCreditsState, deriveBillingEntitlements, filterProductsByKind, normalizeBillingCatalogConfig, normalizeBillingPurchaseStatus, normalizeBillingRuntimeConfig, resolveBillingInterval, resolveBillingItem, resolveBillingProductSnapshot, resolveBillingSubscriptionProduct };
15
+ declare function createBillingPaymentSuccessResponse(request: Request, options?: BillingPaymentSuccessRouteOptions): Promise<Response>;
16
+ declare function createBillingPaymentSuccessRouteHandler(options?: BillingPaymentSuccessRouteOptions): (request: Request) => Promise<Response>;
17
+
18
+ declare function createBillingPaymentFinishedResponse(request: Request, options?: BillingPaymentFinishedRouteOptions): Promise<Response>;
19
+ declare function createBillingPaymentFinishedRouteHandler(options?: BillingPaymentFinishedRouteOptions): (request: Request) => Promise<Response>;
20
+
21
+ export { BillingActionPayload, BillingCatalogConfig, BillingCreditsState, BillingEntitlementState, BillingInterval, BillingItem, BillingOrderHistoryItem, BillingPaymentFinishedRouteOptions, BillingPaymentHistoryItem, BillingPaymentSuccessRouteOptions, BillingProductSnapshot, BillingProductState, BillingPurchaseStatus, BillingRuntimeConfig, BillingSubscriptionState, buildBillingActionPayload, createBillingPaymentFinishedResponse, createBillingPaymentFinishedRouteHandler, createBillingPaymentSuccessResponse, createBillingPaymentSuccessRouteHandler, deriveBillingCreditsState, deriveBillingEntitlements, normalizeBillingCatalogConfig, normalizeBillingPurchaseStatus, normalizeBillingRuntimeConfig, resolveBillingInterval, resolveBillingItem, resolveBillingProductSnapshot, resolveBillingSubscriptionProduct };
@@ -1,9 +1,13 @@
1
- import "../chunk-XMBHIEYL.js";
1
+ import {
2
+ createBillingPaymentFinishedResponse,
3
+ createBillingPaymentFinishedRouteHandler,
4
+ createBillingPaymentSuccessResponse,
5
+ createBillingPaymentSuccessRouteHandler
6
+ } from "../chunk-NGKCQHB3.js";
2
7
  import {
3
8
  buildBillingActionPayload,
4
9
  deriveBillingCreditsState,
5
10
  deriveBillingEntitlements,
6
- filterProductsByKind,
7
11
  normalizeBillingCatalogConfig,
8
12
  normalizeBillingPurchaseStatus,
9
13
  normalizeBillingRuntimeConfig,
@@ -11,12 +15,15 @@ import {
11
15
  resolveBillingItem,
12
16
  resolveBillingProductSnapshot,
13
17
  resolveBillingSubscriptionProduct
14
- } from "../chunk-RGTVPBH7.js";
18
+ } from "../chunk-O3FKI5NT.js";
15
19
  export {
16
20
  buildBillingActionPayload,
21
+ createBillingPaymentFinishedResponse,
22
+ createBillingPaymentFinishedRouteHandler,
23
+ createBillingPaymentSuccessResponse,
24
+ createBillingPaymentSuccessRouteHandler,
17
25
  deriveBillingCreditsState,
18
26
  deriveBillingEntitlements,
19
- filterProductsByKind,
20
27
  normalizeBillingCatalogConfig,
21
28
  normalizeBillingPurchaseStatus,
22
29
  normalizeBillingRuntimeConfig,
@@ -2,7 +2,7 @@ import {
2
2
  createCasdoorApiProxyHandler,
3
3
  createCasdoorCommerceProxyHandler,
4
4
  createCasdoorPageProxyHandler
5
- } from "../chunk-DONQHN4U.js";
5
+ } from "../chunk-YXTDGBLC.js";
6
6
  import {
7
7
  createAuthorizeEntryResponse,
8
8
  createCallbackHandler,
@@ -0,0 +1,173 @@
1
+ // src/billing/payment-route.ts
2
+ import { NextResponse } from "next/server";
3
+
4
+ // src/core/origin.ts
5
+ function normalizeOrigin(value) {
6
+ if (!value) return null;
7
+ try {
8
+ return new URL(value).origin;
9
+ } catch {
10
+ return null;
11
+ }
12
+ }
13
+ function getRequestOrigin(request, appUrl) {
14
+ const referer = normalizeOrigin(request.headers.get("referer"));
15
+ if (referer) return referer;
16
+ const origin = normalizeOrigin(request.headers.get("origin"));
17
+ if (origin) return origin;
18
+ if (appUrl) {
19
+ const normalized = normalizeOrigin(appUrl);
20
+ if (normalized) return normalized;
21
+ }
22
+ const forwardedProto = request.headers.get("x-forwarded-proto")?.split(",")[0]?.trim();
23
+ const forwardedHost = request.headers.get("x-forwarded-host")?.split(",")[0]?.trim();
24
+ if (forwardedProto && forwardedHost) {
25
+ return forwardedProto + "://" + forwardedHost;
26
+ }
27
+ return new URL(request.url).origin;
28
+ }
29
+ function resolvePublicOrigin(request, appUrl) {
30
+ return getRequestOrigin(request, appUrl);
31
+ }
32
+
33
+ // src/billing/payment-route.ts
34
+ function sanitizeRedirectPath(value, fallback) {
35
+ if (!value || !value.startsWith("/") || value.startsWith("//")) {
36
+ return fallback;
37
+ }
38
+ return value;
39
+ }
40
+ function isDebugEnabled() {
41
+ const value = process.env.BILLING_PAYMENT_SUCCESS_DEBUG;
42
+ if (!value) {
43
+ return false;
44
+ }
45
+ return ["1", "true", "yes", "on"].includes(value.toLowerCase());
46
+ }
47
+ async function readRequestBody(request) {
48
+ if (request.method === "GET" || request.method === "HEAD") {
49
+ return null;
50
+ }
51
+ const rawBody = await request.clone().text();
52
+ if (!rawBody) {
53
+ return null;
54
+ }
55
+ const contentType = request.headers.get("content-type") ?? "";
56
+ if (contentType.includes("application/json")) {
57
+ try {
58
+ return JSON.parse(rawBody);
59
+ } catch {
60
+ return rawBody;
61
+ }
62
+ }
63
+ if (contentType.includes("application/x-www-form-urlencoded")) {
64
+ return Object.fromEntries(new URLSearchParams(rawBody).entries());
65
+ }
66
+ return rawBody;
67
+ }
68
+ async function buildContext(request) {
69
+ const url = new URL(request.url);
70
+ const params = {};
71
+ for (const [key, value] of url.searchParams.entries()) {
72
+ params[key] = value;
73
+ }
74
+ return {
75
+ request,
76
+ url,
77
+ searchParams: url.searchParams,
78
+ params,
79
+ paymentId: url.searchParams.get("paymentId"),
80
+ orderId: url.searchParams.get("orderId"),
81
+ redirectTo: url.searchParams.get("redirect") ?? url.searchParams.get("returnTo"),
82
+ body: await readRequestBody(request)
83
+ };
84
+ }
85
+ function resolveRedirectTarget(result, context, fallbackRedirect) {
86
+ if (typeof result === "string") {
87
+ return sanitizeRedirectPath(result, fallbackRedirect);
88
+ }
89
+ if (result && typeof result === "object" && "redirectTo" in result) {
90
+ return sanitizeRedirectPath(result.redirectTo ?? null, fallbackRedirect);
91
+ }
92
+ return sanitizeRedirectPath(context.redirectTo, fallbackRedirect);
93
+ }
94
+ function resolveFallbackTarget(fallbackRedirect) {
95
+ return sanitizeRedirectPath(fallbackRedirect, "/");
96
+ }
97
+ function logMissingPaymentHandler(context, fallbackRedirect, missingHandlerName, routePath) {
98
+ console.warn(
99
+ `[casdoor-next-auth-kit] ${missingHandlerName} is not configured. Set it in .env to handle ${routePath} with order/payment enrichment before redirecting. Falling back to ${fallbackRedirect}.`,
100
+ {
101
+ paymentId: context.paymentId,
102
+ orderId: context.orderId,
103
+ params: context.params
104
+ }
105
+ );
106
+ }
107
+ async function createBillingPaymentRouteResponse(request, options) {
108
+ const origin = resolvePublicOrigin(request, options.appUrl);
109
+ const fallbackRedirect = options.fallbackRedirect ?? "/";
110
+ const context = await buildContext(request);
111
+ if (isDebugEnabled()) {
112
+ console.info(`[casdoor-next-auth-kit] ${options.routePath} request`, {
113
+ method: request.method,
114
+ path: context.url.pathname,
115
+ query: context.params,
116
+ body: context.body
117
+ });
118
+ }
119
+ try {
120
+ if (options.handler) {
121
+ const result = await options.handler(context);
122
+ if (result instanceof Response) {
123
+ return result;
124
+ }
125
+ const target2 = resolveRedirectTarget(result, context, fallbackRedirect);
126
+ return NextResponse.redirect(new URL(target2, origin), 307);
127
+ }
128
+ logMissingPaymentHandler(context, fallbackRedirect, options.missingHandlerName, options.routePath);
129
+ const target = resolveFallbackTarget(fallbackRedirect);
130
+ return NextResponse.redirect(new URL(target, origin), 307);
131
+ } catch (error) {
132
+ console.error(`[casdoor-next-auth-kit] ${options.routePath} handler failed:`, error);
133
+ return new NextResponse("Billing payment handler failed", { status: 500 });
134
+ }
135
+ }
136
+
137
+ // src/billing/payment-success.ts
138
+ async function createBillingPaymentSuccessResponse(request, options = {}) {
139
+ return createBillingPaymentRouteResponse(request, {
140
+ ...options,
141
+ routePath: "/auth/payment/success",
142
+ missingHandlerName: "BILLING_PAYMENT_SUCCESS_HANDLER",
143
+ fallbackRedirect: options.fallbackRedirect ?? "/auth/payment/finished"
144
+ });
145
+ }
146
+ function createBillingPaymentSuccessRouteHandler(options = {}) {
147
+ return async function GET(request) {
148
+ return createBillingPaymentSuccessResponse(request, options);
149
+ };
150
+ }
151
+
152
+ // src/billing/payment-finished.ts
153
+ async function createBillingPaymentFinishedResponse(request, options = {}) {
154
+ return createBillingPaymentRouteResponse(request, {
155
+ ...options,
156
+ routePath: "/auth/payment/finished",
157
+ missingHandlerName: "BILLING_PAYMENT_FINISHED_HANDLER",
158
+ fallbackRedirect: options.fallbackRedirect ?? "/"
159
+ });
160
+ }
161
+ function createBillingPaymentFinishedRouteHandler(options = {}) {
162
+ return async function GET(request) {
163
+ return createBillingPaymentFinishedResponse(request, options);
164
+ };
165
+ }
166
+
167
+ export {
168
+ createBillingPaymentSuccessResponse,
169
+ createBillingPaymentSuccessRouteHandler,
170
+ createBillingPaymentFinishedResponse,
171
+ createBillingPaymentFinishedRouteHandler
172
+ };
173
+ //# sourceMappingURL=chunk-NGKCQHB3.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 missingHandlerName: 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 missingHandlerName: string,\n routePath: string,\n): void {\n console.warn(\n `[casdoor-next-auth-kit] ${missingHandlerName} is not configured. ` +\n `Set it in .env 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.missingHandlerName, 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 missingHandlerName: 'BILLING_PAYMENT_SUCCESS_HANDLER',\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 missingHandlerName: 'BILLING_PAYMENT_FINISHED_HANDLER',\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"]}
@@ -34,6 +34,8 @@ function resolveBillingSubscriptionProduct(subscription, runtimeConfig) {
34
34
  planId: item.backendRef.planId,
35
35
  priceId: item.backendRef.priceId,
36
36
  interval: item.interval,
37
+ creditGrant: item.creditGrant,
38
+ creditRedeem: item.creditRedeem,
37
39
  metadata: item.metadata
38
40
  };
39
41
  }
@@ -47,14 +49,22 @@ function resolveBillingProductSnapshot(item) {
47
49
  planId: item.backendRef.planId,
48
50
  priceId: item.backendRef.priceId,
49
51
  interval: item.interval,
52
+ creditGrant: item.creditGrant,
53
+ creditRedeem: item.creditRedeem,
50
54
  metadata: item.metadata
51
55
  };
52
56
  }
53
57
  function deriveBillingCreditsState(credits, products, conversionRules) {
54
58
  if (credits) return credits;
55
59
  const fromProducts = products?.reduce((total, product) => {
56
- if (product.kind !== "credits") return total;
57
- return total + Number(product.creditsBalance ?? product.quantity ?? 0);
60
+ if (typeof product.creditsBalance === "number") {
61
+ return total + Number(product.creditsBalance);
62
+ }
63
+ if (!product.creditGrant) {
64
+ return total;
65
+ }
66
+ const quantity = Number(product.quantity ?? 1);
67
+ return total + Number(product.creditGrant.creditsPerUnit || 0) * quantity;
58
68
  }, 0);
59
69
  const fromRules = conversionRules?.reduce((total, rule) => {
60
70
  if (rule.kind !== "grant-credits") return total;
@@ -125,10 +135,6 @@ function normalizeBillingPurchaseStatus(status, order, payment) {
125
135
  updatedAt: payment?.updatedAt ?? order?.updatedAt
126
136
  };
127
137
  }
128
- function filterProductsByKind(products, kind) {
129
- if (!kind) return products ?? [];
130
- return (products ?? []).filter((product) => product.kind === kind);
131
- }
132
138
  function resolveBillingInterval(interval) {
133
139
  return interval === "month" || interval === "year" ? interval : void 0;
134
140
  }
@@ -175,8 +181,7 @@ export {
175
181
  deriveBillingCreditsState,
176
182
  deriveBillingEntitlements,
177
183
  normalizeBillingPurchaseStatus,
178
- filterProductsByKind,
179
184
  resolveBillingInterval,
180
185
  buildBillingActionPayload
181
186
  };
182
- //# sourceMappingURL=chunk-RGTVPBH7.js.map
187
+ //# sourceMappingURL=chunk-O3FKI5NT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/billing/runtime.ts"],"sourcesContent":["import type {\n BillingActionPayload,\n BillingCatalogConfig,\n BillingCreditsState,\n BillingEntitlementState,\n BillingInterval,\n BillingItem,\n BillingOrderHistoryItem,\n BillingPaymentHistoryItem,\n BillingProductSnapshot,\n BillingProductState,\n BillingPurchaseStatus,\n BillingRuntimeConfig,\n BillingSubscriptionHistoryItem,\n BillingSubscriptionState,\n} from './types';\n\nexport function normalizeBillingRuntimeConfig(config?: Partial<BillingRuntimeConfig> | null): BillingRuntimeConfig {\n return {\n catalogKey: config?.catalogKey ?? 'default',\n items: config?.items ?? [],\n conversionRules: config?.conversionRules ?? [],\n defaults: config?.defaults ?? {},\n };\n}\n\nexport function normalizeBillingCatalogConfig(config?: Partial<BillingCatalogConfig> | null): BillingCatalogConfig {\n return {\n ...normalizeBillingRuntimeConfig(config),\n title: config?.title,\n description: config?.description,\n portalPath: config?.portalPath,\n successPath: config?.successPath,\n cancelPath: config?.cancelPath,\n };\n}\n\nexport function resolveBillingItem(items: BillingItem[] | undefined, key?: string | null): BillingItem | undefined {\n if (!key) return undefined;\n return items?.find((item) => item.key === key || item.backendRef.productId === key || item.backendRef.planId === key);\n}\n\nexport function resolveBillingSubscriptionProduct(\n subscription: BillingSubscriptionState | undefined,\n runtimeConfig: BillingRuntimeConfig | undefined,\n): BillingProductSnapshot | undefined {\n if (!subscription) return undefined;\n if (subscription.product) return subscription.product;\n\n const item = resolveBillingItem(runtimeConfig?.items, subscription.planKey ?? subscription.subscriptionId);\n if (!item) return undefined;\n\n return {\n productKey: item.key,\n productId: item.backendRef.productId,\n title: item.title,\n kind: item.kind,\n planId: item.backendRef.planId,\n priceId: item.backendRef.priceId,\n interval: item.interval,\n creditGrant: item.creditGrant,\n creditRedeem: item.creditRedeem,\n metadata: item.metadata,\n };\n}\n\nexport function resolveBillingProductSnapshot(item?: BillingItem | null): BillingProductSnapshot | undefined {\n if (!item) return undefined;\n return {\n productKey: item.key,\n productId: item.backendRef.productId,\n title: item.title,\n kind: item.kind,\n planId: item.backendRef.planId,\n priceId: item.backendRef.priceId,\n interval: item.interval,\n creditGrant: item.creditGrant,\n creditRedeem: item.creditRedeem,\n metadata: item.metadata,\n };\n}\n\nexport function deriveBillingCreditsState(\n credits?: BillingCreditsState | null,\n products?: BillingProductState[] | null,\n conversionRules?: BillingRuntimeConfig['conversionRules'],\n): BillingCreditsState {\n if (credits) return credits;\n\n const fromProducts = products?.reduce((total, product) => {\n if (typeof product.creditsBalance === 'number') {\n return total + Number(product.creditsBalance);\n }\n\n if (!product.creditGrant) {\n return total;\n }\n\n const quantity = Number(product.quantity ?? 1);\n return total + Number(product.creditGrant.creditsPerUnit || 0) * quantity;\n }, 0);\n\n const fromRules = conversionRules?.reduce((total, rule) => {\n if (rule.kind !== 'grant-credits') return total;\n return total + Number(rule.creditsPerUnit || 0);\n }, 0);\n\n return {\n balance: Number(fromProducts ?? fromRules ?? 0),\n };\n}\n\nexport function deriveBillingEntitlements(\n subscription: BillingSubscriptionState | undefined,\n products: BillingProductState[] | undefined,\n credits: BillingCreditsState | undefined,\n runtimeConfig: BillingRuntimeConfig | undefined,\n): BillingEntitlementState {\n const features = new Set<string>();\n const limits: Record<string, number> = {};\n const flags: Record<string, boolean> = {};\n const creditBalance = credits?.balance ?? 0;\n\n for (const item of runtimeConfig?.items ?? []) {\n for (const feature of item.features ?? []) {\n features.add(feature);\n }\n if (item.metadata?.tier) {\n flags[item.metadata.tier] = true;\n }\n }\n\n if (subscription?.status === 'active' || subscription?.status === 'trialing') {\n flags.subscribed = true;\n }\n\n if (creditBalance > 0) {\n flags.hasCredits = true;\n limits.credits = creditBalance;\n }\n\n for (const product of products ?? []) {\n if (product.owned) {\n flags[`product:${product.productKey}`] = true;\n }\n }\n\n return {\n features: [...features],\n limits,\n flags,\n };\n}\n\nexport function normalizeBillingPurchaseStatus(\n status?: Partial<BillingPurchaseStatus> | null,\n order?: BillingOrderHistoryItem | null,\n payment?: BillingPaymentHistoryItem | null,\n): BillingPurchaseStatus {\n if (status) {\n return {\n actionKey: status.actionKey,\n orderId: status.orderId,\n paymentId: status.paymentId,\n transactionId: status.transactionId,\n status: status.status ?? 'idle',\n orderStatus: status.orderStatus,\n paymentStatus: status.paymentStatus,\n transactionStatus: status.transactionStatus,\n redirectTo: status.redirectTo,\n updatedAt: status.updatedAt,\n };\n }\n\n const orderStatus = order?.status;\n const paymentStatus = payment?.status;\n const normalizedStatus =\n paymentStatus === 'paid' || orderStatus === 'paid'\n ? 'paid'\n : paymentStatus === 'pending' || orderStatus === 'pending'\n ? 'pending'\n : paymentStatus === 'failed' || orderStatus === 'failed'\n ? 'failed'\n : paymentStatus === 'canceled' || orderStatus === 'canceled'\n ? 'canceled'\n : paymentStatus === 'refunded' || orderStatus === 'refunded'\n ? 'refunded'\n : paymentStatus === 'pending'\n ? 'requires_payment'\n : 'idle';\n\n return {\n actionKey: order?.orderId ?? payment?.paymentId,\n orderId: order?.orderId,\n paymentId: payment?.paymentId,\n transactionId: payment?.transactionId ?? order?.transactionId,\n status: normalizedStatus,\n orderStatus,\n paymentStatus,\n transactionStatus: payment?.transactionId ? 'linked' : undefined,\n updatedAt: payment?.updatedAt ?? order?.updatedAt,\n };\n}\n\nexport function resolveBillingInterval(interval?: BillingInterval | null): BillingInterval | undefined {\n return interval === 'month' || interval === 'year' ? interval : undefined;\n}\n\nexport function buildBillingActionPayload(\n payload: BillingActionPayload,\n runtimeConfig?: BillingRuntimeConfig | null,\n): BillingActionPayload {\n const config = normalizeBillingRuntimeConfig(runtimeConfig);\n const item = resolveBillingItem(config.items, payload.key) ?? resolveBillingItem(config.items, payload.productId);\n\n if (payload.kind === 'subscribe' && item) {\n return {\n ...payload,\n subscriptionConfig: payload.subscriptionConfig ?? {\n productKey: item.key,\n productId: item.backendRef.productId,\n planId: item.backendRef.planId,\n priceId: item.backendRef.priceId,\n interval: item.interval ?? config.defaults?.defaultInterval,\n quantity: payload.quantity ?? config.defaults?.defaultQuantity,\n metadata: item.metadata,\n },\n };\n }\n\n if ((payload.kind === 'purchase' || payload.kind === 'manage' || payload.kind === 'upgrade' || payload.kind === 'cancel') && item) {\n return {\n ...payload,\n productConfig: payload.productConfig ?? {\n productKey: item.key,\n productId: item.backendRef.productId,\n priceId: item.backendRef.priceId,\n quantity: payload.quantity ?? config.defaults?.defaultQuantity,\n creditGrant: item.creditGrant,\n creditRedeem: item.creditRedeem,\n metadata: item.metadata,\n },\n };\n }\n\n return payload;\n}\n"],"mappings":"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","names":[]}
@@ -91,6 +91,27 @@ var AUTH_KIT_ENV_VARIABLES = [
91
91
  example: "your-casdoor-client-secret",
92
92
  local: "your-casdoor-client-secret",
93
93
  production: "your-casdoor-client-secret"
94
+ },
95
+ {
96
+ key: "BILLING_PAYMENT_SUCCESS_HANDLER",
97
+ description: "\u652F\u4ED8\u6210\u529F\u56DE\u8DF3\u5904\u7406\u5668\u6A21\u5757\u8DEF\u5F84",
98
+ example: "@/lib/billing/payment-success",
99
+ local: "@/lib/billing/payment-success",
100
+ production: "@/lib/billing/payment-success"
101
+ },
102
+ {
103
+ key: "BILLING_PAYMENT_FINISHED_HANDLER",
104
+ description: "\u652F\u4ED8\u5B8C\u6210\u56DE\u8C03\u5904\u7406\u5668\u6A21\u5757\u8DEF\u5F84",
105
+ example: "@/lib/billing/payment-finished",
106
+ local: "@/lib/billing/payment-finished",
107
+ production: "@/lib/billing/payment-finished"
108
+ },
109
+ {
110
+ key: "BILLING_PAYMENT_SUCCESS_DEBUG",
111
+ description: "\u662F\u5426\u6253\u5370 payment-success \u8C03\u8BD5\u65E5\u5FD7",
112
+ example: "false",
113
+ local: "false",
114
+ production: "false"
94
115
  }
95
116
  ];
96
117
  function stringifyEnvValue(value) {
@@ -127,6 +148,25 @@ function parseEnvKeys(content) {
127
148
  }
128
149
  return keys;
129
150
  }
151
+ function readManagedEnvValue(content, key) {
152
+ for (const line of content.split(/\r?\n/)) {
153
+ const trimmed = line.trim();
154
+ if (!trimmed || trimmed.startsWith("#")) {
155
+ continue;
156
+ }
157
+ const separatorIndex = trimmed.indexOf("=");
158
+ if (separatorIndex === -1) {
159
+ continue;
160
+ }
161
+ const currentKey = trimmed.slice(0, separatorIndex).trim();
162
+ if (currentKey !== key) {
163
+ continue;
164
+ }
165
+ const rawValue = trimmed.slice(separatorIndex + 1).trim();
166
+ return stripQuotes(rawValue);
167
+ }
168
+ return null;
169
+ }
130
170
  function getManagedEnvValue(definition, file) {
131
171
  if (file === ".env.example") {
132
172
  return definition.example;
@@ -281,6 +321,7 @@ function buildAuthPrismaSchemaTemplate(models = AUTH_PRISMA_SCHEMA_MODELS) {
281
321
  export {
282
322
  AUTH_KIT_ENV_FILES,
283
323
  AUTH_KIT_ENV_VARIABLES,
324
+ readManagedEnvValue,
284
325
  getManagedEnvValue,
285
326
  buildManagedEnvTemplate,
286
327
  getMissingManagedEnvKeys,
@@ -288,4 +329,4 @@ export {
288
329
  AUTH_PRISMA_SCHEMA_MODELS,
289
330
  buildAuthPrismaSchemaTemplate
290
331
  };
291
- //# sourceMappingURL=chunk-6E27SZ7V.js.map
332
+ //# sourceMappingURL=chunk-PFHMT4ZD.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/env.ts","../src/prisma/schema-template.ts"],"sourcesContent":["import type { ManagedEnvFile, ManagedEnvVariableDefinition } from '../types';\n\nexport const AUTH_KIT_ENV_FILES: ManagedEnvFile[] = ['.env', '.env.local', '.env.production', '.env.example'];\n\nexport const AUTH_KIT_ENV_VARIABLES: ManagedEnvVariableDefinition[] = [\n {\n key: 'APP_URL',\n description: '站点对外公开地址',\n example: 'https://your-domain.com',\n local: 'http://localhost:5177',\n production: 'https://your-domain.com',\n },\n {\n key: 'NEXTAUTH_URL',\n description: 'NextAuth 回调地址',\n example: 'http://localhost:5177',\n local: 'http://localhost:5177',\n production: 'https://your-domain.com',\n },\n {\n key: 'NEXTAUTH_SECRET',\n description: 'NextAuth JWT secret',\n example: 'replace-with-a-random-secret',\n local: 'replace-with-a-random-secret',\n production: 'replace-with-a-random-secret',\n },\n {\n key: 'GLOBAL_ADMIN_EMAILS',\n description: '全局管理员邮箱,逗号分隔',\n example: 'admin@example.com',\n local: 'admin@example.com',\n production: 'admin@example.com',\n },\n {\n key: 'AUTH_DEBUG',\n description: '是否开启认证调试日志',\n example: 'false',\n local: 'false',\n production: 'false',\n },\n {\n key: 'NEXT_PUBLIC_CASDOOR_SERVER_URL',\n description: 'Casdoor 服务地址',\n example: 'https://auth.example.com',\n local: 'https://auth.example.com',\n production: 'https://auth.example.com',\n },\n {\n key: 'NEXT_PUBLIC_CASDOOR_CLIENT_ID',\n description: 'Casdoor client id',\n example: 'your-casdoor-client-id',\n local: 'your-casdoor-client-id',\n production: 'your-casdoor-client-id',\n },\n {\n key: 'NEXT_PUBLIC_CASDOOR_APP_NAME',\n description: 'Casdoor app name',\n example: 'your-app-name',\n local: 'your-app-name',\n production: 'your-app-name',\n },\n {\n key: 'NEXT_PUBLIC_CASDOOR_ORGANIZATION_NAME',\n description: 'Casdoor organization name',\n example: 'your-org-name',\n local: 'your-org-name',\n production: 'your-org-name',\n },\n {\n key: 'NEXT_PUBLIC_CASDOOR_REDIRECT_PATH',\n description: 'Casdoor OAuth 回调路径',\n example: '/callback',\n local: '/callback',\n production: '/callback',\n },\n {\n key: 'NEXT_PUBLIC_CASDOOR_SIGNIN_PATH',\n description: 'Casdoor authorize 路径',\n example: '/login/oauth/authorize',\n local: '/login/oauth/authorize',\n production: '/login/oauth/authorize',\n },\n {\n key: 'NEXT_PUBLIC_CASDOOR_STATIC_ORIGIN',\n description: 'Casdoor 静态资源 origin',\n example: 'https://casdoor-static.foldspace.cn',\n local: 'https://casdoor-static.foldspace.cn',\n production: 'https://casdoor-static.foldspace.cn',\n },\n {\n key: 'CASDOOR_CLIENT_SECRET',\n description: 'Casdoor client secret',\n example: 'your-casdoor-client-secret',\n local: 'your-casdoor-client-secret',\n production: 'your-casdoor-client-secret',\n },\n {\n key: 'BILLING_PAYMENT_SUCCESS_HANDLER',\n description: '支付成功回跳处理器模块路径',\n example: '@/lib/billing/payment-success',\n local: '@/lib/billing/payment-success',\n production: '@/lib/billing/payment-success',\n },\n {\n key: 'BILLING_PAYMENT_FINISHED_HANDLER',\n description: '支付完成回调处理器模块路径',\n example: '@/lib/billing/payment-finished',\n local: '@/lib/billing/payment-finished',\n production: '@/lib/billing/payment-finished',\n },\n {\n key: 'BILLING_PAYMENT_SUCCESS_DEBUG',\n description: '是否打印 payment-success 调试日志',\n example: 'false',\n local: 'false',\n production: 'false',\n },\n];\n\nfunction stringifyEnvValue(value: string): string {\n if (value === '') {\n return '\"\"';\n }\n\n if (/^[A-Za-z0-9_./:-]+$/.test(value)) {\n return value;\n }\n\n return JSON.stringify(value);\n}\n\nfunction stripQuotes(value: string): string {\n const trimmed = value.trim();\n if (\n (trimmed.startsWith('\"') && trimmed.endsWith('\"')) ||\n (trimmed.startsWith(\"'\") && trimmed.endsWith(\"'\"))\n ) {\n return trimmed.slice(1, -1);\n }\n\n return trimmed;\n}\n\nfunction parseEnvKeys(content: string): Set<string> {\n const keys = new Set<string>();\n for (const line of content.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) {\n continue;\n }\n\n const separatorIndex = trimmed.indexOf('=');\n if (separatorIndex === -1) {\n continue;\n }\n\n const key = trimmed.slice(0, separatorIndex).trim();\n if (key) {\n keys.add(key);\n }\n }\n return keys;\n}\n\nexport function readManagedEnvValue(content: string, key: string): string | null {\n for (const line of content.split(/\\r?\\n/)) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) {\n continue;\n }\n\n const separatorIndex = trimmed.indexOf('=');\n if (separatorIndex === -1) {\n continue;\n }\n\n const currentKey = trimmed.slice(0, separatorIndex).trim();\n if (currentKey !== key) {\n continue;\n }\n\n const rawValue = trimmed.slice(separatorIndex + 1).trim();\n return stripQuotes(rawValue);\n }\n\n return null;\n}\n\nexport function getManagedEnvValue(definition: ManagedEnvVariableDefinition, file: ManagedEnvFile): string {\n if (file === '.env.example') {\n return definition.example;\n }\n if (file === '.env.production') {\n return definition.production ?? definition.example;\n }\n if (file === '.env.local') {\n return definition.local ?? definition.example;\n }\n return definition.base ?? definition.local ?? definition.production ?? definition.example;\n}\n\nexport function buildManagedEnvTemplate(file: ManagedEnvFile, existingContent = ''): string {\n const existingKeys = parseEnvKeys(existingContent);\n const lines: string[] = existingContent.trimEnd() ? existingContent.trimEnd().split(/\\r?\\n/) : [];\n const missing = AUTH_KIT_ENV_VARIABLES.filter((definition) => !existingKeys.has(definition.key));\n\n if (missing.length === 0 && existingContent) {\n return existingContent;\n }\n\n if (lines.length > 0) {\n lines.push('');\n }\n\n lines.push(`# Casdoor Next Auth Kit managed values for ${file}`);\n for (const definition of missing) {\n const value = getManagedEnvValue(definition, file);\n lines.push(`# ${definition.description}`);\n lines.push(`${definition.key}=${stringifyEnvValue(value)}`);\n lines.push('');\n }\n\n while (lines.length > 0 && lines[lines.length - 1] === '') {\n lines.pop();\n }\n\n return `${lines.join('\\n')}\\n`;\n}\n\nexport function getMissingManagedEnvKeys(content: string): string[] {\n const existingKeys = parseEnvKeys(content);\n return AUTH_KIT_ENV_VARIABLES.filter((definition) => !existingKeys.has(definition.key)).map(\n (definition) => definition.key,\n );\n}\n\nexport function sanitizeExistingEnvContent(content: string): string {\n return stripQuotes(content);\n}\n","import type { PrismaSchemaFieldDefinition, PrismaSchemaModelDefinition } from '../types';\n\nexport const AUTH_PRISMA_SCHEMA_MODELS: PrismaSchemaModelDefinition[] = [\n {\n name: 'AuthUser',\n description: 'Shared authentication user record',\n fields: [\n { name: 'id', type: 'String', attributes: ['@id', '@default(cuid())'] },\n { name: 'email', type: 'String?', attributes: ['@unique'] },\n { name: 'name', type: 'String?' },\n { name: 'image', type: 'String?' },\n { name: 'isAdmin', type: 'Boolean', attributes: ['@default(false)'] },\n { name: 'tokenBalance', type: 'Int', attributes: ['@default(0)'] },\n { name: 'isVip', type: 'Boolean', attributes: ['@default(false)'] },\n { name: 'createdAt', type: 'DateTime', attributes: ['@default(now())'] },\n { name: 'updatedAt', type: 'DateTime', attributes: ['@updatedAt'] },\n ],\n blockAttributes: ['@@index([email])'],\n },\n {\n name: 'AuthMembership',\n description: 'Subscription membership snapshot',\n fields: [\n { name: 'id', type: 'String', attributes: ['@id', '@default(cuid())'] },\n { name: 'userId', type: 'String', attributes: ['@unique'] },\n { name: 'plan', type: 'String' },\n { name: 'status', type: 'String' },\n { name: 'startsAt', type: 'DateTime?' },\n { name: 'endsAt', type: 'DateTime?' },\n { name: 'createdAt', type: 'DateTime', attributes: ['@default(now())'] },\n { name: 'updatedAt', type: 'DateTime', attributes: ['@updatedAt'] },\n ],\n blockAttributes: ['@@index([userId])'],\n },\n {\n name: 'AuthOrder',\n description: 'Commerce order record',\n fields: [\n { name: 'id', type: 'String', attributes: ['@id', '@default(cuid())'] },\n { name: 'userId', type: 'String' },\n { name: 'kind', type: 'String' },\n { name: 'status', type: 'String' },\n { name: 'amount', type: 'Int' },\n { name: 'currency', type: 'String', attributes: ['@default(\"CNY\")'] },\n { name: 'payload', type: 'Json?' },\n { name: 'createdAt', type: 'DateTime', attributes: ['@default(now())'] },\n { name: 'updatedAt', type: 'DateTime', attributes: ['@updatedAt'] },\n ],\n blockAttributes: ['@@index([userId])'],\n },\n {\n name: 'AuthSubscription',\n description: 'Commerce subscription record',\n fields: [\n { name: 'id', type: 'String', attributes: ['@id', '@default(cuid())'] },\n { name: 'userId', type: 'String' },\n { name: 'productId', type: 'String' },\n { name: 'status', type: 'String' },\n { name: 'interval', type: 'String' },\n { name: 'startsAt', type: 'DateTime?' },\n { name: 'endsAt', type: 'DateTime?' },\n { name: 'createdAt', type: 'DateTime', attributes: ['@default(now())'] },\n { name: 'updatedAt', type: 'DateTime', attributes: ['@updatedAt'] },\n ],\n blockAttributes: ['@@index([userId])', '@@index([productId])'],\n },\n {\n name: 'AuthInvoice',\n description: 'Commerce invoice record',\n fields: [\n { name: 'id', type: 'String', attributes: ['@id', '@default(cuid())'] },\n { name: 'userId', type: 'String' },\n { name: 'orderId', type: 'String?' },\n { name: 'invoiceNo', type: 'String', attributes: ['@unique'] },\n { name: 'status', type: 'String' },\n { name: 'amount', type: 'Int' },\n { name: 'createdAt', type: 'DateTime', attributes: ['@default(now())'] },\n { name: 'updatedAt', type: 'DateTime', attributes: ['@updatedAt'] },\n ],\n blockAttributes: ['@@index([userId])', '@@index([orderId])'],\n },\n];\n\nfunction renderField(field: PrismaSchemaFieldDefinition): string {\n const attributes = field.attributes?.length ? ` ${field.attributes.join(' ')}` : '';\n return ` ${field.name} ${field.type}${attributes}`;\n}\n\nfunction renderModel(model: PrismaSchemaModelDefinition): string {\n const lines = [\n `/// ${model.description}`,\n `model ${model.name} {`,\n ...model.fields.map(renderField),\n ];\n\n if (model.blockAttributes?.length) {\n lines.push(...model.blockAttributes.map((attribute) => ` ${attribute}`));\n }\n\n lines.push('}');\n return lines.join('\\n');\n}\n\nexport function buildAuthPrismaSchemaTemplate(models: PrismaSchemaModelDefinition[] = AUTH_PRISMA_SCHEMA_MODELS): string {\n return [\n '// generated by @foldspace-fe/casdoor-next-auth-kit',\n '// merge these models into the host Prisma schema if you want a dedicated auth module',\n '',\n ...models.map(renderModel),\n ].join('\\n\\n');\n}\n"],"mappings":"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","names":[]}
@@ -7,10 +7,20 @@ function buildUpstreamUrl(request, baseUrl, localPrefix, upstreamPrefix) {
7
7
  rewritten.search = url.search;
8
8
  return rewritten.toString();
9
9
  }
10
- async function proxyRequest(request, baseUrl, localPrefix, upstreamPrefix, options = {}) {
11
- const upstreamUrl = buildUpstreamUrl(request, baseUrl, localPrefix, upstreamPrefix);
10
+ function cleanProxyRequestHeaders(request, baseUrl) {
12
11
  const headers = new Headers(request.headers);
13
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
+ async function proxyRequest(request, baseUrl, localPrefix, upstreamPrefix, options = {}) {
22
+ const upstreamUrl = buildUpstreamUrl(request, baseUrl, localPrefix, upstreamPrefix);
23
+ const headers = cleanProxyRequestHeaders(request, baseUrl);
14
24
  const body = request.method === "GET" || request.method === "HEAD" ? void 0 : await request.arrayBuffer();
15
25
  const upstream = await fetch(upstreamUrl, {
16
26
  method: request.method,
@@ -53,4 +63,4 @@ export {
53
63
  createCasdoorPageProxyHandler,
54
64
  createCasdoorCommerceProxyHandler
55
65
  };
56
- //# sourceMappingURL=chunk-DONQHN4U.js.map
66
+ //# sourceMappingURL=chunk-YXTDGBLC.js.map
@@ -0,0 +1 @@
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":[]}