@nextsparkjs/core 0.1.0-beta.171 → 0.1.0-beta.172

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "generated": "2026-06-22T20:21:00.466Z",
2
+ "generated": "2026-06-22T23:25:01.851Z",
3
3
  "totalClasses": 1081,
4
4
  "classes": [
5
5
  "!text-2xl",
@@ -115,6 +115,13 @@ export async function POST(req: NextRequest) {
115
115
  const isOAuthCallback = pathname.includes('/api/auth/callback/');
116
116
  const isSignupRequest = isSignupAttempt || isOAuthCallback;
117
117
 
118
+ // A first-time OTP sign-in (emailOTP plugin with disableSignUp:false) auto-creates
119
+ // the user, so it is an implicit signup that can also carry an intent. It is a
120
+ // sign-in endpoint, so it is deliberately NOT part of `isSignupRequest` above
121
+ // (no registration-mode gating) — it only participates in the intent wrapping
122
+ // below, exactly like header/OAuth signup.
123
+ const isOtpSignin = pathname.includes('/sign-in/email-otp');
124
+
118
125
  if (isSignupRequest) {
119
126
  const registrationMode = AUTH_CONFIG?.registration?.mode ?? 'open';
120
127
  const teamsMode = TEAMS_CONFIG.mode;
@@ -160,10 +167,15 @@ export async function POST(req: NextRequest) {
160
167
  // Read the optional signup intent and run the signup within request-scoped
161
168
  // context so the user.create.after hook can map it to an initial team role
162
169
  // (AUTH_CONFIG.signupIntent). Header-based signup carries it in the
163
- // `x-signup-intent` header; OAuth callbacks (incl. form_post-mode providers
164
- // that POST the callback) can't, so they fall back to the `signup-intent`
165
- // cookie set by the client before the OAuth flow (see the GET handler).
166
- const signupIntent = isSignupAttempt
170
+ // `x-signup-intent` header; a first-time OTP sign-in carries it the same way
171
+ // (header preferred, `signup-intent` cookie fallback); OAuth callbacks (incl.
172
+ // form_post-mode providers that POST the callback) can't send a header, so
173
+ // they fall back to the cookie set by the client before the OAuth flow (see
174
+ // the GET handler). The value only ever maps to an app-configured role via
175
+ // roleMap (never an arbitrary role) and the user.create.after hook runs only
176
+ // when a user is actually created, so wrapping an existing-user sign-in is a
177
+ // no-op — there is no escalation surface.
178
+ const signupIntent = (isSignupAttempt || isOtpSignin)
167
179
  ? (req.headers.get('x-signup-intent') || req.cookies.get('signup-intent')?.value || undefined)
168
180
  : isOAuthCallback
169
181
  ? (req.cookies.get('signup-intent')?.value || undefined)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextsparkjs/core",
3
- "version": "0.1.0-beta.171",
3
+ "version": "0.1.0-beta.172",
4
4
  "description": "NextSpark - The complete SaaS framework for Next.js",
5
5
  "license": "MIT",
6
6
  "author": "NextSpark <hello@nextspark.dev>",
@@ -469,7 +469,7 @@
469
469
  "tailwind-merge": "^3.3.1",
470
470
  "uuid": "^13.0.0",
471
471
  "zod": "^4.1.5",
472
- "@nextsparkjs/testing": "0.1.0-beta.171"
472
+ "@nextsparkjs/testing": "0.1.0-beta.172"
473
473
  },
474
474
  "scripts": {
475
475
  "postinstall": "node scripts/postinstall.mjs || true",
@@ -115,6 +115,13 @@ export async function POST(req: NextRequest) {
115
115
  const isOAuthCallback = pathname.includes('/api/auth/callback/');
116
116
  const isSignupRequest = isSignupAttempt || isOAuthCallback;
117
117
 
118
+ // A first-time OTP sign-in (emailOTP plugin with disableSignUp:false) auto-creates
119
+ // the user, so it is an implicit signup that can also carry an intent. It is a
120
+ // sign-in endpoint, so it is deliberately NOT part of `isSignupRequest` above
121
+ // (no registration-mode gating) — it only participates in the intent wrapping
122
+ // below, exactly like header/OAuth signup.
123
+ const isOtpSignin = pathname.includes('/sign-in/email-otp');
124
+
118
125
  if (isSignupRequest) {
119
126
  const registrationMode = AUTH_CONFIG?.registration?.mode ?? 'open';
120
127
  const teamsMode = TEAMS_CONFIG.mode;
@@ -160,10 +167,15 @@ export async function POST(req: NextRequest) {
160
167
  // Read the optional signup intent and run the signup within request-scoped
161
168
  // context so the user.create.after hook can map it to an initial team role
162
169
  // (AUTH_CONFIG.signupIntent). Header-based signup carries it in the
163
- // `x-signup-intent` header; OAuth callbacks (incl. form_post-mode providers
164
- // that POST the callback) can't, so they fall back to the `signup-intent`
165
- // cookie set by the client before the OAuth flow (see the GET handler).
166
- const signupIntent = isSignupAttempt
170
+ // `x-signup-intent` header; a first-time OTP sign-in carries it the same way
171
+ // (header preferred, `signup-intent` cookie fallback); OAuth callbacks (incl.
172
+ // form_post-mode providers that POST the callback) can't send a header, so
173
+ // they fall back to the cookie set by the client before the OAuth flow (see
174
+ // the GET handler). The value only ever maps to an app-configured role via
175
+ // roleMap (never an arbitrary role) and the user.create.after hook runs only
176
+ // when a user is actually created, so wrapping an existing-user sign-in is a
177
+ // no-op — there is no escalation surface.
178
+ const signupIntent = (isSignupAttempt || isOtpSignin)
167
179
  ? (req.headers.get('x-signup-intent') || req.cookies.get('signup-intent')?.value || undefined)
168
180
  : isOAuthCallback
169
181
  ? (req.cookies.get('signup-intent')?.value || undefined)