@payez/next-mvp 4.1.11 → 4.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/api-handlers/auth/refresh.js +15 -38
  2. package/dist/auth/better-auth.js +12 -33
  3. package/dist/client/better-auth-client.d.ts +14 -2
  4. package/dist/lib/ensure-fresh-access-token.js +8 -42
  5. package/dist/lib/session-store.d.ts +0 -1
  6. package/dist/lib/session-store.js +29 -33
  7. package/dist/lib/startup-init.js +19 -19
  8. package/dist/lib/token-lifecycle.d.ts +0 -2
  9. package/dist/lib/token-lifecycle.js +3 -21
  10. package/package.json +4 -3
  11. package/scripts/check-internal-url-usage.sh +73 -73
  12. package/src/api/index.ts +17 -17
  13. package/src/api-handlers/account/masked-info.ts +45 -45
  14. package/src/api-handlers/account/profile.ts +80 -80
  15. package/src/api-handlers/account/recovery/initiate.ts +23 -23
  16. package/src/api-handlers/account/recovery/send-code.ts +25 -25
  17. package/src/api-handlers/account/recovery/verify-code.ts +25 -25
  18. package/src/api-handlers/account/reset-password.ts +23 -23
  19. package/src/api-handlers/account/send-code.ts +76 -76
  20. package/src/api-handlers/account/validate-password.ts +118 -118
  21. package/src/api-handlers/admin/stats.ts +249 -249
  22. package/src/api-handlers/anon/preferences.ts +123 -123
  23. package/src/api-handlers/auth/jwks.ts +20 -20
  24. package/src/api-handlers/auth/login.ts +240 -240
  25. package/src/api-handlers/auth/refresh.ts +15 -38
  26. package/src/api-handlers/auth/validate.ts +43 -43
  27. package/src/api-handlers/session/viability.ts +142 -142
  28. package/src/auth/better-auth.ts +450 -467
  29. package/src/auth/unauthenticated-routes.ts +2 -2
  30. package/src/client/better-auth-client.ts +70 -70
  31. package/src/client/fetchWithSession.ts +21 -21
  32. package/src/client/index.ts +13 -13
  33. package/src/client/useAnonSession.ts +131 -131
  34. package/src/components/admin/VibeAdminContext.tsx +87 -87
  35. package/src/config/logging-config.ts +82 -82
  36. package/src/config/unauthenticated-routes.ts +19 -19
  37. package/src/edge/internal-api-url.ts +65 -65
  38. package/src/edge/middleware.ts +42 -42
  39. package/src/hooks/useProfile.ts +75 -75
  40. package/src/lib/anon-session.ts +213 -213
  41. package/src/lib/auth-secret.ts +137 -137
  42. package/src/lib/demo-mode.ts +17 -17
  43. package/src/lib/ensure-fresh-access-token.ts +8 -42
  44. package/src/lib/idp-client-config.ts +559 -559
  45. package/src/lib/idp-fetch.ts +126 -126
  46. package/src/lib/internal-api.ts +171 -171
  47. package/src/lib/jwt-decode-client.ts +45 -45
  48. package/src/lib/rate-limit-service.ts +9 -9
  49. package/src/lib/redis.ts +26 -26
  50. package/src/lib/refresh-token-validator.ts +64 -64
  51. package/src/lib/secret-validation.ts +8 -8
  52. package/src/lib/session-store.ts +692 -695
  53. package/src/lib/session.ts +34 -34
  54. package/src/lib/startup-init.ts +251 -251
  55. package/src/lib/token-expiry.ts +40 -40
  56. package/src/lib/token-lifecycle.ts +470 -497
  57. package/src/lib/types/api-responses.ts +336 -336
  58. package/src/middleware/auth-decision.ts +43 -43
  59. package/src/models/DecodedAccessToken.ts +16 -16
  60. package/src/models/SessionModel.ts +264 -264
  61. package/src/pages/admin-roles/index.ts +9 -9
  62. package/src/pages/security/EnhancedSecurityPage.tsx +9 -9
  63. package/src/routes/account/index.ts +31 -31
  64. package/src/routes/account/masked-info.ts +36 -36
  65. package/src/routes/account/send-code.ts +39 -39
  66. package/src/routes/account/verify-email.ts +40 -40
  67. package/src/routes/account/verify-sms.ts +40 -40
  68. package/src/routes/auth/index.ts +22 -22
  69. package/src/routes/auth/refresh.ts +48 -48
  70. package/src/routes/auth/session.ts +166 -166
  71. package/src/routes/index.ts +17 -17
  72. package/src/routes/session/index.ts +7 -7
  73. package/src/routes/session/refresh-viability.ts +17 -17
  74. package/src/server/auth.ts +373 -373
  75. package/src/server/decode-session.ts +202 -202
  76. package/src/services/signalrActivityService.ts +258 -258
  77. package/src/theme/ThemeProvider.tsx +39 -39
  78. package/src/theme/default.ts +33 -33
  79. package/src/theme/index.ts +31 -31
  80. package/src/theme/types.ts +69 -69
  81. package/src/theme/useTheme.ts +57 -57
  82. package/src/theme/utils.ts +40 -40
  83. package/src/types/api.ts +12 -12
  84. package/src/types/auth.d.ts +23 -23
  85. package/src/types/auth.ts +22 -22
  86. package/src/types/logging.ts +11 -11
  87. package/src/types/recovery.ts +54 -54
  88. package/src/utils/api.ts +353 -353
  89. package/src/utils/circuitBreaker.ts +40 -40
  90. package/src/utils/error-message.ts +108 -108
  91. 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
+ }