Making name mandatory in magic link registration

I’m trying to enforce that users provide a name when registering via magic link. Frontend validation isn’t enough, because it leaves the API exposed to registrations without a name. Is there a recommended way to make the name field required on registration while still using magic links for login? I’m currently using the default handler:
app.all("/api/auth/*splat", toNodeHandler(auth));
app.all("/api/auth/*splat", toNodeHandler(auth));
I’ve disabled email & password sign-in and sign-up, so I can’t use auth.api.signUpEmail to create new users. I want to avoid creating users with empty passwords in case I enable that method in the future.
Solution:
I haven't found an official solution or configuration that allows me to do that, but I've managed to do it with this workaround: This is the Express handler: ```js app.all("/api/auth/*splat", async (...args) => {...
Jump to solution
15 Replies
Solution
Moha
Moha2w ago
I haven't found an official solution or configuration that allows me to do that, but I've managed to do it with this workaround: This is the Express handler:
app.all("/api/auth/*splat", async (...args) => {
const [req, res] = args;

if (
req.method === "POST" &&
req.params.splat[0] === "sign-in" &&
req.params.splat[1] === "magic-link"
) {
const { data, error } = registerSchema.safeParse(req.body);
if (error) {
res.status(400).json({
code: "VALIDATION_ERROR",
message: "Invalid body parameters"
});
return;
}

const { email, name } = data;
const user = await db
.select()
.from(users)
.where(eq(users.email, email));

if (user.length === 0 && !name) {
return res.status(400).json({
code: "VALIDATION_ERROR",
message: "Invalid body parameters"
});
}
}

const handler = toNodeHandler(auth);
return handler(...args);
});
app.all("/api/auth/*splat", async (...args) => {
const [req, res] = args;

if (
req.method === "POST" &&
req.params.splat[0] === "sign-in" &&
req.params.splat[1] === "magic-link"
) {
const { data, error } = registerSchema.safeParse(req.body);
if (error) {
res.status(400).json({
code: "VALIDATION_ERROR",
message: "Invalid body parameters"
});
return;
}

const { email, name } = data;
const user = await db
.select()
.from(users)
.where(eq(users.email, email));

if (user.length === 0 && !name) {
return res.status(400).json({
code: "VALIDATION_ERROR",
message: "Invalid body parameters"
});
}
}

const handler = toNodeHandler(auth);
return handler(...args);
});
And this the Zod schema:
import { z } from "zod";

export const registerSchema = z.object({
email: z.email().optional(),
name: z
.string()
.trim()
.min(4, { message: "The name is required" })
.max(50, { message: "The name cannot exceed 50 characters" })
.optional(),
});
import { z } from "zod";

export const registerSchema = z.object({
email: z.email().optional(),
name: z
.string()
.trim()
.min(4, { message: "The name is required" })
.max(50, { message: "The name cannot exceed 50 characters" })
.optional(),
});
Better Auth
Better Auth2w ago
You’ll need to add your own server‐side check, because by default the magic link flow treats the name as optional if you’re not using email/password registration. In other words, since you’ve disabled the email & password endpoints, the built‑in validation (which enforces a name for email/password signups [9]) isn’t triggered for magic link requests. A common solution is to wrap or pre‑validate the incoming magic link requests (for example, with middleware) that inspects the payload and rejects requests that don’t include a non‑empty name. This way, even if someone bypasses your frontend checks, the API won’t create users without a name. You can then pass the validated request to the default Better Auth magic link handler (for example, via your existing route handler with toNodeHandler). Alternatively, if you’re open to extending the magic link plugin, you might look into implementing a custom “beforeCreateUser” hook (or similar) that checks for the required fields. This custom hook would be invoked during the registration flow and reject user creation if the name is missing. These approaches help maintain consistency in your user data—especially if you plan to support email & password sign-up in the future—ensuring that a name is always provided. [9]: Enforcing the name field is already part of the email & password sign-up flow to match the documentation, but that check isn’t applied when using magic links. [17]: The magic link flow itself allows a name to be optionally passed, so adding your own validation is the recommended way when you need to enforce required fields for your use case.
GitHub
Build software better, together
GitHub is where people build software. More than 150 million people use GitHub to discover, fork, and contribute to over 420 million projects.
From An unknown user
From An unknown user
From An unknown user
GitHub
better-auth/better-auth
The most comprehensive authentication framework for TypeScript - better-auth/better-auth
Better Auth
Better Auth2w ago
GitHub
Enforce required 'name' field for email/password signup (Fix #3336)...
The backend previously allowed users to sign up with only email and password, even though the documentation specifies that the name field is also required. This PR updates the backend validation to...
GitHub
Add name field to magic link · Issue #733 · better-auth/better-auth
Love your work team. I would like to have the option to add a name to the magic link sign in/sign up Describe alternatives you've considered I considered having a second step after the user ver...
begot
begot2w ago
@Moha ^
Moha
MohaOP2w ago
i already asked the AI but that solution didn't work for me
begot
begot2w ago
ah fair
Moha
MohaOP2w ago
although it said I needed to do my own checking, which is what I ended up doing 😅
begot
begot2w ago
yeah this seems like something that should be a feature imo
Moha
MohaOP2w ago
Yes, I think so too. I'll try to do a PR if I have time
begot
begot2w ago
maybe just make a before hook? if name is undefined throw an auth error i ended up making a lot of custom plugins for my apps, makes granular control much easier
Moha
MohaOP2w ago
I think these kinds of things would be better as built-in features. If I need granularity to the point of making my own plugins, I would rather create my own authentication from scratch
begot
begot2w ago
i agree that this should be built-in, but i think custom plugins are a great part of better-auth. for example, i wanted to ensure user emails aren't templ mails, which makes sense to do as a plugin
Moha
MohaOP2w ago
I'm not very knowledgeable about BA, I don't know how complex it is to create a plugin, so I didn't take it into account. I'll have to look into it
begot
begot2w ago
once you understand it its not as scary. i definitely recommend it as it helped me understand how BA works as a whole
Moha
MohaOP2w ago
I will definitely take a look at it

Did you find this page helpful?