@payez/next-mvp 4.0.28 → 4.0.30

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.
@@ -9,6 +9,39 @@
9
9
  *
10
10
  * @see BETTER-AUTH-MIGRATION-SPEC.md
11
11
  */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
12
45
  Object.defineProperty(exports, "__esModule", { value: true });
13
46
  exports.__betterAuthInstance = void 0;
14
47
  exports.buildBetterAuthProviders = buildBetterAuthProviders;
@@ -235,9 +268,9 @@ async function exchangeOAuthForIdpTokens(sessionToken, provider = 'google') {
235
268
  console.warn('[BETTER_AUTH] IDP oauth-callback returned no access_token. Keys:', Object.keys(result || {}));
236
269
  return false;
237
270
  }
238
- // Store IDP tokens in the BA Redis session
271
+ // Build IDP token data
239
272
  const requiresTwoFactor = result.user?.requiresTwoFactor ?? result.requiresTwoFactor ?? false;
240
- baData.idpTokens = {
273
+ const idpTokenData = {
241
274
  idpAccessToken: result.access_token,
242
275
  idpRefreshToken: result.refresh_token,
243
276
  idpAccessTokenExpires: result.expires_in
@@ -249,7 +282,22 @@ async function exchangeOAuthForIdpTokens(sessionToken, provider = 'google') {
249
282
  roles: result.user?.roles || result.roles || [],
250
283
  mfaVerified: !requiresTwoFactor,
251
284
  };
285
+ // Store in BA Redis session (for decodeSession)
286
+ baData.idpTokens = idpTokenData;
252
287
  await (0, redis_1.getRedis)().setex(baKey, 7 * 24 * 60 * 60, JSON.stringify(baData));
288
+ // Write to canonical session store so refresh handler and token lifecycle can find the tokens.
289
+ // Key format: {sessionPrefix}{token} — same key that getSession() reads from.
290
+ try {
291
+ const { getSessionPrefix } = await Promise.resolve().then(() => __importStar(require('../lib/app-slug')));
292
+ const canonicalKey = `${getSessionPrefix()}${sessionToken}`;
293
+ await (0, redis_1.getRedis)().setex(canonicalKey, 7 * 24 * 60 * 60, JSON.stringify({
294
+ ...idpTokenData,
295
+ oauthProvider: provider,
296
+ }));
297
+ }
298
+ catch (canonicalErr) {
299
+ console.warn('[BETTER_AUTH] Failed to write canonical session:', canonicalErr instanceof Error ? canonicalErr.message : String(canonicalErr));
300
+ }
253
301
  console.log('[BETTER_AUTH] IDP tokens stored in session for', email);
254
302
  return true;
255
303
  }
@@ -146,5 +146,5 @@ function EnhancedProfilePage() {
146
146
  contact_info.preferred_contact_method.charAt(0).toUpperCase() +
147
147
  contact_info.preferred_contact_method.slice(1) : undefined, isDarkMode: isDarkMode })] }) }), (0, jsx_runtime_1.jsx)(EditableSection, { title: "Address", isDarkMode: isDarkMode, children: address?.address_line_1 ? ((0, jsx_runtime_1.jsxs)("div", { className: textPrimary, children: [(0, jsx_runtime_1.jsx)("p", { children: address.address_line_1 }), address.address_line_2 && (0, jsx_runtime_1.jsx)("p", { children: address.address_line_2 }), (0, jsx_runtime_1.jsx)("p", { children: [address.city, address.state_name, address.postal_code]
148
148
  .filter(Boolean)
149
- .join(', ') }), (0, jsx_runtime_1.jsx)("p", { children: address.country_name || address.country_code })] })) : ((0, jsx_runtime_1.jsx)("p", { className: textMuted, children: "No address on file" })) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex justify-center gap-6 pt-4", children: [(0, jsx_runtime_1.jsx)("a", { href: "/account/security", className: `text-sm ${isDarkMode ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`, children: "Security Settings \u2192" }), (0, jsx_runtime_1.jsx)("a", { href: "/account/settings", className: `text-sm ${isDarkMode ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`, children: "Preferences \u2192" })] })] }) }));
149
+ .join(', ') }), (0, jsx_runtime_1.jsx)("p", { children: address.country_name || address.country_code })] })) : ((0, jsx_runtime_1.jsx)("p", { className: textMuted, children: "No address on file" })) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap justify-center gap-6 pt-4", children: [(0, jsx_runtime_1.jsx)("a", { href: "/account/subscription", className: `text-sm ${isDarkMode ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`, children: "Subscription & Billing \u2192" }), (0, jsx_runtime_1.jsx)("a", { href: "/account/security", className: `text-sm ${isDarkMode ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`, children: "Security Settings \u2192" }), (0, jsx_runtime_1.jsx)("a", { href: "/account/settings", className: `text-sm ${isDarkMode ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`, children: "Preferences \u2192" })] })] }) }));
150
150
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payez/next-mvp",
3
- "version": "4.0.28",
3
+ "version": "4.0.30",
4
4
  "sideEffects": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -261,9 +261,9 @@ export async function exchangeOAuthForIdpTokens(
261
261
  return false;
262
262
  }
263
263
 
264
- // Store IDP tokens in the BA Redis session
264
+ // Build IDP token data
265
265
  const requiresTwoFactor = result.user?.requiresTwoFactor ?? result.requiresTwoFactor ?? false;
266
- baData.idpTokens = {
266
+ const idpTokenData = {
267
267
  idpAccessToken: result.access_token,
268
268
  idpRefreshToken: result.refresh_token,
269
269
  idpAccessTokenExpires: result.expires_in
@@ -275,7 +275,24 @@ export async function exchangeOAuthForIdpTokens(
275
275
  roles: result.user?.roles || result.roles || [],
276
276
  mfaVerified: !requiresTwoFactor,
277
277
  };
278
+
279
+ // Store in BA Redis session (for decodeSession)
280
+ baData.idpTokens = idpTokenData;
278
281
  await getRedis().setex(baKey, 7 * 24 * 60 * 60, JSON.stringify(baData));
282
+
283
+ // Write to canonical session store so refresh handler and token lifecycle can find the tokens.
284
+ // Key format: {sessionPrefix}{token} — same key that getSession() reads from.
285
+ try {
286
+ const { getSessionPrefix } = await import('../lib/app-slug');
287
+ const canonicalKey = `${getSessionPrefix()}${sessionToken}`;
288
+ await getRedis().setex(canonicalKey, 7 * 24 * 60 * 60, JSON.stringify({
289
+ ...idpTokenData,
290
+ oauthProvider: provider,
291
+ }));
292
+ } catch (canonicalErr) {
293
+ console.warn('[BETTER_AUTH] Failed to write canonical session:', canonicalErr instanceof Error ? canonicalErr.message : String(canonicalErr));
294
+ }
295
+
279
296
  console.log('[BETTER_AUTH] IDP tokens stored in session for', email);
280
297
  return true;
281
298
  } catch (err) {
@@ -459,7 +459,13 @@ export default function EnhancedProfilePage() {
459
459
  </EditableSection>
460
460
 
461
461
  {/* Quick Links */}
462
- <div className="flex justify-center gap-6 pt-4">
462
+ <div className="flex flex-wrap justify-center gap-6 pt-4">
463
+ <a
464
+ href="/account/subscription"
465
+ className={`text-sm ${isDarkMode ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`}
466
+ >
467
+ Subscription & Billing →
468
+ </a>
463
469
  <a
464
470
  href="/account/security"
465
471
  className={`text-sm ${isDarkMode ? 'text-blue-400 hover:text-blue-300' : 'text-blue-600 hover:text-blue-700'}`}