@foldspace-fe/casdoor-next-auth-kit 0.1.23 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth-role-C35sP1i6.d.ts +40 -0
- package/dist/callback-Da3JC_EN.d.ts +18 -0
- package/dist/casdoor/index.d.ts +3 -8
- package/dist/casdoor/index.js +6 -4
- package/dist/{chunk-GLK4IW22.js → chunk-CSQFNYTS.js} +25 -11
- package/dist/chunk-CSQFNYTS.js.map +1 -0
- package/dist/{chunk-MWXY4JSL.js → chunk-IPJT66SK.js} +19 -11
- package/dist/{chunk-MWXY4JSL.js.map → chunk-IPJT66SK.js.map} +1 -1
- package/dist/chunk-JCQ5P7QZ.js +74 -0
- package/dist/chunk-JCQ5P7QZ.js.map +1 -0
- package/dist/chunk-YHPSOLXM.js +904 -0
- package/dist/chunk-YHPSOLXM.js.map +1 -0
- package/dist/cli-templates-IhA9gjyF.d.ts +31 -0
- package/dist/cli-templates.d.ts +2 -0
- package/dist/cli-templates.js +7 -0
- package/dist/cli-templates.js.map +1 -0
- package/dist/cli.js +52 -557
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +8 -14
- package/dist/index.js +82 -32
- package/dist/next/index.d.ts +3 -3
- package/dist/next/index.js +7 -5
- package/dist/{options-D2YQdRWu.d.ts → options-CpWDszxZ.d.ts} +5 -2
- package/dist/react/index.d.ts +5 -4
- package/dist/react/index.js +4 -18
- package/dist/react/index.js.map +1 -1
- package/dist/skills/casdoor-next-auth-kit/SKILL.md +1 -0
- package/dist/{types-BJv6j3NZ.d.ts → types-COXcI8tx.d.ts} +3 -1
- package/package.json +1 -1
- package/dist/callback-rEWxVGyL.d.ts +0 -12
- package/dist/chunk-GLK4IW22.js.map +0 -1
- package/dist/chunk-SZVWLQQT.js +0 -332
- package/dist/chunk-SZVWLQQT.js.map +0 -1
- package/dist/chunk-T2M5MVPE.js +0 -20
- package/dist/chunk-T2M5MVPE.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,10 +1,33 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
AUTH_KIT_ENV_FILES,
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
apiProxyRouteTemplate,
|
|
5
|
+
authConfigTemplate,
|
|
6
|
+
authIndexHtmlTemplate,
|
|
7
|
+
authLoginRouteTemplate,
|
|
8
|
+
authSignupRouteTemplate,
|
|
9
|
+
authorizeRouteTemplate,
|
|
10
|
+
billingPaymentFinishedHandlerTemplate,
|
|
11
|
+
billingPaymentSuccessHandlerTemplate,
|
|
12
|
+
callbackErrorClearCookiesButtonTemplate,
|
|
13
|
+
callbackErrorPageTemplate,
|
|
14
|
+
callbackRouteTemplate,
|
|
15
|
+
commerceProxyRouteTemplate,
|
|
16
|
+
envTemplate,
|
|
17
|
+
exists,
|
|
18
|
+
getMissingManagedEnvKeys,
|
|
19
|
+
logoutRouteTemplate,
|
|
20
|
+
nextAuthRouteTemplate,
|
|
21
|
+
paymentFinishedRouteTemplate,
|
|
22
|
+
paymentSuccessRouteTemplate,
|
|
23
|
+
preserveCustomBlock,
|
|
24
|
+
prismaSchemaTemplate,
|
|
25
|
+
read,
|
|
26
|
+
removePath,
|
|
27
|
+
signupAuthorizeRouteTemplate,
|
|
28
|
+
writeGeneratedFile,
|
|
29
|
+
writeTextFile
|
|
30
|
+
} from "./chunk-YHPSOLXM.js";
|
|
8
31
|
|
|
9
32
|
// package.json
|
|
10
33
|
var package_default = {
|
|
@@ -78,542 +101,14 @@ var package_default = {
|
|
|
78
101
|
};
|
|
79
102
|
|
|
80
103
|
// src/cli/operations.ts
|
|
81
|
-
import fs2 from "fs";
|
|
82
|
-
import path2 from "path";
|
|
83
|
-
import { fileURLToPath } from "url";
|
|
84
|
-
|
|
85
|
-
// src/cli/fs.ts
|
|
86
104
|
import fs from "fs";
|
|
87
105
|
import path from "path";
|
|
88
|
-
|
|
89
|
-
var customBegin = "// @foldspace-fe/casdoor-next-auth-kit:begin custom";
|
|
90
|
-
var customEnd = "// @foldspace-fe/casdoor-next-auth-kit:end custom";
|
|
91
|
-
function ensureDir(filePath) {
|
|
92
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
93
|
-
}
|
|
94
|
-
function writeGeneratedFile(filePath, content) {
|
|
95
|
-
ensureDir(filePath);
|
|
96
|
-
fs.writeFileSync(filePath, generatedHeader + content, "utf8");
|
|
97
|
-
}
|
|
98
|
-
function writeTextFile(filePath, content) {
|
|
99
|
-
ensureDir(filePath);
|
|
100
|
-
fs.writeFileSync(filePath, content, "utf8");
|
|
101
|
-
}
|
|
102
|
-
function exists(filePath) {
|
|
103
|
-
return fs.existsSync(filePath);
|
|
104
|
-
}
|
|
105
|
-
function read(filePath) {
|
|
106
|
-
return fs.readFileSync(filePath, "utf8");
|
|
107
|
-
}
|
|
108
|
-
function preserveCustomBlock(existing, next) {
|
|
109
|
-
const begin = existing.indexOf(customBegin);
|
|
110
|
-
const end = existing.indexOf(customEnd);
|
|
111
|
-
if (begin === -1 || end === -1 || end <= begin) return next;
|
|
112
|
-
const custom = existing.slice(begin, end + customEnd.length);
|
|
113
|
-
const targetBegin = next.indexOf(customBegin);
|
|
114
|
-
const targetEnd = next.indexOf(customEnd);
|
|
115
|
-
if (targetBegin === -1 || targetEnd === -1 || targetEnd <= targetBegin) return next;
|
|
116
|
-
return next.slice(0, targetBegin) + custom + next.slice(targetEnd + customEnd.length);
|
|
117
|
-
}
|
|
118
|
-
function removePath(filePath) {
|
|
119
|
-
fs.rmSync(filePath, { force: true, recursive: true });
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// src/cli/templates.ts
|
|
123
|
-
function authLoginRouteTemplate() {
|
|
124
|
-
return `import { loginHandler } from '../../auth-config';
|
|
125
|
-
|
|
126
|
-
export const dynamic = 'force-dynamic';
|
|
127
|
-
|
|
128
|
-
export const GET = loginHandler;
|
|
129
|
-
`;
|
|
130
|
-
}
|
|
131
|
-
function authSignupRouteTemplate() {
|
|
132
|
-
return `import { signupHandler } from '../../auth-config';
|
|
133
|
-
|
|
134
|
-
export const dynamic = 'force-dynamic';
|
|
135
|
-
|
|
136
|
-
export const GET = signupHandler;
|
|
137
|
-
`;
|
|
138
|
-
}
|
|
139
|
-
function authorizeRouteTemplate() {
|
|
140
|
-
return `import { authorizeHandler } from '../../../auth-config';
|
|
141
|
-
|
|
142
|
-
export const dynamic = 'force-dynamic';
|
|
143
|
-
|
|
144
|
-
export const GET = authorizeHandler;
|
|
145
|
-
`;
|
|
146
|
-
}
|
|
147
|
-
function signupAuthorizeRouteTemplate() {
|
|
148
|
-
return `import { authorizeHandler } from '../../../auth-config';
|
|
149
|
-
|
|
150
|
-
export const dynamic = 'force-dynamic';
|
|
151
|
-
|
|
152
|
-
export const GET = authorizeHandler;
|
|
153
|
-
`;
|
|
154
|
-
}
|
|
155
|
-
function callbackRouteTemplate() {
|
|
156
|
-
return `import { callbackHandler } from '../auth-config';
|
|
157
|
-
|
|
158
|
-
export const dynamic = 'force-dynamic';
|
|
159
|
-
|
|
160
|
-
export const GET = callbackHandler;
|
|
161
|
-
`;
|
|
162
|
-
}
|
|
163
|
-
function logoutRouteTemplate() {
|
|
164
|
-
return `import { logoutHandler } from '../auth-config';
|
|
165
|
-
|
|
166
|
-
export const dynamic = 'force-dynamic';
|
|
167
|
-
|
|
168
|
-
export const GET = logoutHandler;
|
|
169
|
-
`;
|
|
170
|
-
}
|
|
171
|
-
function callbackErrorPageTemplate() {
|
|
172
|
-
return `import { ClearDomainCookiesButton } from './clear-domain-cookies-button';
|
|
173
|
-
|
|
174
|
-
export const dynamic = 'force-dynamic';
|
|
175
|
-
|
|
176
|
-
export default async function CallbackErrorPage({
|
|
177
|
-
searchParams,
|
|
178
|
-
}: {
|
|
179
|
-
searchParams: Promise<{ title?: string; message?: string; details?: string }>;
|
|
180
|
-
}) {
|
|
181
|
-
const params = await searchParams;
|
|
182
|
-
|
|
183
|
-
return (
|
|
184
|
-
<main
|
|
185
|
-
style={{
|
|
186
|
-
minHeight: '100dvh',
|
|
187
|
-
display: 'flex',
|
|
188
|
-
alignItems: 'center',
|
|
189
|
-
justifyContent: 'center',
|
|
190
|
-
padding: '20px 16px',
|
|
191
|
-
background:
|
|
192
|
-
'radial-gradient(circle at top, rgba(99, 102, 241, 0.12) 0, rgba(99, 102, 241, 0) 38%), linear-gradient(180deg, #f8fafc 0%, #eef2ff 100%)',
|
|
193
|
-
}}
|
|
194
|
-
>
|
|
195
|
-
<section
|
|
196
|
-
style={{
|
|
197
|
-
width: 'min(100%, 400px)',
|
|
198
|
-
borderRadius: 28,
|
|
199
|
-
padding: '24px 20px',
|
|
200
|
-
boxSizing: 'border-box',
|
|
201
|
-
background: 'rgba(255, 255, 255, 0.96)',
|
|
202
|
-
border: '1px solid rgba(148, 163, 184, 0.2)',
|
|
203
|
-
boxShadow: '0 22px 52px rgba(15, 23, 42, 0.12)',
|
|
204
|
-
textAlign: 'center',
|
|
205
|
-
backdropFilter: 'blur(10px)',
|
|
206
|
-
}}
|
|
207
|
-
>
|
|
208
|
-
<div
|
|
209
|
-
style={{
|
|
210
|
-
width: 52,
|
|
211
|
-
height: 52,
|
|
212
|
-
margin: '0 auto 14px',
|
|
213
|
-
display: 'grid',
|
|
214
|
-
placeItems: 'center',
|
|
215
|
-
borderRadius: 18,
|
|
216
|
-
background: 'linear-gradient(135deg, rgba(239, 68, 68, 0.15), rgba(249, 115, 22, 0.1))',
|
|
217
|
-
color: '#b91c1c',
|
|
218
|
-
fontSize: 28,
|
|
219
|
-
lineHeight: 1,
|
|
220
|
-
}}
|
|
221
|
-
aria-hidden="true"
|
|
222
|
-
>
|
|
223
|
-
!
|
|
224
|
-
</div>
|
|
225
|
-
<div
|
|
226
|
-
style={{
|
|
227
|
-
display: 'inline-flex',
|
|
228
|
-
alignItems: 'center',
|
|
229
|
-
justifyContent: 'center',
|
|
230
|
-
marginBottom: 12,
|
|
231
|
-
padding: '6px 12px',
|
|
232
|
-
borderRadius: 9999,
|
|
233
|
-
background: 'rgba(254, 226, 226, 0.9)',
|
|
234
|
-
color: '#b91c1c',
|
|
235
|
-
fontSize: 13,
|
|
236
|
-
fontWeight: 600,
|
|
237
|
-
letterSpacing: '0.04em',
|
|
238
|
-
}}
|
|
239
|
-
>
|
|
240
|
-
\u8BA4\u8BC1\u5931\u8D25
|
|
241
|
-
</div>
|
|
242
|
-
<h2 style={{ margin: 0, fontSize: 24, lineHeight: 1.2, color: '#0f172a' }}>{params.title ?? 'Callback Error'}</h2>
|
|
243
|
-
<p style={{ margin: '12px 0 0', color: '#334155', lineHeight: 1.6 }}>{params.message ?? 'Unknown callback failure.'}</p>
|
|
244
|
-
{params.details ? (
|
|
245
|
-
<pre
|
|
246
|
-
style={{
|
|
247
|
-
margin: '14px 0 0',
|
|
248
|
-
maxHeight: 140,
|
|
249
|
-
overflow: 'auto',
|
|
250
|
-
padding: 14,
|
|
251
|
-
borderRadius: 18,
|
|
252
|
-
textAlign: 'left',
|
|
253
|
-
whiteSpace: 'pre-wrap',
|
|
254
|
-
wordBreak: 'break-word',
|
|
255
|
-
background: '#f8fafc',
|
|
256
|
-
color: '#0f172a',
|
|
257
|
-
border: '1px solid rgba(148, 163, 184, 0.18)',
|
|
258
|
-
fontSize: 13,
|
|
259
|
-
lineHeight: 1.6,
|
|
260
|
-
}}
|
|
261
|
-
>
|
|
262
|
-
{params.details}
|
|
263
|
-
</pre>
|
|
264
|
-
) : null}
|
|
265
|
-
${customBegin}
|
|
266
|
-
<div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 20 }}>
|
|
267
|
-
<ClearDomainCookiesButton />
|
|
268
|
-
<a href="/" style={{ display: 'inline-flex', width: '100%', alignItems: 'center', justifyContent: 'center', minHeight: 44, padding: '0 16px', boxSizing: 'border-box', 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>
|
|
269
|
-
<a href="/auth/login" style={{ display: 'inline-flex', width: '100%', alignItems: 'center', justifyContent: 'center', minHeight: 44, padding: '0 16px', boxSizing: 'border-box', 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>
|
|
270
|
-
<a href="/auth/signup" style={{ display: 'inline-flex', width: '100%', alignItems: 'center', justifyContent: 'center', minHeight: 44, padding: '0 16px', boxSizing: 'border-box', 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>
|
|
271
|
-
</div>
|
|
272
|
-
${customEnd}
|
|
273
|
-
</section>
|
|
274
|
-
</main>
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
`;
|
|
278
|
-
}
|
|
279
|
-
function callbackErrorClearCookiesButtonTemplate() {
|
|
280
|
-
return `'use client';
|
|
281
|
-
|
|
282
|
-
import { useState } from 'react';
|
|
283
|
-
|
|
284
|
-
const AUTH_COOKIE_NAMES = [
|
|
285
|
-
'auth_origin',
|
|
286
|
-
'auth_redirect',
|
|
287
|
-
'oauth_state',
|
|
288
|
-
'pkce_code_verifier',
|
|
289
|
-
'next-auth.session-token',
|
|
290
|
-
'__Secure-next-auth.session-token',
|
|
291
|
-
'next-auth.csrf-token',
|
|
292
|
-
'__Secure-next-auth.csrf-token',
|
|
293
|
-
'__Host-next-auth.csrf-token',
|
|
294
|
-
];
|
|
295
|
-
|
|
296
|
-
function getPathCandidates(pathname: string): string[] {
|
|
297
|
-
const normalized = pathname.startsWith('/') ? pathname : '/' + pathname;
|
|
298
|
-
const segments = normalized.split('/').filter(Boolean);
|
|
299
|
-
const paths = new Set<string>(['/']);
|
|
300
|
-
|
|
301
|
-
let current = '';
|
|
302
|
-
for (const segment of segments) {
|
|
303
|
-
current += '/' + segment;
|
|
304
|
-
paths.add(current);
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
return [...paths];
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
function getDomainCandidates(hostname: string): string[] {
|
|
311
|
-
const normalized = hostname.toLowerCase();
|
|
312
|
-
if (
|
|
313
|
-
normalized === 'localhost' ||
|
|
314
|
-
normalized.endsWith('.localhost') ||
|
|
315
|
-
/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(normalized) ||
|
|
316
|
-
/^\\[[^\\]]+\\]$/.test(normalized)
|
|
317
|
-
) {
|
|
318
|
-
return [];
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
const parts = normalized.split('.');
|
|
322
|
-
if (parts.length < 2) {
|
|
323
|
-
return [];
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
const domains = new Set<string>();
|
|
327
|
-
for (let index = 0; index < parts.length - 1; index++) {
|
|
328
|
-
const suffix = parts.slice(index).join('.');
|
|
329
|
-
domains.add(suffix);
|
|
330
|
-
domains.add('.' + suffix);
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
return [...domains];
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
function expireCookie(name: string, path: string, domain?: string) {
|
|
337
|
-
const pieces = [
|
|
338
|
-
name + '=',
|
|
339
|
-
'Max-Age=0',
|
|
340
|
-
'Expires=Thu, 01 Jan 1970 00:00:00 GMT',
|
|
341
|
-
'Path=' + path,
|
|
342
|
-
'SameSite=Lax',
|
|
343
|
-
];
|
|
344
|
-
|
|
345
|
-
if (domain) {
|
|
346
|
-
pieces.push('Domain=' + domain);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (window.location.protocol === 'https:') {
|
|
350
|
-
pieces.push('Secure');
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
document.cookie = pieces.join('; ');
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
${customBegin}
|
|
357
|
-
export function ClearDomainCookiesButton() {
|
|
358
|
-
const [cleared, setCleared] = useState(false);
|
|
359
|
-
|
|
360
|
-
const handleClick = () => {
|
|
361
|
-
if (typeof document === 'undefined' || typeof window === 'undefined') {
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
const names = new Set<string>(AUTH_COOKIE_NAMES);
|
|
366
|
-
for (const entry of document.cookie.split(';')) {
|
|
367
|
-
const [rawName] = entry.trim().split('=');
|
|
368
|
-
if (rawName) {
|
|
369
|
-
names.add(rawName);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const pathCandidates = getPathCandidates(window.location.pathname);
|
|
374
|
-
const domainCandidates = getDomainCandidates(window.location.hostname);
|
|
375
|
-
|
|
376
|
-
for (const name of names) {
|
|
377
|
-
for (const path of pathCandidates) {
|
|
378
|
-
expireCookie(name, path);
|
|
379
|
-
for (const domain of domainCandidates) {
|
|
380
|
-
expireCookie(name, path, domain);
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
setCleared(true);
|
|
386
|
-
};
|
|
387
|
-
|
|
388
|
-
return (
|
|
389
|
-
<button
|
|
390
|
-
type="button"
|
|
391
|
-
onClick={handleClick}
|
|
392
|
-
disabled={cleared}
|
|
393
|
-
style={{
|
|
394
|
-
display: 'inline-flex',
|
|
395
|
-
width: '100%',
|
|
396
|
-
alignItems: 'center',
|
|
397
|
-
justifyContent: 'center',
|
|
398
|
-
minHeight: 44,
|
|
399
|
-
padding: '0 16px',
|
|
400
|
-
boxSizing: 'border-box',
|
|
401
|
-
borderRadius: 9999,
|
|
402
|
-
border: '1px solid rgba(148, 163, 184, 0.35)',
|
|
403
|
-
color: '#0f172a',
|
|
404
|
-
background: cleared ? 'rgba(220, 252, 231, 0.92)' : 'rgba(248, 250, 252, 0.9)',
|
|
405
|
-
cursor: cleared ? 'default' : 'pointer',
|
|
406
|
-
}}
|
|
407
|
-
>
|
|
408
|
-
{cleared ? '\u5DF2\u6E05\u7A7A' : '\u6E05\u7A7A\u5F53\u524D\u57DF Cookie'}
|
|
409
|
-
</button>
|
|
410
|
-
);
|
|
411
|
-
}
|
|
412
|
-
${customEnd}
|
|
413
|
-
`;
|
|
414
|
-
}
|
|
415
|
-
function authConfigTemplate() {
|
|
416
|
-
return `import {
|
|
417
|
-
createCallbackHandler,
|
|
418
|
-
createCasdoorApiProxyHandler,
|
|
419
|
-
createCasdoorCommerceProxyHandler,
|
|
420
|
-
createAuthorizeRouteHandler,
|
|
421
|
-
createLoginRouteHandler,
|
|
422
|
-
createLogoutHandler,
|
|
423
|
-
createNextAuthOptions,
|
|
424
|
-
createSignupRouteHandler,
|
|
425
|
-
type AuthBusinessAdapter,
|
|
426
|
-
type AuthKitConfig,
|
|
427
|
-
type AuthPersistenceAdapter,
|
|
428
|
-
} from '@foldspace-fe/casdoor-next-auth-kit';
|
|
429
|
-
import { isGlobalAdminEmail } from '@foldspace-fe/casdoor-next-auth-kit';
|
|
430
|
-
import { paymentSuccessHandler as billingPaymentSuccessHandler } from '@/lib/billing/payment-success';
|
|
431
|
-
import { paymentFinishedHandler as billingPaymentFinishedHandler } from '@/lib/billing/payment-finished';
|
|
432
|
-
|
|
433
|
-
export function createAuthKitConfig(): AuthKitConfig {
|
|
434
|
-
return {
|
|
435
|
-
appUrl: process.env.APP_URL || '',
|
|
436
|
-
nextauthSecret: process.env.NEXTAUTH_SECRET || 'dev-nextauth-secret',
|
|
437
|
-
logoutRedirectPath: process.env.NEXT_PUBLIC_AUTH_LOGOUT_REDIRECT_PATH || '/',
|
|
438
|
-
casdoor: {
|
|
439
|
-
serverUrl: process.env.NEXT_PUBLIC_CASDOOR_SERVER_URL || process.env.CASDOOR_SERVER_URL || '',
|
|
440
|
-
clientId: process.env.NEXT_PUBLIC_CASDOOR_CLIENT_ID || process.env.CASDOOR_CLIENT_ID || '',
|
|
441
|
-
clientSecret: process.env.CASDOOR_CLIENT_SECRET || '',
|
|
442
|
-
appName: process.env.NEXT_PUBLIC_CASDOOR_APP_NAME || '',
|
|
443
|
-
organizationName: process.env.NEXT_PUBLIC_CASDOOR_ORGANIZATION_NAME || '',
|
|
444
|
-
redirectPath: process.env.NEXT_PUBLIC_CASDOOR_REDIRECT_PATH || '/callback',
|
|
445
|
-
signinPath: process.env.NEXT_PUBLIC_CASDOOR_SIGNIN_PATH || '/login/oauth/authorize',
|
|
446
|
-
},
|
|
447
|
-
};
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
export const authKitConfig = createAuthKitConfig();
|
|
451
|
-
|
|
452
|
-
export const adapter: AuthBusinessAdapter = {
|
|
453
|
-
isAdminEmail: isGlobalAdminEmail,
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
export const persistence: AuthPersistenceAdapter = {
|
|
457
|
-
async syncAuthUser() {
|
|
458
|
-
return;
|
|
459
|
-
},
|
|
460
|
-
async findAuthUser() {
|
|
461
|
-
return null;
|
|
462
|
-
},
|
|
463
|
-
};
|
|
464
|
-
|
|
465
|
-
export const paymentSuccessHandler = billingPaymentSuccessHandler;
|
|
466
|
-
export const paymentFinishedHandler = billingPaymentFinishedHandler;
|
|
467
|
-
|
|
468
|
-
export const loginHandler = createLoginRouteHandler(authKitConfig);
|
|
469
|
-
export const signupHandler = createSignupRouteHandler(authKitConfig);
|
|
470
|
-
export const authorizeHandler = createAuthorizeRouteHandler(authKitConfig);
|
|
471
|
-
export const callbackHandler = createCallbackHandler({
|
|
472
|
-
config: authKitConfig,
|
|
473
|
-
adapter,
|
|
474
|
-
persistence,
|
|
475
|
-
});
|
|
476
|
-
export const logoutHandler = createLogoutHandler(authKitConfig);
|
|
477
|
-
export const authOptions = createNextAuthOptions({
|
|
478
|
-
config: authKitConfig,
|
|
479
|
-
adapter,
|
|
480
|
-
persistence,
|
|
481
|
-
});
|
|
482
|
-
export const apiProxyHandler = createCasdoorApiProxyHandler(authKitConfig, '/auth/api', '/api');
|
|
483
|
-
export const commerceProxyHandler = createCasdoorCommerceProxyHandler(authKitConfig, '/auth/api/commerce', '/api/commerce');
|
|
484
|
-
`;
|
|
485
|
-
}
|
|
486
|
-
function nextAuthRouteTemplate() {
|
|
487
|
-
return `import NextAuth from 'next-auth';
|
|
488
|
-
import { createNextAuthOptions } from '@foldspace-fe/casdoor-next-auth-kit';
|
|
489
|
-
import { adapter, authKitConfig, persistence } from '../../../auth-config';
|
|
490
|
-
|
|
491
|
-
export const dynamic = 'force-dynamic';
|
|
492
|
-
export const runtime = 'nodejs';
|
|
493
|
-
|
|
494
|
-
const handler = NextAuth(
|
|
495
|
-
createNextAuthOptions({
|
|
496
|
-
config: authKitConfig,
|
|
497
|
-
adapter,
|
|
498
|
-
persistence,
|
|
499
|
-
}),
|
|
500
|
-
);
|
|
501
|
-
|
|
502
|
-
export const GET = handler;
|
|
503
|
-
export const POST = handler;
|
|
504
|
-
`;
|
|
505
|
-
}
|
|
506
|
-
function paymentSuccessRouteTemplate() {
|
|
507
|
-
return `import { createBillingPaymentSuccessRouteHandler } from '@foldspace-fe/casdoor-next-auth-kit';
|
|
508
|
-
import { authKitConfig, paymentSuccessHandler } from '../../../auth-config';
|
|
509
|
-
|
|
510
|
-
export const dynamic = 'force-dynamic';
|
|
511
|
-
export const runtime = 'nodejs';
|
|
512
|
-
|
|
513
|
-
export const GET = createBillingPaymentSuccessRouteHandler({
|
|
514
|
-
appUrl: authKitConfig.appUrl,
|
|
515
|
-
fallbackRedirect: '/auth/payment/finished',
|
|
516
|
-
handler: paymentSuccessHandler,
|
|
517
|
-
phase: 'success',
|
|
518
|
-
});
|
|
519
|
-
`;
|
|
520
|
-
}
|
|
521
|
-
function paymentFinishedRouteTemplate() {
|
|
522
|
-
return `import { createBillingPaymentFinishedRouteHandler } from '@foldspace-fe/casdoor-next-auth-kit';
|
|
523
|
-
import { authKitConfig, paymentFinishedHandler } from '../../../auth-config';
|
|
524
|
-
|
|
525
|
-
export const dynamic = 'force-dynamic';
|
|
526
|
-
export const runtime = 'nodejs';
|
|
527
|
-
|
|
528
|
-
export const GET = createBillingPaymentFinishedRouteHandler({
|
|
529
|
-
appUrl: authKitConfig.appUrl,
|
|
530
|
-
fallbackRedirect: '/',
|
|
531
|
-
handler: paymentFinishedHandler,
|
|
532
|
-
phase: 'finished',
|
|
533
|
-
});
|
|
534
|
-
`;
|
|
535
|
-
}
|
|
536
|
-
function billingPaymentSuccessHandlerTemplate() {
|
|
537
|
-
return `import type { BillingPaymentSuccessHandler } from '@foldspace-fe/casdoor-next-auth-kit/billing';
|
|
538
|
-
|
|
539
|
-
${customBegin}
|
|
540
|
-
const paymentSuccessHandlerImpl: BillingPaymentSuccessHandler = async (context) => {
|
|
541
|
-
console.info('[casdoor-next-auth-kit] payment success callback received', {
|
|
542
|
-
paymentId: context.paymentId,
|
|
543
|
-
orderId: context.orderId,
|
|
544
|
-
status: context.status,
|
|
545
|
-
redirectTo: context.redirectTo,
|
|
546
|
-
});
|
|
547
|
-
return;
|
|
548
|
-
};
|
|
549
|
-
${customEnd}
|
|
550
|
-
|
|
551
|
-
export const paymentSuccessHandler: BillingPaymentSuccessHandler = paymentSuccessHandlerImpl;
|
|
552
|
-
`;
|
|
553
|
-
}
|
|
554
|
-
function billingPaymentFinishedHandlerTemplate() {
|
|
555
|
-
return `import type { BillingPaymentFinishedHandler } from '@foldspace-fe/casdoor-next-auth-kit/billing';
|
|
556
|
-
|
|
557
|
-
${customBegin}
|
|
558
|
-
const paymentFinishedHandlerImpl: BillingPaymentFinishedHandler = async (context) => {
|
|
559
|
-
console.info('[casdoor-next-auth-kit] payment finished callback received', {
|
|
560
|
-
paymentId: context.paymentId,
|
|
561
|
-
orderId: context.orderId,
|
|
562
|
-
status: context.status,
|
|
563
|
-
redirectTo: context.redirectTo,
|
|
564
|
-
});
|
|
565
|
-
return;
|
|
566
|
-
};
|
|
567
|
-
${customEnd}
|
|
568
|
-
|
|
569
|
-
export const paymentFinishedHandler: BillingPaymentFinishedHandler = paymentFinishedHandlerImpl;
|
|
570
|
-
`;
|
|
571
|
-
}
|
|
572
|
-
function authIndexHtmlTemplate() {
|
|
573
|
-
return `export { AUTH_INDEX_HTML, createAuthIndexHtml } from '@foldspace-fe/casdoor-next-auth-kit';
|
|
574
|
-
`;
|
|
575
|
-
}
|
|
576
|
-
function prismaSchemaTemplate() {
|
|
577
|
-
return buildAuthPrismaSchemaTemplate();
|
|
578
|
-
}
|
|
579
|
-
function apiProxyRouteTemplate() {
|
|
580
|
-
return `import { apiProxyHandler } from '../../../auth-config';
|
|
581
|
-
|
|
582
|
-
export const dynamic = 'force-dynamic';
|
|
583
|
-
|
|
584
|
-
export const GET = apiProxyHandler;
|
|
585
|
-
export const HEAD = apiProxyHandler;
|
|
586
|
-
export const POST = apiProxyHandler;
|
|
587
|
-
export const PUT = apiProxyHandler;
|
|
588
|
-
export const PATCH = apiProxyHandler;
|
|
589
|
-
export const DELETE = apiProxyHandler;
|
|
590
|
-
export const OPTIONS = apiProxyHandler;
|
|
591
|
-
`;
|
|
592
|
-
}
|
|
593
|
-
function commerceProxyRouteTemplate() {
|
|
594
|
-
return `import { commerceProxyHandler } from '../../../../auth-config';
|
|
595
|
-
|
|
596
|
-
export const dynamic = 'force-dynamic';
|
|
597
|
-
|
|
598
|
-
export const GET = commerceProxyHandler;
|
|
599
|
-
export const HEAD = commerceProxyHandler;
|
|
600
|
-
export const POST = commerceProxyHandler;
|
|
601
|
-
export const PUT = commerceProxyHandler;
|
|
602
|
-
export const PATCH = commerceProxyHandler;
|
|
603
|
-
export const DELETE = commerceProxyHandler;
|
|
604
|
-
export const OPTIONS = commerceProxyHandler;
|
|
605
|
-
`;
|
|
606
|
-
}
|
|
607
|
-
function envTemplate(file, existingContent = "") {
|
|
608
|
-
return buildManagedEnvTemplate(file, existingContent);
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
// src/cli/operations.ts
|
|
106
|
+
import { fileURLToPath } from "url";
|
|
612
107
|
var projectRoot = process.cwd();
|
|
613
|
-
var distRoot =
|
|
108
|
+
var distRoot = path.dirname(fileURLToPath(import.meta.url));
|
|
614
109
|
var canonicalSkillPaths = [
|
|
615
|
-
|
|
616
|
-
|
|
110
|
+
path.join(distRoot, "skills/casdoor-next-auth-kit"),
|
|
111
|
+
path.resolve(distRoot, "..", "..", "..", "skills/casdoor-next-auth-kit")
|
|
617
112
|
];
|
|
618
113
|
var skillTarget = ".agents/skills/casdoor-next-auth-kit";
|
|
619
114
|
var targets = [
|
|
@@ -668,17 +163,17 @@ var deprecatedTargets = [
|
|
|
668
163
|
"lib/auth-redirect.ts"
|
|
669
164
|
];
|
|
670
165
|
function logCreated(filePath) {
|
|
671
|
-
console.log(`+ ${
|
|
166
|
+
console.log(`+ ${path.relative(projectRoot, filePath)}`);
|
|
672
167
|
}
|
|
673
168
|
function logUpdated(filePath) {
|
|
674
|
-
console.log(`~ ${
|
|
169
|
+
console.log(`~ ${path.relative(projectRoot, filePath)}`);
|
|
675
170
|
}
|
|
676
171
|
function logRemoved(filePath) {
|
|
677
|
-
console.log(`- ${
|
|
172
|
+
console.log(`- ${path.relative(projectRoot, filePath)}`);
|
|
678
173
|
}
|
|
679
174
|
function syncManagedEnvFiles() {
|
|
680
175
|
for (const file of AUTH_KIT_ENV_FILES) {
|
|
681
|
-
const filePath =
|
|
176
|
+
const filePath = path.join(projectRoot, file);
|
|
682
177
|
const existed = exists(filePath);
|
|
683
178
|
const current = existed ? read(filePath) : "";
|
|
684
179
|
const next = envTemplate(file, current);
|
|
@@ -693,25 +188,25 @@ function syncManagedEnvFiles() {
|
|
|
693
188
|
}
|
|
694
189
|
}
|
|
695
190
|
function syncManagedSkillFile() {
|
|
696
|
-
const filePath =
|
|
191
|
+
const filePath = path.join(projectRoot, skillTarget);
|
|
697
192
|
try {
|
|
698
|
-
const sourcePath = canonicalSkillPaths.find((candidate) =>
|
|
193
|
+
const sourcePath = canonicalSkillPaths.find((candidate) => fs.existsSync(candidate));
|
|
699
194
|
if (!sourcePath) {
|
|
700
195
|
throw new Error(`Unable to locate canonical skill directory. Checked: ${canonicalSkillPaths.join(", ")}`);
|
|
701
196
|
}
|
|
702
197
|
removePath(filePath);
|
|
703
|
-
|
|
198
|
+
fs.mkdirSync(filePath, { recursive: true });
|
|
704
199
|
logCreated(filePath);
|
|
705
|
-
for (const entry of
|
|
706
|
-
const sourceEntry =
|
|
707
|
-
const targetEntry =
|
|
200
|
+
for (const entry of fs.readdirSync(sourcePath, { withFileTypes: true })) {
|
|
201
|
+
const sourceEntry = path.join(sourcePath, entry.name);
|
|
202
|
+
const targetEntry = path.join(filePath, entry.name);
|
|
708
203
|
if (entry.isDirectory()) {
|
|
709
|
-
|
|
710
|
-
console.log(`+ ${
|
|
204
|
+
fs.cpSync(sourceEntry, targetEntry, { recursive: true });
|
|
205
|
+
console.log(`+ ${path.relative(projectRoot, targetEntry)}/`);
|
|
711
206
|
continue;
|
|
712
207
|
}
|
|
713
|
-
|
|
714
|
-
console.log(`+ ${
|
|
208
|
+
fs.copyFileSync(sourceEntry, targetEntry);
|
|
209
|
+
console.log(`+ ${path.relative(projectRoot, targetEntry)}`);
|
|
715
210
|
}
|
|
716
211
|
} catch (error) {
|
|
717
212
|
console.warn(`Skipped skill sync for ${skillTarget}: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -719,7 +214,7 @@ function syncManagedSkillFile() {
|
|
|
719
214
|
}
|
|
720
215
|
async function initProject() {
|
|
721
216
|
for (const [rel, factory] of targets) {
|
|
722
|
-
const filePath =
|
|
217
|
+
const filePath = path.join(projectRoot, rel);
|
|
723
218
|
if (!exists(filePath)) {
|
|
724
219
|
writeGeneratedFile(filePath, factory());
|
|
725
220
|
logCreated(filePath);
|
|
@@ -731,14 +226,14 @@ async function initProject() {
|
|
|
731
226
|
}
|
|
732
227
|
async function updateProject() {
|
|
733
228
|
for (const rel of deprecatedTargets) {
|
|
734
|
-
const filePath =
|
|
229
|
+
const filePath = path.join(projectRoot, rel);
|
|
735
230
|
if (exists(filePath)) {
|
|
736
231
|
removePath(filePath);
|
|
737
232
|
logRemoved(filePath);
|
|
738
233
|
}
|
|
739
234
|
}
|
|
740
235
|
for (const [rel, factory] of targets) {
|
|
741
|
-
const filePath =
|
|
236
|
+
const filePath = path.join(projectRoot, rel);
|
|
742
237
|
const next = "// generated by @foldspace-fe/casdoor-next-auth-kit\n" + factory();
|
|
743
238
|
if (!exists(filePath)) {
|
|
744
239
|
writeGeneratedFile(filePath, factory());
|
|
@@ -765,16 +260,16 @@ async function updateProject() {
|
|
|
765
260
|
console.log("Updated managed route shells, env files, and skill file.");
|
|
766
261
|
}
|
|
767
262
|
async function checkProject() {
|
|
768
|
-
const missingRoutes = targets.filter(([rel]) => !exists(
|
|
263
|
+
const missingRoutes = targets.filter(([rel]) => !exists(path.join(projectRoot, rel))).map(([rel]) => rel);
|
|
769
264
|
const missingEnv = AUTH_KIT_ENV_FILES.filter((file) => {
|
|
770
|
-
const filePath =
|
|
265
|
+
const filePath = path.join(projectRoot, file);
|
|
771
266
|
if (!exists(filePath)) {
|
|
772
267
|
return true;
|
|
773
268
|
}
|
|
774
269
|
return getMissingManagedEnvKeys(read(filePath)).length > 0;
|
|
775
270
|
});
|
|
776
|
-
const skillDir =
|
|
777
|
-
const missingSkill = exists(
|
|
271
|
+
const skillDir = path.join(projectRoot, skillTarget);
|
|
272
|
+
const missingSkill = exists(path.join(skillDir, "SKILL.md")) ? [] : [path.join(skillTarget, "SKILL.md")];
|
|
778
273
|
const missing = [...missingRoutes, ...missingEnv, ...missingSkill];
|
|
779
274
|
if (missing.length > 0) {
|
|
780
275
|
console.error("Missing generated files:");
|