@payez/next-mvp 4.0.49 → 4.1.1

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.
@@ -5,16 +5,6 @@
5
5
  * getAuthInstance(); use getSession(req) for the request-scoped session.
6
6
  */
7
7
  import 'server-only';
8
- import { type SessionData } from '../lib/session-store';
9
- export type IdpTokenResult = {
10
- success: true;
11
- accessToken: string;
12
- sessionData: SessionData;
13
- } | {
14
- success: false;
15
- error: 'NO_SESSION' | 'NO_TOKEN';
16
- terminal: true;
17
- };
18
8
  /**
19
9
  * Get the initialized Better Auth instance (singleton).
20
10
  */
@@ -55,7 +45,102 @@ export declare function getAuthInstance(): Promise<import("better-auth/types").A
55
45
  handler: (inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>;
56
46
  }[];
57
47
  };
58
- }];
48
+ }, ...{
49
+ id: "magic-link";
50
+ endpoints: {
51
+ signInMagicLink: import("better-call").StrictEndpoint<"/sign-in/magic-link", {
52
+ method: "POST";
53
+ requireHeaders: true;
54
+ body: import("zod").ZodObject<{
55
+ email: import("zod").ZodEmail;
56
+ name: import("zod").ZodOptional<import("zod").ZodString>;
57
+ callbackURL: import("zod").ZodOptional<import("zod").ZodString>;
58
+ newUserCallbackURL: import("zod").ZodOptional<import("zod").ZodString>;
59
+ errorCallbackURL: import("zod").ZodOptional<import("zod").ZodString>;
60
+ metadata: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodAny>>;
61
+ }, import("better-auth/*").$strip>;
62
+ metadata: {
63
+ openapi: {
64
+ operationId: string;
65
+ description: string;
66
+ responses: {
67
+ 200: {
68
+ description: string;
69
+ content: {
70
+ "application/json": {
71
+ schema: {
72
+ type: "object";
73
+ properties: {
74
+ status: {
75
+ type: string;
76
+ };
77
+ };
78
+ };
79
+ };
80
+ };
81
+ };
82
+ };
83
+ };
84
+ };
85
+ }, {
86
+ status: boolean;
87
+ }>;
88
+ magicLinkVerify: import("better-call").StrictEndpoint<"/magic-link/verify", {
89
+ method: "GET";
90
+ query: import("zod").ZodObject<{
91
+ token: import("zod").ZodString;
92
+ callbackURL: import("zod").ZodOptional<import("zod").ZodString>;
93
+ errorCallbackURL: import("zod").ZodOptional<import("zod").ZodString>;
94
+ newUserCallbackURL: import("zod").ZodOptional<import("zod").ZodString>;
95
+ }, import("better-auth/*").$strip>;
96
+ use: ((inputContext: import("better-call").MiddlewareInputContext<import("better-call").MiddlewareOptions>) => Promise<void>)[];
97
+ requireHeaders: true;
98
+ metadata: {
99
+ openapi: {
100
+ operationId: string;
101
+ description: string;
102
+ responses: {
103
+ 200: {
104
+ description: string;
105
+ content: {
106
+ "application/json": {
107
+ schema: {
108
+ type: "object";
109
+ properties: {
110
+ session: {
111
+ $ref: string;
112
+ };
113
+ user: {
114
+ $ref: string;
115
+ };
116
+ };
117
+ };
118
+ };
119
+ };
120
+ };
121
+ };
122
+ };
123
+ };
124
+ }, {
125
+ token: string;
126
+ user: {
127
+ id: string;
128
+ createdAt: Date;
129
+ updatedAt: Date;
130
+ email: string;
131
+ emailVerified: boolean;
132
+ name: string;
133
+ image?: string | null | undefined;
134
+ };
135
+ }>;
136
+ };
137
+ rateLimit: {
138
+ pathMatcher(path: string): boolean;
139
+ window: number;
140
+ max: number;
141
+ }[];
142
+ options: import("better-auth/plugins/magic-link").MagicLinkOptions;
143
+ }[]];
59
144
  }>>;
60
145
  /**
61
146
  * Get the current session from a request.
@@ -64,20 +149,6 @@ export declare function getAuthInstance(): Promise<import("better-auth/types").A
64
149
  * Returns the session object or null if not authenticated.
65
150
  */
66
151
  export declare function getSession(request?: Request): Promise<any>;
67
- /**
68
- * Get normalized session data for the current request.
69
- *
70
- * This prefers the app's Redis session because it carries the canonical
71
- * IDP token, roles, and tenant-specific user identity used by app routes.
72
- */
73
- export declare function getSessionData(request?: Request): Promise<SessionData | null>;
74
- /**
75
- * Get the current request's IDP access token without triggering a refresh.
76
- *
77
- * Use this for routes that only need the currently-issued bearer token and
78
- * should fail closed instead of performing token lifecycle work.
79
- */
80
- export declare function getIdpToken(request?: Request): Promise<IdpTokenResult>;
81
152
  /**
82
153
  * Get the current session, throwing if not authenticated.
83
154
  * Use in API handlers that require auth.
@@ -5,67 +5,48 @@
5
5
  * All server-side auth flows go through the Better Auth instance returned by
6
6
  * getAuthInstance(); use getSession(req) for the request-scoped session.
7
7
  */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
8
41
  Object.defineProperty(exports, "__esModule", { value: true });
9
42
  exports.getAuthInstance = getAuthInstance;
10
43
  exports.getSession = getSession;
11
- exports.getSessionData = getSessionData;
12
- exports.getIdpToken = getIdpToken;
13
44
  exports.requireSession = requireSession;
14
45
  require("server-only");
15
46
  const better_auth_1 = require("../auth/better-auth");
16
47
  const idp_client_config_1 = require("../lib/idp-client-config");
17
- const session_store_1 = require("../lib/session-store");
18
48
  let authInstance = null;
19
49
  let authInitPromise = null;
20
- function buildSessionDataFromAuthSession(session) {
21
- const user = session?.user;
22
- if (!user?.id && !user?.email) {
23
- return null;
24
- }
25
- const expiresAt = session?.session?.expiresAt
26
- ? new Date(session.session.expiresAt).getTime()
27
- : Date.now() + 24 * 60 * 60 * 1000;
28
- return {
29
- userId: user.userId || user.id || '',
30
- email: user.email || '',
31
- name: user.name || undefined,
32
- roles: Array.isArray(user.roles) ? user.roles : [],
33
- idpAccessToken: user.idpAccessToken,
34
- idpRefreshToken: user.idpRefreshToken,
35
- idpAccessTokenExpires: user.idpAccessTokenExpires || expiresAt,
36
- mfaVerified: user.mfaVerified ?? user.twoFactorSessionVerified ?? false,
37
- oauthProvider: user.oauthProvider,
38
- idpClientId: user.idpClientId,
39
- merchantId: user.merchantId,
40
- };
41
- }
42
- function attachSessionData(session, sessionData, sessionToken) {
43
- if (!sessionData) {
44
- return session;
45
- }
46
- const enrichedSessionData = {
47
- ...sessionData,
48
- ...(sessionToken ? { sessionToken } : {}),
49
- };
50
- session.sessionData = enrichedSessionData;
51
- if (session?.user) {
52
- const user = session.user;
53
- user.userId = enrichedSessionData.userId || user.userId;
54
- user.email = enrichedSessionData.email || user.email;
55
- user.name = enrichedSessionData.name || user.name;
56
- user.roles = enrichedSessionData.roles || user.roles || [];
57
- user.idpAccessToken = enrichedSessionData.idpAccessToken;
58
- user.idpRefreshToken = enrichedSessionData.idpRefreshToken;
59
- user.idpAccessTokenExpires = enrichedSessionData.idpAccessTokenExpires;
60
- user.mfaVerified = enrichedSessionData.mfaVerified;
61
- user.twoFactorSessionVerified =
62
- enrichedSessionData.mfaVerified ?? user.twoFactorSessionVerified;
63
- user.oauthProvider = enrichedSessionData.oauthProvider || user.oauthProvider;
64
- user.idpClientId = enrichedSessionData.idpClientId || user.idpClientId;
65
- user.merchantId = enrichedSessionData.merchantId || user.merchantId;
66
- }
67
- return session;
68
- }
69
50
  /**
70
51
  * Get the initialized Better Auth instance (singleton).
71
52
  */
@@ -94,66 +75,31 @@ async function getSession(request) {
94
75
  const session = await auth.api.getSession({ headers: request.headers });
95
76
  if (!session?.session?.token || !session?.user)
96
77
  return session;
97
- const sessionToken = session.session.token;
98
- let sessionData = null;
99
- // Prefer the app's normalized Redis session. Fall back to Better Auth's
100
- // secondary storage record, then finally to whatever Better Auth already
101
- // put on the request session object.
78
+ // Enrich with IDP tokens from Redis (stored by post-login hook)
102
79
  try {
103
- sessionData = await (0, session_store_1.getSession)(sessionToken);
104
- if (!sessionData) {
105
- sessionData = await (0, session_store_1.getBetterAuthSession)(sessionToken);
80
+ const { getRedis } = await Promise.resolve().then(() => __importStar(require('../lib/redis')));
81
+ const { getAppSlug } = await Promise.resolve().then(() => __importStar(require('../lib/app-slug')));
82
+ const baKey = `ba:${getAppSlug()}:${session.session.token}`;
83
+ const baRaw = await getRedis().get(baKey);
84
+ if (baRaw) {
85
+ const baData = JSON.parse(baRaw);
86
+ if (baData.idpTokens) {
87
+ const u = session.user;
88
+ u.roles = baData.idpTokens.roles || [];
89
+ u.userId = baData.idpTokens.userId;
90
+ u.idpAccessToken = baData.idpTokens.idpAccessToken;
91
+ u.idpRefreshToken = baData.idpTokens.idpRefreshToken;
92
+ u.idpAccessTokenExpires = baData.idpTokens.idpAccessTokenExpires;
93
+ }
106
94
  }
107
95
  }
108
96
  catch { /* Redis unavailable */ }
109
- if (!sessionData) {
110
- sessionData = buildSessionDataFromAuthSession(session);
111
- }
112
- return attachSessionData(session, sessionData, sessionToken);
97
+ return session;
113
98
  }
114
99
  catch {
115
100
  return null;
116
101
  }
117
102
  }
118
- /**
119
- * Get normalized session data for the current request.
120
- *
121
- * This prefers the app's Redis session because it carries the canonical
122
- * IDP token, roles, and tenant-specific user identity used by app routes.
123
- */
124
- async function getSessionData(request) {
125
- const session = await getSession(request);
126
- const sessionData = session?.sessionData ||
127
- buildSessionDataFromAuthSession(session);
128
- if (!sessionData) {
129
- return null;
130
- }
131
- const sessionToken = session?.session?.token;
132
- return sessionToken
133
- ? { ...sessionData, sessionToken }
134
- : sessionData;
135
- }
136
- /**
137
- * Get the current request's IDP access token without triggering a refresh.
138
- *
139
- * Use this for routes that only need the currently-issued bearer token and
140
- * should fail closed instead of performing token lifecycle work.
141
- */
142
- async function getIdpToken(request) {
143
- const sessionData = await getSessionData(request);
144
- if (!sessionData) {
145
- return { success: false, error: 'NO_SESSION', terminal: true };
146
- }
147
- const accessToken = sessionData.idpAccessToken || sessionData.accessToken;
148
- if (!accessToken) {
149
- return { success: false, error: 'NO_TOKEN', terminal: true };
150
- }
151
- return {
152
- success: true,
153
- accessToken,
154
- sessionData,
155
- };
156
- }
157
103
  /**
158
104
  * Get the current session, throwing if not authenticated.
159
105
  * Use in API handlers that require auth.
@@ -141,7 +141,7 @@ export declare function useVibeMutation<T extends VibeTableName, Op extends Muta
141
141
  /**
142
142
  * Convenience hook for creating records.
143
143
  */
144
- export declare function useVibeCreate<T extends VibeTableName>(table: T, options?: Omit<UseVibeMutationOptions<T, 'create'>, never>): import("@tanstack/react-query").UseMutationResult<VibeTableType<T>, VibeError, Omit<VibeTableType<T>, "created_at" | "id" | "updated_at">, unknown>;
144
+ export declare function useVibeCreate<T extends VibeTableName>(table: T, options?: Omit<UseVibeMutationOptions<T, 'create'>, never>): import("@tanstack/react-query").UseMutationResult<VibeTableType<T>, VibeError, Omit<VibeTableType<T>, "id" | "created_at" | "updated_at">, unknown>;
145
145
  /**
146
146
  * Convenience hook for updating records.
147
147
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payez/next-mvp",
3
- "version": "4.0.49",
3
+ "version": "4.1.1",
4
4
  "sideEffects": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",