@payez/next-mvp 4.0.0 → 4.0.2

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 (81) hide show
  1. package/dist/api-handlers/account/change-password.js +110 -110
  2. package/dist/api-handlers/admin/analytics.d.ts +19 -19
  3. package/dist/api-handlers/admin/analytics.js +378 -378
  4. package/dist/api-handlers/admin/audit.d.ts +19 -19
  5. package/dist/api-handlers/admin/audit.js +213 -213
  6. package/dist/api-handlers/admin/index.d.ts +21 -21
  7. package/dist/api-handlers/admin/index.js +42 -42
  8. package/dist/api-handlers/admin/redis-sessions.d.ts +35 -35
  9. package/dist/api-handlers/admin/redis-sessions.js +203 -203
  10. package/dist/api-handlers/admin/sessions.d.ts +20 -20
  11. package/dist/api-handlers/admin/sessions.js +283 -283
  12. package/dist/api-handlers/admin/site-logs.d.ts +45 -45
  13. package/dist/api-handlers/admin/site-logs.js +317 -317
  14. package/dist/api-handlers/admin/stats.d.ts +20 -20
  15. package/dist/api-handlers/admin/stats.js +239 -239
  16. package/dist/api-handlers/admin/users.d.ts +19 -19
  17. package/dist/api-handlers/admin/users.js +221 -221
  18. package/dist/api-handlers/admin/vibe-data.d.ts +79 -79
  19. package/dist/api-handlers/admin/vibe-data.js +267 -267
  20. package/dist/api-handlers/auth/refresh.js +633 -633
  21. package/dist/api-handlers/auth/signout.js +186 -186
  22. package/dist/api-handlers/auth/verify-code.d.ts +43 -43
  23. package/dist/api-handlers/auth/verify-code.js +90 -90
  24. package/dist/api-handlers/session/viability.js +114 -114
  25. package/dist/api-handlers/test/force-expire.js +59 -59
  26. package/dist/auth/auth-decision.js +182 -182
  27. package/dist/auth/utils/token-utils.d.ts +83 -83
  28. package/dist/auth/utils/token-utils.js +218 -218
  29. package/dist/client/AuthContext.js +115 -115
  30. package/dist/client/better-auth-client.d.ts +1020 -1020
  31. package/dist/components/SessionSync.js +121 -121
  32. package/dist/components/account/MobileNavDrawer.js +64 -64
  33. package/dist/components/account/UserAvatarMenu.js +91 -91
  34. package/dist/components/admin/VibeAdminLayout.js +71 -71
  35. package/dist/hooks/useAuthSettings.js +93 -93
  36. package/dist/hooks/useAvailableProviders.d.ts +43 -43
  37. package/dist/hooks/useAvailableProviders.js +112 -112
  38. package/dist/lib/app-slug.d.ts +95 -95
  39. package/dist/lib/app-slug.js +172 -172
  40. package/dist/lib/test-aware-get-token.js +86 -86
  41. package/dist/lib/token-lifecycle.d.ts +78 -78
  42. package/dist/lib/token-lifecycle.js +360 -360
  43. package/dist/pages/admin-login/page.js +73 -73
  44. package/dist/pages/client-admin/ClientSiteAdminPage.js +179 -179
  45. package/dist/pages/login/page.js +202 -202
  46. package/dist/pages/showcase/ShowcasePage.js +142 -142
  47. package/dist/pages/test-env/EmergencyLogoutPage.js +99 -99
  48. package/dist/pages/test-env/JwtInspectPage.js +116 -116
  49. package/dist/pages/test-env/TestEnvPage.js +51 -51
  50. package/dist/pages/verify-code/page.js +412 -412
  51. package/dist/routes/auth/logout.d.ts +31 -31
  52. package/dist/routes/auth/logout.js +98 -98
  53. package/dist/routes/auth/session.js +157 -157
  54. package/dist/routes/auth/viability.js +190 -190
  55. package/package.json +6 -16
  56. package/dist/auth/auth-options.d.ts +0 -57
  57. package/dist/auth/auth-options.js +0 -213
  58. package/dist/auth/callbacks/index.d.ts +0 -6
  59. package/dist/auth/callbacks/index.js +0 -12
  60. package/dist/auth/callbacks/jwt.d.ts +0 -45
  61. package/dist/auth/callbacks/jwt.js +0 -305
  62. package/dist/auth/callbacks/session.d.ts +0 -60
  63. package/dist/auth/callbacks/session.js +0 -170
  64. package/dist/auth/callbacks/signin.d.ts +0 -23
  65. package/dist/auth/callbacks/signin.js +0 -44
  66. package/dist/auth/events/index.d.ts +0 -4
  67. package/dist/auth/events/index.js +0 -8
  68. package/dist/auth/events/signout.d.ts +0 -17
  69. package/dist/auth/events/signout.js +0 -32
  70. package/dist/auth/providers/credentials.d.ts +0 -32
  71. package/dist/auth/providers/credentials.js +0 -223
  72. package/dist/auth/providers/index.d.ts +0 -5
  73. package/dist/auth/providers/index.js +0 -21
  74. package/dist/auth/providers/oauth.d.ts +0 -26
  75. package/dist/auth/providers/oauth.js +0 -105
  76. package/dist/lib/nextauth-secret.d.ts +0 -10
  77. package/dist/lib/nextauth-secret.js +0 -100
  78. package/dist/pages/profile/profile-patch.d.ts +0 -1
  79. package/dist/pages/profile/profile-patch.js +0 -281
  80. package/dist/pages/security/security-patch.d.ts +0 -1
  81. package/dist/pages/security/security-patch.js +0 -302
@@ -1,86 +1,86 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.getTokenTestAware = getTokenTestAware;
37
- const logger_1 = require("../config/logger");
38
- const auth_1 = require("../server/auth");
39
- const app_slug_1 = require("./app-slug");
40
- async function getTokenTestAware(req) {
41
- if (process.env.TEST_MODE === 'true') {
42
- try {
43
- let secret = process.env.NEXTAUTH_SECRET;
44
- if (!secret || secret.trim() === '') {
45
- const { getIDPClientConfig } = await Promise.resolve().then(() => __importStar(require('./idp-client-config')));
46
- const idpConfig = await getIDPClientConfig();
47
- secret = idpConfig.nextAuthSecret;
48
- }
49
- // Use app-slug prefixed cookie name
50
- const cookieName = (0, app_slug_1.getSessionCookieName)();
51
- const cookies = req.headers.get('cookie');
52
- if (!cookies) {
53
- logger_1.logger.debug('[GET_TOKEN] No cookies in request');
54
- return null;
55
- }
56
- const cookieValue = cookies.split(';').find(c => c.trim().startsWith(`${cookieName}=`))?.split('=')[1];
57
- if (!cookieValue) {
58
- logger_1.logger.debug('[GET_TOKEN] Session token cookie not found');
59
- return null;
60
- }
61
- const { jwtVerify } = await Promise.resolve().then(() => __importStar(require('jose')));
62
- const secretKey = new TextEncoder().encode(secret);
63
- const { payload } = await jwtVerify(cookieValue, secretKey);
64
- logger_1.logger.debug('[GET_TOKEN] TEST_MODE token decoded:', { hasPayload: !!payload, redisSessionId: payload.redisSessionId, sub: payload.sub });
65
- return payload;
66
- }
67
- catch (error) {
68
- logger_1.logger.error('[GET_TOKEN] TEST_MODE token decode error:', { error: error instanceof Error ? error.message : String(error) });
69
- return null;
70
- }
71
- }
72
- // Production path: use Better Auth session
73
- const session = await (0, auth_1.getSession)(req);
74
- if (!session)
75
- return null;
76
- // Return a token-like object for backward compatibility with callers
77
- // that access token.sub, token.email, token.sessionToken, token.roles, etc.
78
- return {
79
- sub: session.user?.id,
80
- email: session.user?.email,
81
- name: session.user?.name,
82
- sessionToken: session.session?.token,
83
- roles: session.user?.roles || [],
84
- ...(session.user || {}),
85
- };
86
- }
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getTokenTestAware = getTokenTestAware;
37
+ const logger_1 = require("../config/logger");
38
+ const auth_1 = require("../server/auth");
39
+ const app_slug_1 = require("./app-slug");
40
+ async function getTokenTestAware(req) {
41
+ if (process.env.TEST_MODE === 'true') {
42
+ try {
43
+ let secret = process.env.NEXTAUTH_SECRET;
44
+ if (!secret || secret.trim() === '') {
45
+ const { getIDPClientConfig } = await Promise.resolve().then(() => __importStar(require('./idp-client-config')));
46
+ const idpConfig = await getIDPClientConfig();
47
+ secret = idpConfig.nextAuthSecret;
48
+ }
49
+ // Use app-slug prefixed cookie name
50
+ const cookieName = (0, app_slug_1.getSessionCookieName)();
51
+ const cookies = req.headers.get('cookie');
52
+ if (!cookies) {
53
+ logger_1.logger.debug('[GET_TOKEN] No cookies in request');
54
+ return null;
55
+ }
56
+ const cookieValue = cookies.split(';').find(c => c.trim().startsWith(`${cookieName}=`))?.split('=')[1];
57
+ if (!cookieValue) {
58
+ logger_1.logger.debug('[GET_TOKEN] Session token cookie not found');
59
+ return null;
60
+ }
61
+ const { jwtVerify } = await Promise.resolve().then(() => __importStar(require('jose')));
62
+ const secretKey = new TextEncoder().encode(secret);
63
+ const { payload } = await jwtVerify(cookieValue, secretKey);
64
+ logger_1.logger.debug('[GET_TOKEN] TEST_MODE token decoded:', { hasPayload: !!payload, redisSessionId: payload.redisSessionId, sub: payload.sub });
65
+ return payload;
66
+ }
67
+ catch (error) {
68
+ logger_1.logger.error('[GET_TOKEN] TEST_MODE token decode error:', { error: error instanceof Error ? error.message : String(error) });
69
+ return null;
70
+ }
71
+ }
72
+ // Production path: use Better Auth session
73
+ const session = await (0, auth_1.getSession)(req);
74
+ if (!session)
75
+ return null;
76
+ // Return a token-like object for backward compatibility with callers
77
+ // that access token.sub, token.email, token.sessionToken, token.roles, etc.
78
+ return {
79
+ sub: session.user?.id,
80
+ email: session.user?.email,
81
+ name: session.user?.name,
82
+ sessionToken: session.session?.token,
83
+ roles: session.user?.roles || [],
84
+ ...(session.user || {}),
85
+ };
86
+ }
@@ -1,78 +1,78 @@
1
- /**
2
- * Token Lifecycle Management for @payez/next-mvp
3
- *
4
- * Ensures tokens are fresh before making API calls.
5
- * Checks expiration and triggers refresh if needed.
6
- *
7
- * Pattern: Check first, refresh if needed, fail gracefully if refresh fails.
8
- *
9
- * HANDLES CONCURRENT REFRESH: When multiple API calls arrive simultaneously
10
- * with expired tokens, only one will actually perform the refresh. Others
11
- * receive 409 (conflict) and wait for the refresh to complete, then use
12
- * the freshly refreshed tokens.
13
- *
14
- * REQUIRED: Your app must expose the refresh route:
15
- * ```typescript
16
- * // app/api/auth/refresh/route.ts
17
- * export { POST } from '@payez/next-mvp/routes/auth/refresh';
18
- * ```
19
- *
20
- * @version 2.0.0
21
- */
22
- import { NextRequest } from 'next/server';
23
- import { SessionData } from './session-store';
24
- export interface TokenResult {
25
- success: true;
26
- accessToken: string;
27
- sessionData: SessionData;
28
- }
29
- export interface TokenError {
30
- success: false;
31
- error: 'NO_SESSION' | 'NO_TOKEN' | 'EXPIRED' | 'REFRESH_FAILED' | 'SESSION_EXPIRED_NO_REFRESH';
32
- message: string;
33
- terminal?: boolean;
34
- }
35
- export type EnsureFreshTokenResult = TokenResult | TokenError;
36
- /**
37
- * Ensures we have a fresh access token before making API calls.
38
- *
39
- * This utility checks token expiration and triggers a refresh if needed,
40
- * preventing 401 errors from expired tokens being sent to downstream APIs.
41
- *
42
- * @param request - The incoming NextRequest
43
- * @returns TokenResult with accessToken and sessionData, or TokenError
44
- *
45
- * @example
46
- * ```typescript
47
- * import { ensureFreshToken } from '@payez/next-mvp/lib/token-lifecycle';
48
- *
49
- * export async function GET(request: NextRequest) {
50
- * const tokenResult = await ensureFreshToken(request);
51
- * if (!tokenResult.success) {
52
- * return NextResponse.json({ error: tokenResult.error }, { status: 401 });
53
- * }
54
- *
55
- * // Use tokenResult.accessToken for downstream API calls
56
- * const response = await fetch('https://api.example.com/data', {
57
- * headers: { 'Authorization': `Bearer ${tokenResult.accessToken}` }
58
- * });
59
- * }
60
- * ```
61
- */
62
- export declare function ensureFreshToken(request: NextRequest): Promise<EnsureFreshTokenResult>;
63
- /**
64
- * Get authorization header from fresh token.
65
- * Convenience wrapper for API routes.
66
- *
67
- * @param request - The incoming NextRequest
68
- * @returns Authorization header string or null if token unavailable
69
- *
70
- * @example
71
- * ```typescript
72
- * const authHeader = await getFreshAuthHeader(request);
73
- * if (!authHeader) {
74
- * return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
75
- * }
76
- * ```
77
- */
78
- export declare function getFreshAuthHeader(request: NextRequest): Promise<string | null>;
1
+ /**
2
+ * Token Lifecycle Management for @payez/next-mvp
3
+ *
4
+ * Ensures tokens are fresh before making API calls.
5
+ * Checks expiration and triggers refresh if needed.
6
+ *
7
+ * Pattern: Check first, refresh if needed, fail gracefully if refresh fails.
8
+ *
9
+ * HANDLES CONCURRENT REFRESH: When multiple API calls arrive simultaneously
10
+ * with expired tokens, only one will actually perform the refresh. Others
11
+ * receive 409 (conflict) and wait for the refresh to complete, then use
12
+ * the freshly refreshed tokens.
13
+ *
14
+ * REQUIRED: Your app must expose the refresh route:
15
+ * ```typescript
16
+ * // app/api/auth/refresh/route.ts
17
+ * export { POST } from '@payez/next-mvp/routes/auth/refresh';
18
+ * ```
19
+ *
20
+ * @version 2.0.0
21
+ */
22
+ import { NextRequest } from 'next/server';
23
+ import { SessionData } from './session-store';
24
+ export interface TokenResult {
25
+ success: true;
26
+ accessToken: string;
27
+ sessionData: SessionData;
28
+ }
29
+ export interface TokenError {
30
+ success: false;
31
+ error: 'NO_SESSION' | 'NO_TOKEN' | 'EXPIRED' | 'REFRESH_FAILED' | 'SESSION_EXPIRED_NO_REFRESH';
32
+ message: string;
33
+ terminal?: boolean;
34
+ }
35
+ export type EnsureFreshTokenResult = TokenResult | TokenError;
36
+ /**
37
+ * Ensures we have a fresh access token before making API calls.
38
+ *
39
+ * This utility checks token expiration and triggers a refresh if needed,
40
+ * preventing 401 errors from expired tokens being sent to downstream APIs.
41
+ *
42
+ * @param request - The incoming NextRequest
43
+ * @returns TokenResult with accessToken and sessionData, or TokenError
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * import { ensureFreshToken } from '@payez/next-mvp/lib/token-lifecycle';
48
+ *
49
+ * export async function GET(request: NextRequest) {
50
+ * const tokenResult = await ensureFreshToken(request);
51
+ * if (!tokenResult.success) {
52
+ * return NextResponse.json({ error: tokenResult.error }, { status: 401 });
53
+ * }
54
+ *
55
+ * // Use tokenResult.accessToken for downstream API calls
56
+ * const response = await fetch('https://api.example.com/data', {
57
+ * headers: { 'Authorization': `Bearer ${tokenResult.accessToken}` }
58
+ * });
59
+ * }
60
+ * ```
61
+ */
62
+ export declare function ensureFreshToken(request: NextRequest): Promise<EnsureFreshTokenResult>;
63
+ /**
64
+ * Get authorization header from fresh token.
65
+ * Convenience wrapper for API routes.
66
+ *
67
+ * @param request - The incoming NextRequest
68
+ * @returns Authorization header string or null if token unavailable
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * const authHeader = await getFreshAuthHeader(request);
73
+ * if (!authHeader) {
74
+ * return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
75
+ * }
76
+ * ```
77
+ */
78
+ export declare function getFreshAuthHeader(request: NextRequest): Promise<string | null>;