Bug Description
When allowNewUserRegistration is set to true in the OTP plugin settings, the /auth/otp/request endpoint correctly generates an OTP code and sends the verification email to new (unregistered) email addresses. However, when the user submits the code to /auth/otp/verify, it returns a 404 "User not found" error because the user record was never created in the users table.
Steps to Reproduce
- Enable new user registration in the OTP plugin: set
allowNewUserRegistration: true in the plugins table settings for otp-login
- Request an OTP for an email that has no existing user record (e.g.,
newuser@example.com)
- OTP code is generated in
otp_codes table and email is sent ✅
- Submit the received code to
/auth/otp/verify with the same email
- Result: 404
"User not found" — verification fails
Root Cause
In the OTP request handler (/auth/otp/request), when allowNewUserRegistration is true, the code skips the early return for unknown emails and proceeds to generate + send the OTP. But it never creates a user record.
Then in the verify handler (/auth/otp/verify), after the code is validated successfully, the handler queries:
const user = await db.prepare('SELECT id, email, role, is_active FROM users WHERE email = ?')
.bind(normalizedEmail).first();
if (!user) {
return c.json({ error: "User not found" }, 404);
}
Since no user was ever created, this always fails for new registrations.
Expected Behavior
When allowNewUserRegistration is true and a valid OTP code is verified for an email with no existing user, the verify endpoint should auto-create a new user record (with role viewer, is_active: 1, email_verified: 1) and then proceed with authentication.
Affected Code
- Request handler:
src/plugins/core-plugins/otp-login-plugin — correctly allows new emails through but doesn't create user
- Verify handler: Same plugin — expects user to exist, no fallback creation
Suggested Fix
In the /auth/otp/verify handler, after the code is verified as valid but before the user lookup, add user creation logic:
let user = await db.prepare('SELECT id, email, role, is_active FROM users WHERE email = ?')
.bind(normalizedEmail).first();
if (!user && settings.allowNewUserRegistration) {
const id = crypto.randomUUID();
const now = Date.now();
const username = normalizedEmail.split('@')[0] + '_' + id.slice(0, 6);
await db.prepare(
`INSERT INTO users (id, email, username, first_name, last_name, role, is_active, email_verified, created_at, updated_at)
VALUES (?, ?, ?, '', '', 'viewer', 1, 1, ?, ?)`
).bind(id, normalizedEmail, username, now, now).run();
user = { id, email: normalizedEmail, role: 'viewer', is_active: 1 };
}
if (!user) {
return c.json({ error: "User not found" }, 404);
}
Environment
- SonicJS version:
@sonicjs-cms/core@2.10.0
- Runtime: Cloudflare Workers
- Database: D1
Bug Description
When
allowNewUserRegistrationis set totruein the OTP plugin settings, the/auth/otp/requestendpoint correctly generates an OTP code and sends the verification email to new (unregistered) email addresses. However, when the user submits the code to/auth/otp/verify, it returns a 404"User not found"error because the user record was never created in theuserstable.Steps to Reproduce
allowNewUserRegistration: truein thepluginstable settings forotp-loginnewuser@example.com)otp_codestable and email is sent ✅/auth/otp/verifywith the same email"User not found"— verification failsRoot Cause
In the OTP request handler (
/auth/otp/request), whenallowNewUserRegistrationistrue, the code skips the early return for unknown emails and proceeds to generate + send the OTP. But it never creates a user record.Then in the verify handler (
/auth/otp/verify), after the code is validated successfully, the handler queries:Since no user was ever created, this always fails for new registrations.
Expected Behavior
When
allowNewUserRegistrationistrueand a valid OTP code is verified for an email with no existing user, the verify endpoint should auto-create a new user record (with roleviewer,is_active: 1,email_verified: 1) and then proceed with authentication.Affected Code
src/plugins/core-plugins/otp-login-plugin— correctly allows new emails through but doesn't create userSuggested Fix
In the
/auth/otp/verifyhandler, after the code is verified as valid but before the user lookup, add user creation logic:Environment
@sonicjs-cms/core@2.10.0