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