@rovela-ai/sdk 0.3.17 → 0.3.20
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.
- package/dist/admin/api/settings.d.ts.map +1 -1
- package/dist/admin/api/settings.js +4 -0
- package/dist/admin/api/settings.js.map +1 -1
- package/dist/admin/components/AdminAcceptInviteForm.js +1 -1
- package/dist/admin/components/AdminAcceptInviteForm.js.map +1 -1
- package/dist/admin/components/AdminAccountPage.js +1 -1
- package/dist/admin/components/AdminAccountPage.js.map +1 -1
- package/dist/admin/components/AdminForgotPasswordForm.js +1 -1
- package/dist/admin/components/AdminForgotPasswordForm.js.map +1 -1
- package/dist/admin/components/AdminLoginForm.js +1 -1
- package/dist/admin/components/AdminLoginForm.js.map +1 -1
- package/dist/admin/components/AdminResetPasswordForm.js +1 -1
- package/dist/admin/components/AdminResetPasswordForm.js.map +1 -1
- package/dist/admin/components/AdminSetupForm.js +1 -1
- package/dist/admin/components/AdminSetupForm.js.map +1 -1
- package/dist/admin/components/InviteUserDialog.js +1 -1
- package/dist/admin/components/InviteUserDialog.js.map +1 -1
- package/dist/admin/components/StoreSettings.d.ts.map +1 -1
- package/dist/admin/components/StoreSettings.js +11 -3
- package/dist/admin/components/StoreSettings.js.map +1 -1
- package/dist/admin/config.d.ts +30 -38
- package/dist/admin/config.d.ts.map +1 -1
- package/dist/admin/config.js +106 -67
- package/dist/admin/config.js.map +1 -1
- package/dist/admin/hooks/index.d.ts +2 -0
- package/dist/admin/hooks/index.d.ts.map +1 -1
- package/dist/admin/hooks/index.js +1 -0
- package/dist/admin/hooks/index.js.map +1 -1
- package/dist/admin/hooks/useAdminAuth.d.ts +3 -14
- package/dist/admin/hooks/useAdminAuth.d.ts.map +1 -1
- package/dist/admin/hooks/useAdminAuth.js +110 -55
- package/dist/admin/hooks/useAdminAuth.js.map +1 -1
- package/dist/admin/hooks/useAdminSession.d.ts +23 -0
- package/dist/admin/hooks/useAdminSession.d.ts.map +1 -0
- package/dist/admin/hooks/useAdminSession.js +117 -0
- package/dist/admin/hooks/useAdminSession.js.map +1 -0
- package/dist/admin/index.d.ts +2 -1
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +1 -1
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/server/admin-service.d.ts.map +1 -1
- package/dist/admin/server/admin-service.js +15 -0
- package/dist/admin/server/admin-service.js.map +1 -1
- package/dist/admin/server/admin-session.d.ts +11 -12
- package/dist/admin/server/admin-session.d.ts.map +1 -1
- package/dist/admin/server/admin-session.js +20 -20
- package/dist/admin/server/admin-session.js.map +1 -1
- package/dist/admin/types.d.ts +5 -0
- package/dist/admin/types.d.ts.map +1 -1
- package/dist/auth/api/request-refund.d.ts.map +1 -1
- package/dist/auth/api/request-refund.js +7 -8
- package/dist/auth/api/request-refund.js.map +1 -1
- package/dist/auth/api/request-return.d.ts.map +1 -1
- package/dist/auth/api/request-return.js +7 -8
- package/dist/auth/api/request-return.js.map +1 -1
- package/dist/auth/components/ForgotPasswordForm.d.ts.map +1 -1
- package/dist/auth/components/ForgotPasswordForm.js +2 -1
- package/dist/auth/components/ForgotPasswordForm.js.map +1 -1
- package/dist/auth/components/Label.d.ts +19 -0
- package/dist/auth/components/Label.d.ts.map +1 -0
- package/dist/auth/components/Label.js +18 -0
- package/dist/auth/components/Label.js.map +1 -0
- package/dist/auth/components/ResetPasswordForm.d.ts.map +1 -1
- package/dist/auth/components/ResetPasswordForm.js +2 -1
- package/dist/auth/components/ResetPasswordForm.js.map +1 -1
- package/dist/auth/components/SignInForm.d.ts.map +1 -1
- package/dist/auth/components/SignInForm.js +2 -1
- package/dist/auth/components/SignInForm.js.map +1 -1
- package/dist/auth/components/SignUpForm.d.ts.map +1 -1
- package/dist/auth/components/SignUpForm.js +2 -1
- package/dist/auth/components/SignUpForm.js.map +1 -1
- package/dist/auth/components/index.d.ts +2 -0
- package/dist/auth/components/index.d.ts.map +1 -1
- package/dist/auth/components/index.js +1 -0
- package/dist/auth/components/index.js.map +1 -1
- package/dist/auth/config.d.ts +22 -10
- package/dist/auth/config.d.ts.map +1 -1
- package/dist/auth/config.js +51 -98
- package/dist/auth/config.js.map +1 -1
- package/dist/auth/hooks/useAuth.d.ts.map +1 -1
- package/dist/auth/hooks/useAuth.js +11 -1
- package/dist/auth/hooks/useAuth.js.map +1 -1
- package/dist/auth/index.d.ts +2 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +2 -1
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/server/customer-session.d.ts +81 -0
- package/dist/auth/server/customer-session.d.ts.map +1 -0
- package/dist/auth/server/customer-session.js +115 -0
- package/dist/auth/server/customer-session.js.map +1 -0
- package/dist/auth/server/index.d.ts +2 -0
- package/dist/auth/server/index.d.ts.map +1 -1
- package/dist/auth/server/index.js +2 -0
- package/dist/auth/server/index.js.map +1 -1
- package/dist/core/cookie-consent/CookieBanner.d.ts +2 -0
- package/dist/core/cookie-consent/CookieBanner.d.ts.map +1 -0
- package/dist/core/cookie-consent/CookieBanner.js +207 -0
- package/dist/core/cookie-consent/CookieBanner.js.map +1 -0
- package/dist/core/cookie-consent/CookieConsentProvider.d.ts +53 -0
- package/dist/core/cookie-consent/CookieConsentProvider.d.ts.map +1 -0
- package/dist/core/cookie-consent/CookieConsentProvider.js +162 -0
- package/dist/core/cookie-consent/CookieConsentProvider.js.map +1 -0
- package/dist/core/cookie-consent/CookiePreferencesLink.d.ts +15 -0
- package/dist/core/cookie-consent/CookiePreferencesLink.d.ts.map +1 -0
- package/dist/core/cookie-consent/CookiePreferencesLink.js +12 -0
- package/dist/core/cookie-consent/CookiePreferencesLink.js.map +1 -0
- package/dist/core/cookie-consent/index.d.ts +17 -0
- package/dist/core/cookie-consent/index.d.ts.map +1 -0
- package/dist/core/cookie-consent/index.js +16 -0
- package/dist/core/cookie-consent/index.js.map +1 -0
- package/dist/core/cookie-consent/types.d.ts +31 -0
- package/dist/core/cookie-consent/types.d.ts.map +1 -0
- package/dist/core/cookie-consent/types.js +10 -0
- package/dist/core/cookie-consent/types.js.map +1 -0
- package/dist/core/cookie-consent/useCookieConsent.d.ts +14 -0
- package/dist/core/cookie-consent/useCookieConsent.d.ts.map +1 -0
- package/dist/core/cookie-consent/useCookieConsent.js +25 -0
- package/dist/core/cookie-consent/useCookieConsent.js.map +1 -0
- package/dist/core/db/queries.d.ts +1 -0
- package/dist/core/db/queries.d.ts.map +1 -1
- package/dist/core/db/queries.js +6 -0
- package/dist/core/db/queries.js.map +1 -1
- package/dist/core/db/schema.d.ts +17 -0
- package/dist/core/db/schema.d.ts.map +1 -1
- package/dist/core/db/schema.js +5 -0
- package/dist/core/db/schema.js.map +1 -1
- package/dist/core/server/index.d.ts +1 -1
- package/dist/core/server/index.d.ts.map +1 -1
- package/dist/core/server/index.js +3 -1
- package/dist/core/server/index.js.map +1 -1
- package/package.json +5 -1
package/dist/auth/config.d.ts
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @rovela/sdk/auth/config
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* Uses JWT strategy with two credentials providers:
|
|
6
|
-
* - 'credentials' for customer login
|
|
7
|
-
* - 'admin-credentials' for admin login
|
|
4
|
+
* NextAuth configuration for STOREFRONT CUSTOMER authentication only.
|
|
8
5
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Admin authentication has its own completely separate config with its own
|
|
7
|
+
* cookie name, living in `@rovela-ai/sdk/admin/config`. Both can coexist in
|
|
8
|
+
* the same browser — that's what makes the "linked customer" feature work.
|
|
9
|
+
*
|
|
10
|
+
* See §26 of the platform CLAUDE.md for the full two-cookie architecture.
|
|
11
11
|
*/
|
|
12
12
|
import type { NextAuthOptions } from 'next-auth';
|
|
13
13
|
import type { CustomerSession, AuthConfigOptions } from './types';
|
|
14
14
|
/**
|
|
15
|
-
* Create NextAuth options for
|
|
15
|
+
* Create NextAuth options for STOREFRONT CUSTOMER authentication.
|
|
16
|
+
*
|
|
17
|
+
* This config wires ONLY the customer credentials provider. Admin auth
|
|
18
|
+
* is a separate config (see `@rovela-ai/sdk/admin` → `createAdminAuthOptions`)
|
|
19
|
+
* mounted at `/api/admin-auth/[...nextauth]` with its own cookie name so
|
|
20
|
+
* both sessions can coexist in the same browser.
|
|
16
21
|
*
|
|
17
22
|
* @param options - Configuration options
|
|
18
23
|
* @returns NextAuth options object
|
|
@@ -21,13 +26,13 @@ import type { CustomerSession, AuthConfigOptions } from './types';
|
|
|
21
26
|
* ```typescript
|
|
22
27
|
* // app/api/auth/[...nextauth]/route.ts
|
|
23
28
|
* import NextAuth from 'next-auth'
|
|
24
|
-
* import {
|
|
29
|
+
* import { createCustomerAuthOptions } from '@rovela-ai/sdk/auth'
|
|
25
30
|
*
|
|
26
|
-
* const handler = NextAuth(
|
|
31
|
+
* const handler = NextAuth(createCustomerAuthOptions())
|
|
27
32
|
* export { handler as GET, handler as POST }
|
|
28
33
|
* ```
|
|
29
34
|
*/
|
|
30
|
-
export declare function
|
|
35
|
+
export declare function createCustomerAuthOptions(options?: AuthConfigOptions): NextAuthOptions;
|
|
31
36
|
/**
|
|
32
37
|
* Get customer session data from the current session.
|
|
33
38
|
* Refreshes data from database for accuracy.
|
|
@@ -44,4 +49,11 @@ export declare function createAuthOptions(options?: AuthConfigOptions): NextAuth
|
|
|
44
49
|
* ```
|
|
45
50
|
*/
|
|
46
51
|
export declare function getCustomerSession(customerId: string): Promise<CustomerSession | null>;
|
|
52
|
+
/**
|
|
53
|
+
* @deprecated Use `createCustomerAuthOptions()` instead. This alias returns
|
|
54
|
+
* the customer-only config, matching the pre-split behavior for storefront
|
|
55
|
+
* auth. Admin auth now lives at `createAdminAuthOptions()` in the admin
|
|
56
|
+
* module and mounts a separate NextAuth endpoint.
|
|
57
|
+
*/
|
|
58
|
+
export declare function createAuthOptions(options?: AuthConfigOptions): NextAuthOptions;
|
|
47
59
|
//# sourceMappingURL=config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,WAAW,CAAA;AAI/D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AA0BjE
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,WAAW,CAAA;AAI/D,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AA0BjE;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,iBAAsB,GAC9B,eAAe,CAsMjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,kBAAkB,CACtC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAEjC;AAgED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,iBAAsB,GAC9B,eAAe,CAEjB"}
|
package/dist/auth/config.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @rovela/sdk/auth/config
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* Uses JWT strategy with two credentials providers:
|
|
6
|
-
* - 'credentials' for customer login
|
|
7
|
-
* - 'admin-credentials' for admin login
|
|
4
|
+
* NextAuth configuration for STOREFRONT CUSTOMER authentication only.
|
|
8
5
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* Admin authentication has its own completely separate config with its own
|
|
7
|
+
* cookie name, living in `@rovela-ai/sdk/admin/config`. Both can coexist in
|
|
8
|
+
* the same browser — that's what makes the "linked customer" feature work.
|
|
9
|
+
*
|
|
10
|
+
* See §26 of the platform CLAUDE.md for the full two-cookie architecture.
|
|
11
11
|
*/
|
|
12
12
|
import CredentialsProvider from 'next-auth/providers/credentials';
|
|
13
13
|
import { authenticateCustomer, findCustomerForSession } from './server/customer-service';
|
|
@@ -31,7 +31,12 @@ const REMEMBER_ME_MAX_AGE = 30 * 24 * 60 * 60;
|
|
|
31
31
|
// Auth Configuration
|
|
32
32
|
// =============================================================================
|
|
33
33
|
/**
|
|
34
|
-
* Create NextAuth options for
|
|
34
|
+
* Create NextAuth options for STOREFRONT CUSTOMER authentication.
|
|
35
|
+
*
|
|
36
|
+
* This config wires ONLY the customer credentials provider. Admin auth
|
|
37
|
+
* is a separate config (see `@rovela-ai/sdk/admin` → `createAdminAuthOptions`)
|
|
38
|
+
* mounted at `/api/admin-auth/[...nextauth]` with its own cookie name so
|
|
39
|
+
* both sessions can coexist in the same browser.
|
|
35
40
|
*
|
|
36
41
|
* @param options - Configuration options
|
|
37
42
|
* @returns NextAuth options object
|
|
@@ -40,13 +45,13 @@ const REMEMBER_ME_MAX_AGE = 30 * 24 * 60 * 60;
|
|
|
40
45
|
* ```typescript
|
|
41
46
|
* // app/api/auth/[...nextauth]/route.ts
|
|
42
47
|
* import NextAuth from 'next-auth'
|
|
43
|
-
* import {
|
|
48
|
+
* import { createCustomerAuthOptions } from '@rovela-ai/sdk/auth'
|
|
44
49
|
*
|
|
45
|
-
* const handler = NextAuth(
|
|
50
|
+
* const handler = NextAuth(createCustomerAuthOptions())
|
|
46
51
|
* export { handler as GET, handler as POST }
|
|
47
52
|
* ```
|
|
48
53
|
*/
|
|
49
|
-
export function
|
|
54
|
+
export function createCustomerAuthOptions(options = {}) {
|
|
50
55
|
const { sessionMaxAge = DEFAULT_SESSION_MAX_AGE, rememberMeMaxAge = REMEMBER_ME_MAX_AGE, requireEmailVerification = true, signInPage = '/auth/signin', errorPage = '/auth/signin', } = options;
|
|
51
56
|
return {
|
|
52
57
|
providers: [
|
|
@@ -76,45 +81,6 @@ export function createAuthOptions(options = {}) {
|
|
|
76
81
|
emailVerified: result.customer.emailVerified,
|
|
77
82
|
// Pass rememberMe through to JWT callback
|
|
78
83
|
rememberMe: credentials.rememberMe === 'true',
|
|
79
|
-
// No role means customer (not admin)
|
|
80
|
-
role: undefined,
|
|
81
|
-
};
|
|
82
|
-
},
|
|
83
|
-
}),
|
|
84
|
-
// =========================================================================
|
|
85
|
-
// Admin Credentials Provider
|
|
86
|
-
// =========================================================================
|
|
87
|
-
CredentialsProvider({
|
|
88
|
-
id: 'admin-credentials',
|
|
89
|
-
name: 'Admin Credentials',
|
|
90
|
-
credentials: {
|
|
91
|
-
email: { label: 'Email', type: 'email' },
|
|
92
|
-
password: { label: 'Password', type: 'password' },
|
|
93
|
-
rememberMe: { label: 'Remember Me', type: 'checkbox' },
|
|
94
|
-
},
|
|
95
|
-
async authorize(credentials) {
|
|
96
|
-
if (!credentials?.email || !credentials?.password) {
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
// Dynamic import to avoid circular dependency
|
|
100
|
-
const { authenticateAdmin } = await import('../admin/server/admin-service');
|
|
101
|
-
const result = await authenticateAdmin(credentials.email, credentials.password);
|
|
102
|
-
if (!result.success) {
|
|
103
|
-
throw new Error(result.error, { cause: result.code });
|
|
104
|
-
}
|
|
105
|
-
// Return admin user with role. `sessionVersion` is embedded in
|
|
106
|
-
// the JWT at sign-in so `requireAdmin` can detect forced logouts
|
|
107
|
-
// after password changes (Phase 4 session versioning).
|
|
108
|
-
const sessionVersion = result.admin.sessionVersion ?? 0;
|
|
109
|
-
return {
|
|
110
|
-
id: result.admin.id,
|
|
111
|
-
email: result.admin.email,
|
|
112
|
-
name: result.admin.name,
|
|
113
|
-
role: result.admin.role,
|
|
114
|
-
sessionVersion,
|
|
115
|
-
// Pass rememberMe through to the JWT callback so it can set a
|
|
116
|
-
// long exp instead of the default admin session window.
|
|
117
|
-
rememberMe: credentials.rememberMe === 'true',
|
|
118
84
|
};
|
|
119
85
|
},
|
|
120
86
|
}),
|
|
@@ -140,10 +106,13 @@ export function createAuthOptions(options = {}) {
|
|
|
140
106
|
// =========================================================================
|
|
141
107
|
// SameSite=None allows cookies in cross-origin contexts (iframes)
|
|
142
108
|
// Secure=true is required when SameSite=None (HTTPS only)
|
|
143
|
-
// This enables authentication in Blaxel preview iframes
|
|
109
|
+
// This enables authentication in Blaxel preview iframes.
|
|
110
|
+
//
|
|
111
|
+
// Cookie names are customer-specific so the admin auth endpoint can
|
|
112
|
+
// write a separate cookie without colliding. Both sessions coexist.
|
|
144
113
|
cookies: {
|
|
145
114
|
sessionToken: {
|
|
146
|
-
name: `__Secure-
|
|
115
|
+
name: `__Secure-rovela.customer.session-token`,
|
|
147
116
|
options: {
|
|
148
117
|
httpOnly: true,
|
|
149
118
|
sameSite: 'none',
|
|
@@ -152,7 +121,7 @@ export function createAuthOptions(options = {}) {
|
|
|
152
121
|
},
|
|
153
122
|
},
|
|
154
123
|
callbackUrl: {
|
|
155
|
-
name: `__Secure-
|
|
124
|
+
name: `__Secure-rovela.customer.callback-url`,
|
|
156
125
|
options: {
|
|
157
126
|
sameSite: 'none',
|
|
158
127
|
path: '/',
|
|
@@ -160,7 +129,7 @@ export function createAuthOptions(options = {}) {
|
|
|
160
129
|
},
|
|
161
130
|
},
|
|
162
131
|
csrfToken: {
|
|
163
|
-
name: `__Host-
|
|
132
|
+
name: `__Host-rovela.customer.csrf-token`,
|
|
164
133
|
options: {
|
|
165
134
|
httpOnly: true,
|
|
166
135
|
sameSite: 'none',
|
|
@@ -187,31 +156,17 @@ export function createAuthOptions(options = {}) {
|
|
|
187
156
|
const rememberMe = Boolean(sdkUser.rememberMe);
|
|
188
157
|
sdkToken.rememberMe = rememberMe;
|
|
189
158
|
sdkToken.originalIat = now;
|
|
190
|
-
//
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
// Store as ISO string or null (aligned with main project pattern)
|
|
202
|
-
sdkToken.emailVerified = sdkUser.emailVerified
|
|
203
|
-
? (sdkUser.emailVerified instanceof Date
|
|
204
|
-
? sdkUser.emailVerified.toISOString()
|
|
205
|
-
: String(sdkUser.emailVerified))
|
|
206
|
-
: null;
|
|
207
|
-
}
|
|
208
|
-
// Compute absolute exp. Admins without rememberMe use
|
|
209
|
-
// sessionMaxAge (caller-configurable; defaults to 24h); customers
|
|
210
|
-
// without rememberMe use the customer default. Both cohorts fall
|
|
211
|
-
// through to REMEMBER_ME_MAX_AGE (30 days) when the checkbox is
|
|
212
|
-
// ticked.
|
|
213
|
-
const defaultMaxAge = sdkUser.role ? sessionMaxAge : DEFAULT_SESSION_MAX_AGE;
|
|
214
|
-
const effectiveMaxAge = rememberMe ? rememberMeMaxAge : defaultMaxAge;
|
|
159
|
+
// Customer token: no role, has emailVerified. Store as ISO string
|
|
160
|
+
// or null (aligned with main project pattern).
|
|
161
|
+
sdkToken.emailVerified = sdkUser.emailVerified
|
|
162
|
+
? (sdkUser.emailVerified instanceof Date
|
|
163
|
+
? sdkUser.emailVerified.toISOString()
|
|
164
|
+
: String(sdkUser.emailVerified))
|
|
165
|
+
: null;
|
|
166
|
+
// Compute absolute exp. Without rememberMe use `sessionMaxAge`
|
|
167
|
+
// (caller-configurable; defaults to 24h). With rememberMe the
|
|
168
|
+
// session lives up to `rememberMeMaxAge` (30 days).
|
|
169
|
+
const effectiveMaxAge = rememberMe ? rememberMeMaxAge : sessionMaxAge;
|
|
215
170
|
sdkToken.exp = now + effectiveMaxAge;
|
|
216
171
|
}
|
|
217
172
|
else if (sdkToken.originalIat) {
|
|
@@ -220,10 +175,8 @@ export function createAuthOptions(options = {}) {
|
|
|
220
175
|
// ceiling we raised session.maxAge to. Legacy tokens without
|
|
221
176
|
// originalIat fall through to NextAuth's default exp handling,
|
|
222
177
|
// which is a benign one-time drift until they re-auth.
|
|
223
|
-
const role = sdkToken.role;
|
|
224
178
|
const rememberMe = Boolean(sdkToken.rememberMe);
|
|
225
|
-
const
|
|
226
|
-
const effectiveMaxAge = rememberMe ? rememberMeMaxAge : defaultMaxAge;
|
|
179
|
+
const effectiveMaxAge = rememberMe ? rememberMeMaxAge : sessionMaxAge;
|
|
227
180
|
sdkToken.exp = sdkToken.originalIat + effectiveMaxAge;
|
|
228
181
|
}
|
|
229
182
|
// Update session when triggered
|
|
@@ -241,29 +194,17 @@ export function createAuthOptions(options = {}) {
|
|
|
241
194
|
return token;
|
|
242
195
|
},
|
|
243
196
|
async session({ session, token }) {
|
|
244
|
-
//
|
|
245
|
-
//
|
|
197
|
+
// Customer session builder — no role, no sessionVersion, no admin
|
|
198
|
+
// fields. An admin JWT cannot reach this callback because the admin
|
|
199
|
+
// cookie is in a different cookie jar (`__Secure-rovela.admin.*`).
|
|
246
200
|
if (token) {
|
|
247
201
|
const sdkToken = token;
|
|
248
202
|
const user = session.user;
|
|
249
203
|
user.id = sdkToken.id;
|
|
250
204
|
user.email = sdkToken.email;
|
|
251
205
|
user.name = sdkToken.name;
|
|
252
|
-
//
|
|
253
|
-
|
|
254
|
-
// Admin user
|
|
255
|
-
user.role = sdkToken.role;
|
|
256
|
-
user.emailVerified = true; // Admins don't need email verification
|
|
257
|
-
// Phase 4: propagate session version so requireAdmin can
|
|
258
|
-
// compare it against the DB row.
|
|
259
|
-
user.sessionVersion = sdkToken.sessionVersion ?? 0;
|
|
260
|
-
}
|
|
261
|
-
else {
|
|
262
|
-
// Customer user
|
|
263
|
-
user.role = undefined;
|
|
264
|
-
// Convert string back to boolean for session
|
|
265
|
-
user.emailVerified = !!sdkToken.emailVerified;
|
|
266
|
-
}
|
|
206
|
+
// Convert string back to boolean for session
|
|
207
|
+
user.emailVerified = !!sdkToken.emailVerified;
|
|
267
208
|
}
|
|
268
209
|
return session;
|
|
269
210
|
},
|
|
@@ -299,4 +240,16 @@ export function createAuthOptions(options = {}) {
|
|
|
299
240
|
export async function getCustomerSession(customerId) {
|
|
300
241
|
return findCustomerForSession(customerId);
|
|
301
242
|
}
|
|
243
|
+
// =============================================================================
|
|
244
|
+
// Backward-compat alias
|
|
245
|
+
// =============================================================================
|
|
246
|
+
/**
|
|
247
|
+
* @deprecated Use `createCustomerAuthOptions()` instead. This alias returns
|
|
248
|
+
* the customer-only config, matching the pre-split behavior for storefront
|
|
249
|
+
* auth. Admin auth now lives at `createAdminAuthOptions()` in the admin
|
|
250
|
+
* module and mounts a separate NextAuth endpoint.
|
|
251
|
+
*/
|
|
252
|
+
export function createAuthOptions(options = {}) {
|
|
253
|
+
return createCustomerAuthOptions(options);
|
|
254
|
+
}
|
|
302
255
|
//# sourceMappingURL=config.js.map
|
package/dist/auth/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,mBAAmB,MAAM,iCAAiC,CAAA;AACjE,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAGxF,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF;;GAEG;AACH,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;AAE5C;;GAEG;AACH,MAAM,mBAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;AAE7C,6DAA6D;AAC7D,4EAA4E;AAC5E,qEAAqE;AACrE,2EAA2E;AAC3E,4CAA4C;AAE5C,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,mBAAmB,MAAM,iCAAiC,CAAA;AACjE,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAGxF,gFAAgF;AAChF,YAAY;AACZ,gFAAgF;AAEhF;;GAEG;AACH,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;AAE5C;;GAEG;AACH,MAAM,mBAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;AAE7C,6DAA6D;AAC7D,4EAA4E;AAC5E,qEAAqE;AACrE,2EAA2E;AAC3E,4CAA4C;AAE5C,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,yBAAyB,CACvC,UAA6B,EAAE;IAE/B,MAAM,EACJ,aAAa,GAAG,uBAAuB,EACvC,gBAAgB,GAAG,mBAAmB,EACtC,wBAAwB,GAAG,IAAI,EAC/B,UAAU,GAAG,cAAc,EAC3B,SAAS,GAAG,cAAc,GAC3B,GAAG,OAAO,CAAA;IAEX,OAAO;QACL,SAAS,EAAE;YACT,mBAAmB,CAAC;gBAClB,EAAE,EAAE,aAAa;gBACjB,IAAI,EAAE,aAAa;gBACnB,WAAW,EAAE;oBACX,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE;oBACxC,QAAQ,EAAE,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE;oBACjD,UAAU,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,UAAU,EAAE;iBACvD;gBACD,KAAK,CAAC,SAAS,CAAC,WAAW;oBACzB,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,CAAC;wBAClD,OAAO,IAAI,CAAA;oBACb,CAAC;oBAED,MAAM,MAAM,GAAG,MAAM,oBAAoB,CACvC,WAAW,CAAC,KAAK,EACjB,WAAW,CAAC,QAAQ,EACpB,wBAAwB,CACzB,CAAA;oBAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;wBACpB,uDAAuD;wBACvD,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;oBACvD,CAAC;oBAED,iCAAiC;oBACjC,sEAAsE;oBACtE,OAAO;wBACL,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;wBACtB,KAAK,EAAE,MAAM,CAAC,QAAQ,CAAC,KAAK;wBAC5B,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,IAAI,SAAS;wBACvC,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,aAAa;wBAC5C,0CAA0C;wBAC1C,UAAU,EAAE,WAAW,CAAC,UAAU,KAAK,MAAM;qBAC3B,CAAA;gBACtB,CAAC;aACF,CAAC;SACH;QAED,0EAA0E;QAC1E,sEAAsE;QACtE,oEAAoE;QACpE,oEAAoE;QACpE,yEAAyE;QACzE,OAAO,EAAE;YACP,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,gBAAgB;SACzB;QAED,GAAG,EAAE;YACH,MAAM,EAAE,gBAAgB;SACzB;QAED,KAAK,EAAE;YACL,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,SAAS;SACjB;QAED,4EAA4E;QAC5E,mEAAmE;QACnE,4EAA4E;QAC5E,kEAAkE;QAClE,0DAA0D;QAC1D,yDAAyD;QACzD,EAAE;QACF,oEAAoE;QACpE,oEAAoE;QACpE,OAAO,EAAE;YACP,YAAY,EAAE;gBACZ,IAAI,EAAE,wCAAwC;gBAC9C,OAAO,EAAE;oBACP,QAAQ,EAAE,IAAI;oBACd,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,GAAG;oBACT,MAAM,EAAE,IAAI;iBACb;aACF;YACD,WAAW,EAAE;gBACX,IAAI,EAAE,uCAAuC;gBAC7C,OAAO,EAAE;oBACP,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,GAAG;oBACT,MAAM,EAAE,IAAI;iBACb;aACF;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,mCAAmC;gBACzC,OAAO,EAAE;oBACP,QAAQ,EAAE,IAAI;oBACd,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,GAAG;oBACT,MAAM,EAAE,IAAI;iBACb;aACF;SACF;QAED,SAAS,EAAE;YACT,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE;gBACzC,2CAA2C;gBAC3C,MAAM,QAAQ,GAAG,KAA0B,CAAA;gBAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;gBAEzC,kBAAkB;gBAClB,IAAI,IAAI,EAAE,CAAC;oBACT,gDAAgD;oBAChD,MAAM,OAAO,GAAG,IAAe,CAAA;oBAC/B,QAAQ,CAAC,EAAE,GAAG,IAAI,CAAC,EAAE,CAAA;oBACrB,QAAQ,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,SAAS,CAAA;oBACxC,QAAQ,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,SAAS,CAAA;oBAEtC,0DAA0D;oBAC1D,+DAA+D;oBAC/D,0DAA0D;oBAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;oBAC9C,QAAQ,CAAC,UAAU,GAAG,UAAU,CAAA;oBAChC,QAAQ,CAAC,WAAW,GAAG,GAAG,CAAA;oBAE1B,kEAAkE;oBAClE,+CAA+C;oBAC/C,QAAQ,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa;wBAC5C,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa,YAAY,IAAI;4BACtC,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,WAAW,EAAE;4BACrC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;wBAClC,CAAC,CAAC,IAAI,CAAA;oBAER,+DAA+D;oBAC/D,8DAA8D;oBAC9D,oDAAoD;oBACpD,MAAM,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAA;oBACrE,QAAQ,CAAC,GAAG,GAAG,GAAG,GAAG,eAAe,CAAA;gBACtC,CAAC;qBAAM,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC;oBAChC,6DAA6D;oBAC7D,+DAA+D;oBAC/D,6DAA6D;oBAC7D,+DAA+D;oBAC/D,uDAAuD;oBACvD,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;oBAC/C,MAAM,eAAe,GAAG,UAAU,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,aAAa,CAAA;oBACrE,QAAQ,CAAC,GAAG,GAAG,QAAQ,CAAC,WAAW,GAAG,eAAe,CAAA;gBACvD,CAAC;gBAED,gCAAgC;gBAChC,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,EAAE,CAAC;oBACpC,8BAA8B;oBAC9B,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;wBAC/B,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;oBAC9B,CAAC;oBACD,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;wBACxC,QAAQ,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa;4BAC5C,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC;4BAC/B,CAAC,CAAC,IAAI,CAAA;oBACV,CAAC;gBACH,CAAC;gBAED,OAAO,KAAK,CAAA;YACd,CAAC;YAED,KAAK,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;gBAC9B,kEAAkE;gBAClE,oEAAoE;gBACpE,mEAAmE;gBACnE,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,QAAQ,GAAG,KAA0B,CAAA;oBAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,IAAuC,CAAA;oBAC5D,IAAI,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAY,CAAA;oBAC/B,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,KAAe,CAAA;oBACrC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAA;oBACzB,6CAA6C;oBAC7C,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAA;gBAC/C,CAAC;gBAED,OAAO,OAAO,CAAA;YAChB,CAAC;SACF;QAED,MAAM,EAAE;YACN,+BAA+B;YAC/B,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE;gBACnB,OAAO,CAAC,GAAG,CAAC,8BAA8B,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;YACzD,CAAC;YACD,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE;gBACrB,OAAO,CAAC,GAAG,CAAC,+BAA+B,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;YAC5D,CAAC;SACF;QAED,8BAA8B;QAC9B,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa;KAC9C,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAAkB;IAElB,OAAO,sBAAsB,CAAC,UAAU,CAAC,CAAA;AAC3C,CAAC;AA4DD,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAA6B,EAAE;IAE/B,OAAO,yBAAyB,CAAC,OAAO,CAAC,CAAA;AAC3C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../../src/auth/hooks/useAuth.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,aAAa,EAUd,MAAM,UAAU,CAAA;AAMjB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,OAAO,IAAI,aAAa,
|
|
1
|
+
{"version":3,"file":"useAuth.d.ts","sourceRoot":"","sources":["../../../src/auth/hooks/useAuth.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,aAAa,EAUd,MAAM,UAAU,CAAA;AAMjB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,OAAO,IAAI,aAAa,CAkPvC"}
|
|
@@ -44,10 +44,20 @@ export function useAuth() {
|
|
|
44
44
|
const status = sessionResult?.status ?? 'loading';
|
|
45
45
|
const update = sessionResult?.update;
|
|
46
46
|
// Memoized customer data
|
|
47
|
-
//
|
|
47
|
+
//
|
|
48
|
+
// Role filter: an admin JWT never reaches this hook post-0.3.20 because
|
|
49
|
+
// admin auth lives in a separate cookie. This filter is a belt-and-braces
|
|
50
|
+
// guard for legacy tokens or any future cross-contamination: if the
|
|
51
|
+
// session carries a `role` field, treat it as NOT a customer session —
|
|
52
|
+
// so components like the account page, checkout email prefill, and the
|
|
53
|
+
// storefront header never render admin identity as if it were a customer.
|
|
54
|
+
//
|
|
55
|
+
// Use double cast to avoid type conflicts with parent project's type declarations.
|
|
48
56
|
const customer = useMemo(() => {
|
|
49
57
|
if (!session?.user)
|
|
50
58
|
return null;
|
|
59
|
+
if (session.user.role)
|
|
60
|
+
return null;
|
|
51
61
|
return session.user;
|
|
52
62
|
}, [session?.user]);
|
|
53
63
|
// Derived state
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAuth.js","sourceRoot":"","sources":["../../../src/auth/hooks/useAuth.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,cAAc,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAclG,gFAAgF;AAChF,sBAAsB;AACtB,gFAAgF;AAEhF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,UAAU,OAAO;IACrB,2EAA2E;IAC3E,MAAM,aAAa,GAAG,UAAU,EAAE,CAAA;IAClC,MAAM,OAAO,GAAG,aAAa,EAAE,IAAI,IAAI,IAAI,CAAA;IAC3C,MAAM,MAAM,GAAG,aAAa,EAAE,MAAM,IAAI,SAAS,CAAA;IACjD,MAAM,MAAM,GAAG,aAAa,EAAE,MAAM,CAAA;IAEpC,yBAAyB;IACzB,
|
|
1
|
+
{"version":3,"file":"useAuth.js","sourceRoot":"","sources":["../../../src/auth/hooks/useAuth.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
* ```
|
|
37
37
|
*/
|
|
38
38
|
export type { CustomerSession, AuthSession, AuthState, SignInOptions, SignInResult, SignUpData, SignUpResult, PasswordResetRequestResult, PasswordResetResult, TokenValidationResult, VerifyEmailResult, ResendVerificationResult, SignInFormProps, SignUpFormProps, ForgotPasswordFormProps, ResetPasswordFormProps, VerifyEmailNoticeProps, UserMenuProps, AuthGuardProps, AuthApiError, RegisterRequest, RegisterResponse, VerifyEmailResponse, ForgotPasswordRequest, ResetPasswordRequest, AuthConfigOptions, UseAuthReturn, } from './types';
|
|
39
|
-
export { createAuthOptions,
|
|
39
|
+
export { createCustomerAuthOptions, createAuthOptions, // @deprecated alias for createCustomerAuthOptions — kept for SDK-API compatibility
|
|
40
|
+
getCustomerSession, } from './config';
|
|
40
41
|
export { createAuthHandlers } from './api/auth';
|
|
41
42
|
export { POST as registerPOST } from './api/register';
|
|
42
43
|
export { GET as verifyEmailGET, POST as verifyEmailPOST } from './api/verify-email';
|
package/dist/auth/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAMH,YAAY,EAEV,eAAe,EACf,WAAW,EACX,SAAS,EAGT,aAAa,EACb,YAAY,EAGZ,UAAU,EACV,YAAY,EAGZ,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EAGrB,iBAAiB,EACjB,wBAAwB,EAGxB,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,EACb,cAAc,EAGd,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EAGpB,iBAAiB,EAGjB,aAAa,GACd,MAAM,SAAS,CAAA;AAMhB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAMH,YAAY,EAEV,eAAe,EACf,WAAW,EACX,SAAS,EAGT,aAAa,EACb,YAAY,EAGZ,UAAU,EACV,YAAY,EAGZ,0BAA0B,EAC1B,mBAAmB,EACnB,qBAAqB,EAGrB,iBAAiB,EACjB,wBAAwB,EAGxB,eAAe,EACf,eAAe,EACf,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,EACb,cAAc,EAGd,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,oBAAoB,EAGpB,iBAAiB,EAGjB,aAAa,GACd,MAAM,SAAS,CAAA;AAMhB,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EAAE,mFAAmF;AACtG,kBAAkB,GACnB,MAAM,UAAU,CAAA;AAMjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAG/C,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,EAAE,GAAG,IAAI,cAAc,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACnF,OAAO,EAAE,IAAI,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAC1E,OAAO,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,IAAI,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAMzF,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAMzC,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA"}
|
package/dist/auth/index.js
CHANGED
|
@@ -38,7 +38,8 @@
|
|
|
38
38
|
// =============================================================================
|
|
39
39
|
// Configuration
|
|
40
40
|
// =============================================================================
|
|
41
|
-
export { createAuthOptions,
|
|
41
|
+
export { createCustomerAuthOptions, createAuthOptions, // @deprecated alias for createCustomerAuthOptions — kept for SDK-API compatibility
|
|
42
|
+
getCustomerSession, } from './config';
|
|
42
43
|
// =============================================================================
|
|
43
44
|
// API Route Handlers
|
|
44
45
|
// =============================================================================
|
package/dist/auth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAqDH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAqDH,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,OAAO,EACL,yBAAyB,EACzB,iBAAiB,EAAE,mFAAmF;AACtG,kBAAkB,GACnB,MAAM,UAAU,CAAA;AAEjB,gFAAgF;AAChF,qBAAqB;AACrB,gFAAgF;AAEhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE/C,mDAAmD;AACnD,OAAO,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,EAAE,GAAG,IAAI,cAAc,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACnF,OAAO,EAAE,IAAI,IAAI,sBAAsB,EAAE,MAAM,2BAA2B,CAAA;AAC1E,OAAO,EAAE,IAAI,IAAI,kBAAkB,EAAE,MAAM,uBAAuB,CAAA;AAClE,OAAO,EAAE,GAAG,IAAI,gBAAgB,EAAE,IAAI,IAAI,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAEzF,gFAAgF;AAChF,eAAe;AACf,gFAAgF;AAEhF,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEzC,gFAAgF;AAChF,gBAAgB;AAChB,gFAAgF;AAEhF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAA;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rovela-ai/sdk/auth/server/customer-session
|
|
3
|
+
*
|
|
4
|
+
* Centralized session check for customer-side API routes and Server
|
|
5
|
+
* Components. Mirror of `requireAdmin()` on the admin side.
|
|
6
|
+
*
|
|
7
|
+
* # Why this exists
|
|
8
|
+
*
|
|
9
|
+
* Before this helper, customer API routes each had their own inline
|
|
10
|
+
* "check session.user.id, optionally check session.user.role" scaffolding.
|
|
11
|
+
* Some of them (e.g. `/api/account/orders`) simply checked `session.user.id`
|
|
12
|
+
* and trusted whatever was there — including an admin session that happened
|
|
13
|
+
* to be in the single shared cookie. Result: admin JWTs silently succeeded
|
|
14
|
+
* on customer endpoints, returning "no orders" for the admin UUID rather
|
|
15
|
+
* than rejecting the request.
|
|
16
|
+
*
|
|
17
|
+
* Post-0.3.20 the admin cookie lives at a different name entirely
|
|
18
|
+
* (`__Secure-rovela.admin.session-token`), so an admin JWT CANNOT reach
|
|
19
|
+
* this helper because `getServerSession(createCustomerAuthOptions())` only
|
|
20
|
+
* reads the customer cookie (`__Secure-rovela.customer.session-token`).
|
|
21
|
+
* The `role` check below is belt-and-braces for legacy tokens still in
|
|
22
|
+
* flight during the fleet-wide cookie-name rollout.
|
|
23
|
+
*
|
|
24
|
+
* # Return contract
|
|
25
|
+
*
|
|
26
|
+
* Discriminated union, same as `requireAdmin`:
|
|
27
|
+
* - `{ ok: true, customer }` — caller proceeds
|
|
28
|
+
* - `{ ok: false, response }` — caller returns `response` directly
|
|
29
|
+
*
|
|
30
|
+
* Never throws — any internal error converts to a safe response.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* export async function GET() {
|
|
35
|
+
* const guard = await requireCustomer()
|
|
36
|
+
* if (!guard.ok) return guard.response
|
|
37
|
+
* const { customer } = guard
|
|
38
|
+
* const orders = await findOrders({ customerId: customer.id })
|
|
39
|
+
* return Response.json({ orders })
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
import { NextResponse } from 'next/server';
|
|
44
|
+
/**
|
|
45
|
+
* Shape of the verified customer returned on success. Deliberately a subset
|
|
46
|
+
* of the full customer row so callers don't accidentally leak sensitive
|
|
47
|
+
* fields (passwordHash, emailVerifiedAt timestamp, etc).
|
|
48
|
+
*/
|
|
49
|
+
export interface VerifiedCustomer {
|
|
50
|
+
id: string;
|
|
51
|
+
email: string;
|
|
52
|
+
name: string | null;
|
|
53
|
+
emailVerified: boolean;
|
|
54
|
+
}
|
|
55
|
+
export type RequireCustomerResult = {
|
|
56
|
+
ok: true;
|
|
57
|
+
customer: VerifiedCustomer;
|
|
58
|
+
} | {
|
|
59
|
+
ok: false;
|
|
60
|
+
response: NextResponse<{
|
|
61
|
+
error: string;
|
|
62
|
+
code: string;
|
|
63
|
+
}>;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Authenticate the current request as a customer.
|
|
67
|
+
*
|
|
68
|
+
* Resolves with either `{ ok: true, customer }` (caller may proceed) or
|
|
69
|
+
* `{ ok: false, response }` (caller returns the response to the client).
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```ts
|
|
73
|
+
* export async function GET() {
|
|
74
|
+
* const guard = await requireCustomer()
|
|
75
|
+
* if (!guard.ok) return guard.response
|
|
76
|
+
* // ...proceed with guard.customer
|
|
77
|
+
* }
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
export declare function requireCustomer(): Promise<RequireCustomerResult>;
|
|
81
|
+
//# sourceMappingURL=customer-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"customer-session.d.ts","sourceRoot":"","sources":["../../../src/auth/server/customer-session.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAS1C;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GACxC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,YAAY,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAAA;AAwB1E;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,qBAAqB,CAAC,CA6CtE"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @rovela-ai/sdk/auth/server/customer-session
|
|
3
|
+
*
|
|
4
|
+
* Centralized session check for customer-side API routes and Server
|
|
5
|
+
* Components. Mirror of `requireAdmin()` on the admin side.
|
|
6
|
+
*
|
|
7
|
+
* # Why this exists
|
|
8
|
+
*
|
|
9
|
+
* Before this helper, customer API routes each had their own inline
|
|
10
|
+
* "check session.user.id, optionally check session.user.role" scaffolding.
|
|
11
|
+
* Some of them (e.g. `/api/account/orders`) simply checked `session.user.id`
|
|
12
|
+
* and trusted whatever was there — including an admin session that happened
|
|
13
|
+
* to be in the single shared cookie. Result: admin JWTs silently succeeded
|
|
14
|
+
* on customer endpoints, returning "no orders" for the admin UUID rather
|
|
15
|
+
* than rejecting the request.
|
|
16
|
+
*
|
|
17
|
+
* Post-0.3.20 the admin cookie lives at a different name entirely
|
|
18
|
+
* (`__Secure-rovela.admin.session-token`), so an admin JWT CANNOT reach
|
|
19
|
+
* this helper because `getServerSession(createCustomerAuthOptions())` only
|
|
20
|
+
* reads the customer cookie (`__Secure-rovela.customer.session-token`).
|
|
21
|
+
* The `role` check below is belt-and-braces for legacy tokens still in
|
|
22
|
+
* flight during the fleet-wide cookie-name rollout.
|
|
23
|
+
*
|
|
24
|
+
* # Return contract
|
|
25
|
+
*
|
|
26
|
+
* Discriminated union, same as `requireAdmin`:
|
|
27
|
+
* - `{ ok: true, customer }` — caller proceeds
|
|
28
|
+
* - `{ ok: false, response }` — caller returns `response` directly
|
|
29
|
+
*
|
|
30
|
+
* Never throws — any internal error converts to a safe response.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```ts
|
|
34
|
+
* export async function GET() {
|
|
35
|
+
* const guard = await requireCustomer()
|
|
36
|
+
* if (!guard.ok) return guard.response
|
|
37
|
+
* const { customer } = guard
|
|
38
|
+
* const orders = await findOrders({ customerId: customer.id })
|
|
39
|
+
* return Response.json({ orders })
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
import { NextResponse } from 'next/server';
|
|
44
|
+
import { getServerSession } from 'next-auth';
|
|
45
|
+
import { createCustomerAuthOptions } from '../config';
|
|
46
|
+
import { findCustomerById } from './customer-service';
|
|
47
|
+
// =============================================================================
|
|
48
|
+
// Response helpers
|
|
49
|
+
// =============================================================================
|
|
50
|
+
function unauthorized() {
|
|
51
|
+
return NextResponse.json({ error: 'Unauthorized', code: 'UNAUTHORIZED' }, { status: 401 });
|
|
52
|
+
}
|
|
53
|
+
function forbidden() {
|
|
54
|
+
return NextResponse.json({ error: 'Forbidden', code: 'FORBIDDEN' }, { status: 403 });
|
|
55
|
+
}
|
|
56
|
+
// =============================================================================
|
|
57
|
+
// Main helper
|
|
58
|
+
// =============================================================================
|
|
59
|
+
/**
|
|
60
|
+
* Authenticate the current request as a customer.
|
|
61
|
+
*
|
|
62
|
+
* Resolves with either `{ ok: true, customer }` (caller may proceed) or
|
|
63
|
+
* `{ ok: false, response }` (caller returns the response to the client).
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* export async function GET() {
|
|
68
|
+
* const guard = await requireCustomer()
|
|
69
|
+
* if (!guard.ok) return guard.response
|
|
70
|
+
* // ...proceed with guard.customer
|
|
71
|
+
* }
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
export async function requireCustomer() {
|
|
75
|
+
let rawSession;
|
|
76
|
+
try {
|
|
77
|
+
rawSession = await getServerSession(createCustomerAuthOptions());
|
|
78
|
+
}
|
|
79
|
+
catch (err) {
|
|
80
|
+
console.error('[requireCustomer] Failed to read session:', err);
|
|
81
|
+
return { ok: false, response: unauthorized() };
|
|
82
|
+
}
|
|
83
|
+
const sessionUser = rawSession?.user;
|
|
84
|
+
if (!sessionUser?.id) {
|
|
85
|
+
return { ok: false, response: unauthorized() };
|
|
86
|
+
}
|
|
87
|
+
// Defense in depth: an admin cookie cannot reach this endpoint by
|
|
88
|
+
// design (separate cookie jar), but if a legacy token with a `role`
|
|
89
|
+
// field somehow decodes in this context, treat it as forbidden rather
|
|
90
|
+
// than render customer UI with admin identity.
|
|
91
|
+
if (sessionUser.role) {
|
|
92
|
+
return { ok: false, response: forbidden() };
|
|
93
|
+
}
|
|
94
|
+
// Re-validate the customer exists in the DB. Catches orphan JWTs where
|
|
95
|
+
// the customer row was deleted after the token was minted.
|
|
96
|
+
let customer;
|
|
97
|
+
try {
|
|
98
|
+
const row = await findCustomerById(sessionUser.id);
|
|
99
|
+
if (!row) {
|
|
100
|
+
return { ok: false, response: unauthorized() };
|
|
101
|
+
}
|
|
102
|
+
customer = {
|
|
103
|
+
id: row.id,
|
|
104
|
+
email: row.email,
|
|
105
|
+
name: row.name ?? null,
|
|
106
|
+
emailVerified: !!row.emailVerified,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
console.error('[requireCustomer] Failed to load customer row:', err);
|
|
111
|
+
return { ok: false, response: unauthorized() };
|
|
112
|
+
}
|
|
113
|
+
return { ok: true, customer };
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=customer-session.js.map
|