@payez/next-mvp 4.1.11 → 4.1.20
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/api-handlers/account/profile.d.ts +38 -0
- package/dist/api-handlers/account/profile.js +73 -45
- package/dist/api-handlers/account/recovery/send-code.d.ts +33 -0
- package/dist/api-handlers/account/recovery/send-code.js +52 -18
- package/dist/api-handlers/account/recovery/verify-code.d.ts +33 -0
- package/dist/api-handlers/account/recovery/verify-code.js +52 -18
- package/dist/api-handlers/account/verify-email.js +15 -1
- package/dist/api-handlers/account/verify-sms.js +15 -1
- package/dist/api-handlers/auth/passkey-signin.d.ts +29 -0
- package/dist/api-handlers/auth/passkey-signin.js +97 -0
- package/dist/api-handlers/mfa/backup-code-verify.d.ts +73 -0
- package/dist/api-handlers/mfa/backup-code-verify.js +153 -0
- package/dist/api-handlers/mfa/backup-codes.d.ts +7 -0
- package/dist/api-handlers/mfa/backup-codes.js +40 -0
- package/dist/api-handlers/mfa/methods.d.ts +3 -0
- package/dist/api-handlers/mfa/methods.js +41 -0
- package/dist/api-handlers/mfa/totp-confirm.d.ts +8 -0
- package/dist/api-handlers/mfa/totp-confirm.js +41 -0
- package/dist/api-handlers/mfa/totp-enroll.d.ts +8 -0
- package/dist/api-handlers/mfa/totp-enroll.js +41 -0
- package/dist/api-handlers/mfa/totp-verify.d.ts +47 -0
- package/dist/api-handlers/mfa/totp-verify.js +134 -0
- package/dist/api-handlers/passkeys/list.d.ts +7 -0
- package/dist/api-handlers/passkeys/list.js +29 -0
- package/dist/api-handlers/passkeys/manage.d.ts +3 -0
- package/dist/api-handlers/passkeys/manage.js +54 -0
- package/dist/api-handlers/passkeys/register-options.d.ts +8 -0
- package/dist/api-handlers/passkeys/register-options.js +41 -0
- package/dist/api-handlers/passkeys/register-verify.d.ts +7 -0
- package/dist/api-handlers/passkeys/register-verify.js +40 -0
- package/dist/api-handlers/session/viability.js +19 -0
- package/dist/auth/better-auth.d.ts +68 -5
- package/dist/auth/better-auth.js +256 -42
- package/dist/auth/utils/idp-client.d.ts +13 -22
- package/dist/auth/utils/idp-client.js +12 -82
- package/dist/client/better-auth-client.d.ts +14 -2
- package/dist/lib/session-store.js +28 -21
- package/dist/lib/startup-init.js +19 -19
- package/dist/lib/token-lifecycle.js +40 -4
- package/dist/models/SessionModel.d.ts +17 -0
- package/dist/pages/login/page.d.ts +10 -1
- package/dist/pages/login/page.js +69 -80
- package/dist/pages/verify-code/page.d.ts +10 -1
- package/dist/pages/verify-code/page.js +72 -4
- package/dist/routes/auth/passkey-signin.d.ts +13 -0
- package/dist/routes/auth/passkey-signin.js +18 -0
- package/dist/routes/auth/viability.d.ts +2 -0
- package/dist/routes/auth/viability.js +88 -0
- package/dist/routes/mfa/backup-code-verify.d.ts +1 -0
- package/dist/routes/mfa/backup-code-verify.js +5 -0
- package/dist/routes/mfa/backup-codes.d.ts +10 -0
- package/dist/routes/mfa/backup-codes.js +14 -0
- package/dist/routes/mfa/methods.d.ts +21 -0
- package/dist/routes/mfa/methods.js +10 -0
- package/dist/routes/mfa/totp-confirm.d.ts +10 -0
- package/dist/routes/mfa/totp-confirm.js +14 -0
- package/dist/routes/mfa/totp-enroll.d.ts +10 -0
- package/dist/routes/mfa/totp-enroll.js +14 -0
- package/dist/routes/mfa/totp-verify.d.ts +14 -0
- package/dist/routes/mfa/totp-verify.js +18 -0
- package/dist/routes/passkeys/list.d.ts +10 -0
- package/dist/routes/passkeys/list.js +14 -0
- package/dist/routes/passkeys/manage.d.ts +18 -0
- package/dist/routes/passkeys/manage.js +13 -0
- package/dist/routes/passkeys/register-options.d.ts +10 -0
- package/dist/routes/passkeys/register-options.js +14 -0
- package/dist/routes/passkeys/register-verify.d.ts +10 -0
- package/dist/routes/passkeys/register-verify.js +14 -0
- package/dist/server/auth.d.ts +2 -2
- package/dist/server/decode-session.js +37 -3
- package/package.json +958 -893
- package/scripts/check-internal-url-usage.sh +73 -73
- package/src/api/index.ts +17 -17
- package/src/api-handlers/account/masked-info.ts +45 -45
- package/src/api-handlers/account/profile.ts +99 -80
- package/src/api-handlers/account/recovery/initiate.ts +23 -23
- package/src/api-handlers/account/recovery/send-code.ts +73 -25
- package/src/api-handlers/account/recovery/verify-code.ts +73 -25
- package/src/api-handlers/account/reset-password.ts +23 -23
- package/src/api-handlers/account/send-code.ts +76 -76
- package/src/api-handlers/account/validate-password.ts +118 -118
- package/src/api-handlers/account/verify-email.ts +15 -1
- package/src/api-handlers/account/verify-sms.ts +15 -1
- package/src/api-handlers/admin/stats.ts +249 -249
- package/src/api-handlers/anon/preferences.ts +123 -123
- package/src/api-handlers/auth/jwks.ts +20 -20
- package/src/api-handlers/auth/login.ts +240 -240
- package/src/api-handlers/auth/passkey-signin.ts +98 -0
- package/src/api-handlers/auth/validate.ts +43 -43
- package/src/api-handlers/mfa/backup-code-verify.ts +175 -0
- package/src/api-handlers/mfa/backup-codes.ts +41 -0
- package/src/api-handlers/mfa/methods.ts +46 -0
- package/src/api-handlers/mfa/totp-confirm.ts +42 -0
- package/src/api-handlers/mfa/totp-enroll.ts +42 -0
- package/src/api-handlers/mfa/totp-verify.ts +156 -0
- package/src/api-handlers/passkeys/list.ts +31 -0
- package/src/api-handlers/passkeys/manage.ts +54 -0
- package/src/api-handlers/passkeys/register-options.ts +42 -0
- package/src/api-handlers/passkeys/register-verify.ts +41 -0
- package/src/api-handlers/session/viability.ts +161 -142
- package/src/auth/better-auth.ts +247 -6
- package/src/auth/unauthenticated-routes.ts +2 -2
- package/src/auth/utils/idp-client.ts +13 -95
- package/src/client/better-auth-client.ts +70 -70
- package/src/client/fetchWithSession.ts +21 -21
- package/src/client/index.ts +13 -13
- package/src/client/useAnonSession.ts +131 -131
- package/src/components/admin/VibeAdminContext.tsx +87 -87
- package/src/config/logging-config.ts +82 -82
- package/src/config/unauthenticated-routes.ts +19 -19
- package/src/edge/internal-api-url.ts +65 -65
- package/src/edge/middleware.ts +42 -42
- package/src/hooks/useProfile.ts +75 -75
- package/src/lib/anon-session.ts +213 -213
- package/src/lib/auth-secret.ts +137 -137
- package/src/lib/demo-mode.ts +17 -17
- package/src/lib/idp-client-config.ts +559 -559
- package/src/lib/idp-fetch.ts +126 -126
- package/src/lib/internal-api.ts +171 -171
- package/src/lib/jwt-decode-client.ts +45 -45
- package/src/lib/rate-limit-service.ts +9 -9
- package/src/lib/redis.ts +26 -26
- package/src/lib/refresh-token-validator.ts +64 -64
- package/src/lib/secret-validation.ts +8 -8
- package/src/lib/session-store.ts +702 -695
- package/src/lib/session.ts +34 -34
- package/src/lib/startup-init.ts +251 -251
- package/src/lib/token-expiry.ts +40 -40
- package/src/lib/token-lifecycle.ts +533 -497
- package/src/lib/types/api-responses.ts +336 -336
- package/src/middleware/auth-decision.ts +43 -43
- package/src/models/DecodedAccessToken.ts +16 -16
- package/src/models/SessionModel.ts +282 -264
- package/src/pages/admin-roles/index.ts +9 -9
- package/src/pages/login/page.tsx +123 -228
- package/src/pages/security/EnhancedSecurityPage.tsx +9 -9
- package/src/pages/verify-code/page.tsx +71 -5
- package/src/routes/account/index.ts +31 -31
- package/src/routes/account/masked-info.ts +36 -36
- package/src/routes/account/send-code.ts +39 -39
- package/src/routes/account/verify-email.ts +40 -40
- package/src/routes/account/verify-sms.ts +40 -40
- package/src/routes/auth/index.ts +22 -22
- package/src/routes/auth/passkey-signin.ts +13 -0
- package/src/routes/auth/refresh.ts +48 -48
- package/src/routes/auth/session.ts +166 -166
- package/src/routes/auth/viability.ts +89 -0
- package/src/routes/index.ts +17 -17
- package/src/routes/mfa/backup-code-verify.ts +1 -0
- package/src/routes/mfa/backup-codes.ts +10 -0
- package/src/routes/mfa/methods.ts +22 -0
- package/src/routes/mfa/totp-confirm.ts +10 -0
- package/src/routes/mfa/totp-enroll.ts +10 -0
- package/src/routes/mfa/totp-verify.ts +14 -0
- package/src/routes/passkeys/list.ts +10 -0
- package/src/routes/passkeys/manage.ts +23 -0
- package/src/routes/passkeys/register-options.ts +10 -0
- package/src/routes/passkeys/register-verify.ts +10 -0
- package/src/routes/session/index.ts +7 -7
- package/src/routes/session/refresh-viability.ts +17 -17
- package/src/server/auth.ts +373 -373
- package/src/server/decode-session.ts +235 -202
- package/src/services/signalrActivityService.ts +258 -258
- package/src/theme/ThemeProvider.tsx +39 -39
- package/src/theme/default.ts +33 -33
- package/src/theme/index.ts +31 -31
- package/src/theme/types.ts +69 -69
- package/src/theme/useTheme.ts +57 -57
- package/src/theme/utils.ts +40 -40
- package/src/types/api.ts +12 -12
- package/src/types/auth.d.ts +23 -23
- package/src/types/auth.ts +22 -22
- package/src/types/logging.ts +11 -11
- package/src/types/recovery.ts +54 -54
- package/src/utils/api.ts +353 -353
- package/src/utils/circuitBreaker.ts +40 -40
- package/src/utils/error-message.ts +108 -108
- package/src/utils/layout/reservedSpace.ts +124 -124
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Anonymous Session Preferences API Handler
|
|
3
|
-
*
|
|
4
|
-
* GET /api/anon/preferences - Get current preferences
|
|
5
|
-
* POST /api/anon/preferences - Update preferences
|
|
6
|
-
*
|
|
7
|
-
* Sets a cookie to track anonymous visitors and stores preferences in Redis.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { NextRequest, NextResponse } from 'next/server';
|
|
11
|
-
import { cookies } from 'next/headers';
|
|
12
|
-
import {
|
|
13
|
-
getOrCreateAnonSession,
|
|
14
|
-
updateAnonPreferences,
|
|
15
|
-
ANON_COOKIE_NAME,
|
|
16
|
-
AnonSessionPreferences,
|
|
17
|
-
} from '../../lib/anon-session';
|
|
18
|
-
|
|
19
|
-
const COOKIE_MAX_AGE = 90 * 24 * 60 * 60; // 90 days in seconds
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* GET handler - retrieves anonymous session preferences
|
|
23
|
-
*/
|
|
24
|
-
export async function GET(request: NextRequest) {
|
|
25
|
-
try {
|
|
26
|
-
const cookieStore = await cookies();
|
|
27
|
-
let anonId = cookieStore.get(ANON_COOKIE_NAME)?.value;
|
|
28
|
-
|
|
29
|
-
// Get or create session
|
|
30
|
-
const session = await getOrCreateAnonSession(anonId);
|
|
31
|
-
|
|
32
|
-
// Build response
|
|
33
|
-
const response = NextResponse.json({
|
|
34
|
-
success: true,
|
|
35
|
-
data: {
|
|
36
|
-
id: session.id,
|
|
37
|
-
preferences: session.preferences,
|
|
38
|
-
metrics: session.metrics,
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
// Set cookie if it's a new session
|
|
43
|
-
if (!anonId || anonId !== session.id) {
|
|
44
|
-
response.cookies.set(ANON_COOKIE_NAME, session.id, {
|
|
45
|
-
httpOnly: true,
|
|
46
|
-
secure: process.env.NODE_ENV === 'production',
|
|
47
|
-
sameSite: 'lax',
|
|
48
|
-
maxAge: COOKIE_MAX_AGE,
|
|
49
|
-
path: '/',
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return response;
|
|
54
|
-
} catch (error) {
|
|
55
|
-
console.error('[ANON-PREFERENCES] GET error:', error);
|
|
56
|
-
return NextResponse.json(
|
|
57
|
-
{ success: false, error: 'Failed to get preferences' },
|
|
58
|
-
{ status: 500 }
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* POST handler - updates anonymous session preferences
|
|
65
|
-
*/
|
|
66
|
-
export async function POST(request: NextRequest) {
|
|
67
|
-
try {
|
|
68
|
-
const cookieStore = await cookies();
|
|
69
|
-
let anonId = cookieStore.get(ANON_COOKIE_NAME)?.value;
|
|
70
|
-
|
|
71
|
-
// Get or create session first
|
|
72
|
-
const session = await getOrCreateAnonSession(anonId);
|
|
73
|
-
anonId = session.id;
|
|
74
|
-
|
|
75
|
-
// Parse body for preferences to update
|
|
76
|
-
const body = await request.json();
|
|
77
|
-
const preferences: Partial<AnonSessionPreferences> = body.preferences || body;
|
|
78
|
-
|
|
79
|
-
// Validate preferences
|
|
80
|
-
if (typeof preferences !== 'object') {
|
|
81
|
-
return NextResponse.json(
|
|
82
|
-
{ success: false, error: 'Invalid preferences format' },
|
|
83
|
-
{ status: 400 }
|
|
84
|
-
);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Update preferences
|
|
88
|
-
const updatedSession = await updateAnonPreferences(anonId, preferences);
|
|
89
|
-
|
|
90
|
-
if (!updatedSession) {
|
|
91
|
-
return NextResponse.json(
|
|
92
|
-
{ success: false, error: 'Session not found' },
|
|
93
|
-
{ status: 404 }
|
|
94
|
-
);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
// Build response
|
|
98
|
-
const response = NextResponse.json({
|
|
99
|
-
success: true,
|
|
100
|
-
data: {
|
|
101
|
-
id: updatedSession.id,
|
|
102
|
-
preferences: updatedSession.preferences,
|
|
103
|
-
},
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
// Ensure cookie is set
|
|
107
|
-
response.cookies.set(ANON_COOKIE_NAME, anonId, {
|
|
108
|
-
httpOnly: true,
|
|
109
|
-
secure: process.env.NODE_ENV === 'production',
|
|
110
|
-
sameSite: 'lax',
|
|
111
|
-
maxAge: COOKIE_MAX_AGE,
|
|
112
|
-
path: '/',
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
return response;
|
|
116
|
-
} catch (error) {
|
|
117
|
-
console.error('[ANON-PREFERENCES] POST error:', error);
|
|
118
|
-
return NextResponse.json(
|
|
119
|
-
{ success: false, error: 'Failed to update preferences' },
|
|
120
|
-
{ status: 500 }
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Anonymous Session Preferences API Handler
|
|
3
|
+
*
|
|
4
|
+
* GET /api/anon/preferences - Get current preferences
|
|
5
|
+
* POST /api/anon/preferences - Update preferences
|
|
6
|
+
*
|
|
7
|
+
* Sets a cookie to track anonymous visitors and stores preferences in Redis.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
11
|
+
import { cookies } from 'next/headers';
|
|
12
|
+
import {
|
|
13
|
+
getOrCreateAnonSession,
|
|
14
|
+
updateAnonPreferences,
|
|
15
|
+
ANON_COOKIE_NAME,
|
|
16
|
+
AnonSessionPreferences,
|
|
17
|
+
} from '../../lib/anon-session';
|
|
18
|
+
|
|
19
|
+
const COOKIE_MAX_AGE = 90 * 24 * 60 * 60; // 90 days in seconds
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* GET handler - retrieves anonymous session preferences
|
|
23
|
+
*/
|
|
24
|
+
export async function GET(request: NextRequest) {
|
|
25
|
+
try {
|
|
26
|
+
const cookieStore = await cookies();
|
|
27
|
+
let anonId = cookieStore.get(ANON_COOKIE_NAME)?.value;
|
|
28
|
+
|
|
29
|
+
// Get or create session
|
|
30
|
+
const session = await getOrCreateAnonSession(anonId);
|
|
31
|
+
|
|
32
|
+
// Build response
|
|
33
|
+
const response = NextResponse.json({
|
|
34
|
+
success: true,
|
|
35
|
+
data: {
|
|
36
|
+
id: session.id,
|
|
37
|
+
preferences: session.preferences,
|
|
38
|
+
metrics: session.metrics,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Set cookie if it's a new session
|
|
43
|
+
if (!anonId || anonId !== session.id) {
|
|
44
|
+
response.cookies.set(ANON_COOKIE_NAME, session.id, {
|
|
45
|
+
httpOnly: true,
|
|
46
|
+
secure: process.env.NODE_ENV === 'production',
|
|
47
|
+
sameSite: 'lax',
|
|
48
|
+
maxAge: COOKIE_MAX_AGE,
|
|
49
|
+
path: '/',
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return response;
|
|
54
|
+
} catch (error) {
|
|
55
|
+
console.error('[ANON-PREFERENCES] GET error:', error);
|
|
56
|
+
return NextResponse.json(
|
|
57
|
+
{ success: false, error: 'Failed to get preferences' },
|
|
58
|
+
{ status: 500 }
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* POST handler - updates anonymous session preferences
|
|
65
|
+
*/
|
|
66
|
+
export async function POST(request: NextRequest) {
|
|
67
|
+
try {
|
|
68
|
+
const cookieStore = await cookies();
|
|
69
|
+
let anonId = cookieStore.get(ANON_COOKIE_NAME)?.value;
|
|
70
|
+
|
|
71
|
+
// Get or create session first
|
|
72
|
+
const session = await getOrCreateAnonSession(anonId);
|
|
73
|
+
anonId = session.id;
|
|
74
|
+
|
|
75
|
+
// Parse body for preferences to update
|
|
76
|
+
const body = await request.json();
|
|
77
|
+
const preferences: Partial<AnonSessionPreferences> = body.preferences || body;
|
|
78
|
+
|
|
79
|
+
// Validate preferences
|
|
80
|
+
if (typeof preferences !== 'object') {
|
|
81
|
+
return NextResponse.json(
|
|
82
|
+
{ success: false, error: 'Invalid preferences format' },
|
|
83
|
+
{ status: 400 }
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Update preferences
|
|
88
|
+
const updatedSession = await updateAnonPreferences(anonId, preferences);
|
|
89
|
+
|
|
90
|
+
if (!updatedSession) {
|
|
91
|
+
return NextResponse.json(
|
|
92
|
+
{ success: false, error: 'Session not found' },
|
|
93
|
+
{ status: 404 }
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Build response
|
|
98
|
+
const response = NextResponse.json({
|
|
99
|
+
success: true,
|
|
100
|
+
data: {
|
|
101
|
+
id: updatedSession.id,
|
|
102
|
+
preferences: updatedSession.preferences,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Ensure cookie is set
|
|
107
|
+
response.cookies.set(ANON_COOKIE_NAME, anonId, {
|
|
108
|
+
httpOnly: true,
|
|
109
|
+
secure: process.env.NODE_ENV === 'production',
|
|
110
|
+
sameSite: 'lax',
|
|
111
|
+
maxAge: COOKIE_MAX_AGE,
|
|
112
|
+
path: '/',
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
return response;
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.error('[ANON-PREFERENCES] POST error:', error);
|
|
118
|
+
return NextResponse.json(
|
|
119
|
+
{ success: false, error: 'Failed to update preferences' },
|
|
120
|
+
{ status: 500 }
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
-
import { ENV_CONFIG, API_ENDPOINTS } from '../../config/env';
|
|
3
|
-
import { logger } from '../../config/logger';
|
|
4
|
-
|
|
5
|
-
export async function GET(_req: NextRequest) {
|
|
6
|
-
try {
|
|
7
|
-
const url = `${ENV_CONFIG.IDP_URL}${API_ENDPOINTS.externalAuth.jwks}`;
|
|
8
|
-
const res = await fetch(url, { headers: { 'Accept': 'application/json' } });
|
|
9
|
-
const bodyText = await res.text();
|
|
10
|
-
try {
|
|
11
|
-
const json = JSON.parse(bodyText);
|
|
12
|
-
return NextResponse.json(json, { status: res.status });
|
|
13
|
-
} catch (e) {
|
|
14
|
-
logger.error('[AUTH_JWKS] Upstream returned non-JSON', { status: res.status, bodyText: bodyText?.slice(0, 200) });
|
|
15
|
-
return NextResponse.json({ error: 'Invalid JWKS response' }, { status: 502 });
|
|
16
|
-
}
|
|
17
|
-
} catch (error) {
|
|
18
|
-
return NextResponse.json({ error: 'Failed to fetch JWKS' }, { status: 502 });
|
|
19
|
-
}
|
|
20
|
-
}
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
import { ENV_CONFIG, API_ENDPOINTS } from '../../config/env';
|
|
3
|
+
import { logger } from '../../config/logger';
|
|
4
|
+
|
|
5
|
+
export async function GET(_req: NextRequest) {
|
|
6
|
+
try {
|
|
7
|
+
const url = `${ENV_CONFIG.IDP_URL}${API_ENDPOINTS.externalAuth.jwks}`;
|
|
8
|
+
const res = await fetch(url, { headers: { 'Accept': 'application/json' } });
|
|
9
|
+
const bodyText = await res.text();
|
|
10
|
+
try {
|
|
11
|
+
const json = JSON.parse(bodyText);
|
|
12
|
+
return NextResponse.json(json, { status: res.status });
|
|
13
|
+
} catch (e) {
|
|
14
|
+
logger.error('[AUTH_JWKS] Upstream returned non-JSON', { status: res.status, bodyText: bodyText?.slice(0, 200) });
|
|
15
|
+
return NextResponse.json({ error: 'Invalid JWKS response' }, { status: 502 });
|
|
16
|
+
}
|
|
17
|
+
} catch (error) {
|
|
18
|
+
return NextResponse.json({ error: 'Failed to fetch JWKS' }, { status: 502 });
|
|
19
|
+
}
|
|
20
|
+
}
|