@payez/next-mvp 3.9.0 → 4.0.0

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 (149) hide show
  1. package/dist/api/auth-handler.d.ts +1 -2
  2. package/dist/api/auth-handler.js +9 -9
  3. package/dist/api-handlers/account/change-password.js +110 -112
  4. package/dist/api-handlers/admin/analytics.d.ts +19 -20
  5. package/dist/api-handlers/admin/analytics.js +378 -379
  6. package/dist/api-handlers/admin/audit.d.ts +19 -20
  7. package/dist/api-handlers/admin/audit.js +213 -214
  8. package/dist/api-handlers/admin/index.d.ts +21 -22
  9. package/dist/api-handlers/admin/index.js +42 -43
  10. package/dist/api-handlers/admin/redis-sessions.d.ts +35 -36
  11. package/dist/api-handlers/admin/redis-sessions.js +203 -204
  12. package/dist/api-handlers/admin/sessions.d.ts +20 -21
  13. package/dist/api-handlers/admin/sessions.js +283 -284
  14. package/dist/api-handlers/admin/site-logs.d.ts +45 -46
  15. package/dist/api-handlers/admin/site-logs.js +317 -318
  16. package/dist/api-handlers/admin/stats.d.ts +20 -21
  17. package/dist/api-handlers/admin/stats.js +239 -240
  18. package/dist/api-handlers/admin/users.d.ts +19 -20
  19. package/dist/api-handlers/admin/users.js +221 -222
  20. package/dist/api-handlers/admin/vibe-data.d.ts +79 -80
  21. package/dist/api-handlers/admin/vibe-data.js +267 -268
  22. package/dist/api-handlers/auth/refresh.js +633 -635
  23. package/dist/api-handlers/auth/signout.js +186 -187
  24. package/dist/api-handlers/auth/status.js +4 -7
  25. package/dist/api-handlers/auth/update-session.d.ts +1 -1
  26. package/dist/api-handlers/auth/update-session.js +12 -14
  27. package/dist/api-handlers/auth/verify-code.d.ts +43 -43
  28. package/dist/api-handlers/auth/verify-code.js +90 -94
  29. package/dist/api-handlers/session/viability.js +114 -146
  30. package/dist/api-handlers/test/force-expire.js +59 -65
  31. package/dist/auth/auth-decision.js +182 -182
  32. package/dist/auth/better-auth.d.ts +3 -6
  33. package/dist/auth/better-auth.js +3 -6
  34. package/dist/auth/route-config.js +2 -2
  35. package/dist/auth/utils/token-utils.d.ts +83 -84
  36. package/dist/auth/utils/token-utils.js +218 -219
  37. package/dist/client/AuthContext.js +115 -112
  38. package/dist/client/better-auth-client.d.ts +1020 -961
  39. package/dist/client/better-auth-client.js +54 -7
  40. package/dist/client/fetch-with-auth.js +2 -2
  41. package/dist/components/SessionSync.js +121 -119
  42. package/dist/components/account/MobileNavDrawer.js +64 -64
  43. package/dist/components/account/UserAvatarMenu.js +91 -88
  44. package/dist/components/admin/VibeAdminLayout.js +71 -69
  45. package/dist/hooks/useAuth.js +9 -7
  46. package/dist/hooks/useAuthSettings.js +93 -93
  47. package/dist/hooks/useAvailableProviders.d.ts +43 -45
  48. package/dist/hooks/useAvailableProviders.js +112 -108
  49. package/dist/hooks/useSessionExpiration.d.ts +2 -3
  50. package/dist/hooks/useSessionExpiration.js +2 -2
  51. package/dist/hooks/useViabilitySession.js +3 -2
  52. package/dist/index.js +4 -6
  53. package/dist/lib/app-slug.d.ts +95 -95
  54. package/dist/lib/app-slug.js +172 -172
  55. package/dist/lib/standardized-client-api.js +10 -5
  56. package/dist/lib/startup-init.js +21 -25
  57. package/dist/lib/test-aware-get-token.js +86 -81
  58. package/dist/lib/token-lifecycle.d.ts +78 -52
  59. package/dist/lib/token-lifecycle.js +360 -398
  60. package/dist/pages/admin-login/page.js +73 -83
  61. package/dist/pages/client-admin/ClientSiteAdminPage.js +179 -177
  62. package/dist/pages/login/page.js +202 -211
  63. package/dist/pages/showcase/ShowcasePage.js +142 -140
  64. package/dist/pages/test-env/EmergencyLogoutPage.js +99 -98
  65. package/dist/pages/test-env/JwtInspectPage.js +116 -114
  66. package/dist/pages/test-env/RefreshTokenPage.js +4 -2
  67. package/dist/pages/test-env/TestEnvPage.js +51 -49
  68. package/dist/pages/verify-code/page.js +412 -408
  69. package/dist/routes/auth/logout.d.ts +31 -31
  70. package/dist/routes/auth/logout.js +98 -113
  71. package/dist/routes/auth/nextauth.d.ts +14 -11
  72. package/dist/routes/auth/nextauth.js +25 -57
  73. package/dist/routes/auth/session.js +157 -179
  74. package/dist/routes/auth/viability.js +190 -201
  75. package/dist/server/auth.d.ts +50 -0
  76. package/dist/server/auth.js +62 -0
  77. package/dist/stores/authStore.js +19 -23
  78. package/dist/utils/logout.js +5 -5
  79. package/package.json +1 -3
  80. package/src/api/auth-handler.ts +550 -549
  81. package/src/api-handlers/account/change-password.ts +5 -8
  82. package/src/api-handlers/admin/analytics.ts +4 -6
  83. package/src/api-handlers/admin/audit.ts +5 -7
  84. package/src/api-handlers/admin/index.ts +1 -2
  85. package/src/api-handlers/admin/redis-sessions.ts +6 -8
  86. package/src/api-handlers/admin/sessions.ts +5 -7
  87. package/src/api-handlers/admin/site-logs.ts +8 -10
  88. package/src/api-handlers/admin/stats.ts +4 -6
  89. package/src/api-handlers/admin/users.ts +5 -7
  90. package/src/api-handlers/admin/vibe-data.ts +10 -12
  91. package/src/api-handlers/auth/refresh.ts +5 -7
  92. package/src/api-handlers/auth/signout.ts +5 -6
  93. package/src/api-handlers/auth/status.ts +4 -7
  94. package/src/api-handlers/auth/update-session.ts +123 -125
  95. package/src/api-handlers/auth/verify-code.ts +9 -13
  96. package/src/api-handlers/session/viability.ts +10 -47
  97. package/src/api-handlers/test/force-expire.ts +4 -11
  98. package/src/auth/auth-decision.ts +1 -1
  99. package/src/auth/better-auth.ts +138 -141
  100. package/src/auth/route-config.ts +219 -219
  101. package/src/auth/utils/token-utils.ts +0 -1
  102. package/src/client/AuthContext.tsx +6 -2
  103. package/src/client/better-auth-client.ts +54 -7
  104. package/src/client/fetch-with-auth.ts +47 -47
  105. package/src/components/SessionSync.tsx +6 -5
  106. package/src/components/account/MobileNavDrawer.tsx +3 -3
  107. package/src/components/account/UserAvatarMenu.tsx +6 -3
  108. package/src/components/admin/VibeAdminLayout.tsx +4 -2
  109. package/src/config/logger.ts +1 -1
  110. package/src/hooks/useAuth.ts +117 -115
  111. package/src/hooks/useAuthSettings.ts +2 -2
  112. package/src/hooks/useAvailableProviders.ts +9 -5
  113. package/src/hooks/useSessionExpiration.ts +101 -102
  114. package/src/hooks/useViabilitySession.ts +336 -335
  115. package/src/index.ts +60 -63
  116. package/src/lib/api-handler.ts +0 -1
  117. package/src/lib/app-slug.ts +6 -6
  118. package/src/lib/standardized-client-api.ts +901 -895
  119. package/src/lib/startup-init.ts +243 -247
  120. package/src/lib/test-aware-get-token.ts +22 -12
  121. package/src/lib/token-lifecycle.ts +12 -53
  122. package/src/pages/admin-login/page.tsx +9 -17
  123. package/src/pages/client-admin/ClientSiteAdminPage.tsx +4 -2
  124. package/src/pages/login/page.tsx +21 -28
  125. package/src/pages/showcase/ShowcasePage.tsx +4 -2
  126. package/src/pages/test-env/EmergencyLogoutPage.tsx +7 -6
  127. package/src/pages/test-env/JwtInspectPage.tsx +5 -3
  128. package/src/pages/test-env/RefreshTokenPage.tsx +157 -155
  129. package/src/pages/test-env/TestEnvPage.tsx +4 -2
  130. package/src/pages/verify-code/page.tsx +10 -6
  131. package/src/routes/auth/logout.ts +7 -25
  132. package/src/routes/auth/nextauth.ts +45 -71
  133. package/src/routes/auth/session.ts +25 -50
  134. package/src/routes/auth/viability.ts +7 -19
  135. package/src/server/auth.ts +60 -0
  136. package/src/stores/authStore.ts +1899 -1904
  137. package/src/utils/logout.ts +30 -30
  138. package/src/auth/auth-options.ts +0 -237
  139. package/src/auth/callbacks/index.ts +0 -7
  140. package/src/auth/callbacks/jwt.ts +0 -382
  141. package/src/auth/callbacks/session.ts +0 -243
  142. package/src/auth/callbacks/signin.ts +0 -56
  143. package/src/auth/events/index.ts +0 -5
  144. package/src/auth/events/signout.ts +0 -33
  145. package/src/auth/providers/credentials.ts +0 -256
  146. package/src/auth/providers/index.ts +0 -6
  147. package/src/auth/providers/oauth.ts +0 -114
  148. package/src/lib/nextauth-secret.ts +0 -121
  149. package/src/types/next-auth.d.ts +0 -15
@@ -1,179 +1,157 @@
1
- "use strict";
2
- /**
3
- * Ready-to-Use Session Management Route
4
- *
5
- * Provides pre-configured session handlers for checking and updating session state.
6
- *
7
- * @example
8
- * ```typescript
9
- * // app/api/auth/session/route.ts
10
- * export { GET, POST } from '@payez/next-mvp/routes/auth/session';
11
- * ```
12
- *
13
- * @version 2.0.0
14
- * @since auth-ready-v2
15
- */
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.GET = GET;
18
- exports.POST = POST;
19
- const server_1 = require("next/server");
20
- const jwt_1 = require("next-auth/jwt");
21
- const session_store_1 = require("../../lib/session-store");
22
- const app_slug_1 = require("../../lib/app-slug");
23
- const idp_client_config_1 = require("../../lib/idp-client-config");
24
- /**
25
- * Get NextAuth secret from IDP config (cached).
26
- * NEVER use process.env.NEXTAUTH_SECRET - it's always loaded from IDP.
27
- */
28
- async function getNextAuthSecret() {
29
- const config = await (0, idp_client_config_1.getIDPClientConfig)();
30
- return config.nextAuthSecret || '';
31
- }
32
- /**
33
- * GET /api/auth/session - Check current session status
34
- *
35
- * Returns the current session information including:
36
- * - User details
37
- * - Token expiry status
38
- * - Session validity
39
- */
40
- async function GET(req) {
41
- try {
42
- const secret = await getNextAuthSecret();
43
- const cookieName = (0, app_slug_1.getJwtCookieName)();
44
- // Debug logging
45
- const cookieValue = req.cookies.get(cookieName)?.value;
46
- console.log('[SESSION_ROUTE] GET called:', {
47
- cookieName,
48
- hasCookie: !!cookieValue,
49
- cookieLength: cookieValue?.length || 0,
50
- secretLength: secret?.length || 0,
51
- });
52
- const token = await (0, jwt_1.getToken)({ req, secret, cookieName });
53
- if (!token) {
54
- console.warn('[SESSION_ROUTE] getToken returned null');
55
- // MUST return empty {} NextAuth's useSession() treats any non-empty
56
- // response object as "authenticated", causing redirect loops on login page.
57
- return server_1.NextResponse.json({});
58
- }
59
- // Support both field names: sessionToken (auth.ts JWT) and redisSessionId (legacy)
60
- const redisSessionId = token.sessionToken || token.redisSessionId;
61
- console.log('[SESSION_ROUTE] Token found:', {
62
- sub: token.sub,
63
- email: token.email,
64
- name: token.name,
65
- hasExp: !!token.exp,
66
- redisSessionId: redisSessionId ? redisSessionId.substring(0, 8) + '...' : 'MISSING',
67
- });
68
- // Fetch full session data from Redis
69
- const session = redisSessionId ? await (0, session_store_1.getSession)(redisSessionId) : null;
70
- console.log('[SESSION_ROUTE] Redis session:', {
71
- found: !!session,
72
- userId: session?.userId,
73
- roles: session?.roles,
74
- hasAccessToken: !!session?.idpAccessToken,
75
- });
76
- // Return NextAuth-compatible session format with Redis data
77
- // useSession() expects: { user: {...}, expires: "..." }
78
- // We enrich with all session data from Redis
79
- return server_1.NextResponse.json({
80
- user: {
81
- id: session?.userId || token.sub,
82
- email: session?.email || token.email,
83
- name: session?.name || token.name,
84
- image: token.picture || null,
85
- // Redis session data
86
- roles: session?.roles || [],
87
- twoFactorSessionVerified: session?.mfaVerified || false,
88
- requiresTwoFactor: !session?.mfaVerified,
89
- authenticationMethods: session?.authenticationMethods,
90
- authenticationLevel: session?.authenticationLevel,
91
- mfaCompletedAt: session?.mfaCompletedAt,
92
- mfaExpiresAt: session?.mfaExpiresAt,
93
- mfaValidityHours: session?.mfaValidityHours,
94
- oauthProvider: session?.oauthProvider,
95
- idpClientId: session?.idpClientId,
96
- merchantId: session?.merchantId,
97
- },
98
- // Session tokens
99
- sessionToken: redisSessionId,
100
- accessToken: session?.idpAccessToken,
101
- refreshToken: session?.idpRefreshToken,
102
- accessTokenExpires: session?.idpAccessTokenExpires,
103
- expires: token.exp ? new Date(token.exp * 1000).toISOString() : new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
104
- });
105
- }
106
- catch (error) {
107
- console.error('[SESSION_ROUTE] Error checking session:', error);
108
- return server_1.NextResponse.json({
109
- error: 'Failed to check session',
110
- details: error instanceof Error ? error.message : 'Unknown error'
111
- }, { status: 500 });
112
- }
113
- }
114
- /**
115
- * POST /api/auth/session - Update session data
116
- *
117
- * Allows updating session metadata (not tokens).
118
- * Token refresh should use the /api/auth/refresh endpoint.
119
- *
120
- * Body:
121
- * - metadata: object - Custom metadata to store in session
122
- */
123
- async function POST(req) {
124
- try {
125
- const secret = await getNextAuthSecret();
126
- const token = await (0, jwt_1.getToken)({ req, secret, cookieName: (0, app_slug_1.getJwtCookieName)() });
127
- if (!token) {
128
- return server_1.NextResponse.json({
129
- error: 'No session found',
130
- code: 'UNAUTHORIZED'
131
- }, { status: 401 });
132
- }
133
- // Support both field names: sessionToken (auth.ts JWT) and redisSessionId (legacy)
134
- const sessionToken = token.sessionToken || token.redisSessionId;
135
- if (!sessionToken) {
136
- return server_1.NextResponse.json({
137
- error: 'Invalid session',
138
- code: 'INVALID_SESSION'
139
- }, { status: 400 });
140
- }
141
- const body = await req.json();
142
- const { metadata, access_token, refresh_token, twoFactorComplete, twoFactorMethod } = body;
143
- // Get current session
144
- const session = await (0, session_store_1.getSession)(sessionToken);
145
- if (!session) {
146
- return server_1.NextResponse.json({
147
- error: 'Session not found',
148
- code: 'SESSION_NOT_FOUND'
149
- }, { status: 404 });
150
- }
151
- // Update session with new data
152
- const updatedSession = {
153
- ...session,
154
- ...(access_token ? { accessToken: access_token } : {}),
155
- ...(refresh_token ? { refreshToken: refresh_token } : {}),
156
- ...(typeof twoFactorComplete === 'boolean' ? { twoFactorComplete } : {}),
157
- ...(twoFactorMethod ? { twoFactorMethod } : {}),
158
- ...(metadata ? {
159
- metadata: {
160
- ...(session.metadata || {}),
161
- ...metadata,
162
- updatedAt: new Date().toISOString()
163
- }
164
- } : {})
165
- };
166
- await (0, session_store_1.updateSession)(sessionToken, updatedSession);
167
- return server_1.NextResponse.json({
168
- success: true,
169
- message: 'Session updated successfully'
170
- });
171
- }
172
- catch (error) {
173
- console.error('[SESSION_ROUTE] Error updating session:', error);
174
- return server_1.NextResponse.json({
175
- error: 'Failed to update session',
176
- details: error instanceof Error ? error.message : 'Unknown error'
177
- }, { status: 500 });
178
- }
179
- }
1
+ "use strict";
2
+ /**
3
+ * Ready-to-Use Session Management Route
4
+ *
5
+ * Provides pre-configured session handlers for checking and updating session state.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // app/api/auth/session/route.ts
10
+ * export { GET, POST } from '@payez/next-mvp/routes/auth/session';
11
+ * ```
12
+ *
13
+ * @version 2.0.0
14
+ * @since auth-ready-v2
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.GET = GET;
18
+ exports.POST = POST;
19
+ const server_1 = require("next/server");
20
+ const auth_1 = require("../../server/auth");
21
+ const session_store_1 = require("../../lib/session-store");
22
+ /**
23
+ * GET /api/auth/session - Check current session status
24
+ *
25
+ * Returns the current session information including:
26
+ * - User details
27
+ * - Token expiry status
28
+ * - Session validity
29
+ */
30
+ async function GET(req) {
31
+ try {
32
+ const authSession = await (0, auth_1.getSession)(req);
33
+ if (!authSession) {
34
+ console.warn('[SESSION_ROUTE] Better Auth session not found');
35
+ // MUST return empty {} useSession() treats any non-empty
36
+ // response object as "authenticated", causing redirect loops on login page.
37
+ return server_1.NextResponse.json({});
38
+ }
39
+ const redisSessionId = authSession.session?.token;
40
+ console.log('[SESSION_ROUTE] Session found:', {
41
+ userId: authSession.user?.id,
42
+ email: authSession.user?.email,
43
+ name: authSession.user?.name,
44
+ redisSessionId: redisSessionId ? redisSessionId.substring(0, 8) + '...' : 'MISSING',
45
+ });
46
+ // Fetch full session data from Redis
47
+ const session = redisSessionId ? await (0, session_store_1.getSession)(redisSessionId) : null;
48
+ console.log('[SESSION_ROUTE] Redis session:', {
49
+ found: !!session,
50
+ userId: session?.userId,
51
+ roles: session?.roles,
52
+ hasAccessToken: !!session?.idpAccessToken,
53
+ });
54
+ // Return session format with Redis data
55
+ // useSession() expects: { user: {...}, expires: "..." }
56
+ // We enrich with all session data from Redis
57
+ return server_1.NextResponse.json({
58
+ user: {
59
+ id: session?.userId || authSession.user?.id,
60
+ email: session?.email || authSession.user?.email,
61
+ name: session?.name || authSession.user?.name,
62
+ image: authSession.user?.image || null,
63
+ // Redis session data
64
+ roles: session?.roles || [],
65
+ twoFactorSessionVerified: session?.mfaVerified || false,
66
+ requiresTwoFactor: !session?.mfaVerified,
67
+ authenticationMethods: session?.authenticationMethods,
68
+ authenticationLevel: session?.authenticationLevel,
69
+ mfaCompletedAt: session?.mfaCompletedAt,
70
+ mfaExpiresAt: session?.mfaExpiresAt,
71
+ mfaValidityHours: session?.mfaValidityHours,
72
+ oauthProvider: session?.oauthProvider,
73
+ idpClientId: session?.idpClientId,
74
+ merchantId: session?.merchantId,
75
+ },
76
+ // Session tokens
77
+ sessionToken: redisSessionId,
78
+ accessToken: session?.idpAccessToken,
79
+ refreshToken: session?.idpRefreshToken,
80
+ accessTokenExpires: session?.idpAccessTokenExpires,
81
+ expires: authSession.session?.expiresAt
82
+ ? new Date(authSession.session.expiresAt).toISOString()
83
+ : new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(),
84
+ });
85
+ }
86
+ catch (error) {
87
+ console.error('[SESSION_ROUTE] Error checking session:', error);
88
+ return server_1.NextResponse.json({
89
+ error: 'Failed to check session',
90
+ details: error instanceof Error ? error.message : 'Unknown error'
91
+ }, { status: 500 });
92
+ }
93
+ }
94
+ /**
95
+ * POST /api/auth/session - Update session data
96
+ *
97
+ * Allows updating session metadata (not tokens).
98
+ * Token refresh should use the /api/auth/refresh endpoint.
99
+ *
100
+ * Body:
101
+ * - metadata: object - Custom metadata to store in session
102
+ */
103
+ async function POST(req) {
104
+ try {
105
+ const authSession = await (0, auth_1.getSession)(req);
106
+ if (!authSession) {
107
+ return server_1.NextResponse.json({
108
+ error: 'No session found',
109
+ code: 'UNAUTHORIZED'
110
+ }, { status: 401 });
111
+ }
112
+ const sessionToken = authSession.session?.token;
113
+ if (!sessionToken) {
114
+ return server_1.NextResponse.json({
115
+ error: 'Invalid session',
116
+ code: 'INVALID_SESSION'
117
+ }, { status: 400 });
118
+ }
119
+ const body = await req.json();
120
+ const { metadata, access_token, refresh_token, twoFactorComplete, twoFactorMethod } = body;
121
+ // Get current session from Redis
122
+ const session = await (0, session_store_1.getSession)(sessionToken);
123
+ if (!session) {
124
+ return server_1.NextResponse.json({
125
+ error: 'Session not found',
126
+ code: 'SESSION_NOT_FOUND'
127
+ }, { status: 404 });
128
+ }
129
+ // Update session with new data
130
+ const updatedSession = {
131
+ ...session,
132
+ ...(access_token ? { accessToken: access_token } : {}),
133
+ ...(refresh_token ? { refreshToken: refresh_token } : {}),
134
+ ...(typeof twoFactorComplete === 'boolean' ? { twoFactorComplete } : {}),
135
+ ...(twoFactorMethod ? { twoFactorMethod } : {}),
136
+ ...(metadata ? {
137
+ metadata: {
138
+ ...(session.metadata || {}),
139
+ ...metadata,
140
+ updatedAt: new Date().toISOString()
141
+ }
142
+ } : {})
143
+ };
144
+ await (0, session_store_1.updateSession)(sessionToken, updatedSession);
145
+ return server_1.NextResponse.json({
146
+ success: true,
147
+ message: 'Session updated successfully'
148
+ });
149
+ }
150
+ catch (error) {
151
+ console.error('[SESSION_ROUTE] Error updating session:', error);
152
+ return server_1.NextResponse.json({
153
+ error: 'Failed to update session',
154
+ details: error instanceof Error ? error.message : 'Unknown error'
155
+ }, { status: 500 });
156
+ }
157
+ }