From 8fba8fff2b0f1cfcf5f3a08af0e2e5ebf26d117c Mon Sep 17 00:00:00 2001 From: Alex Yang Date: Fri, 9 Jan 2026 10:03:34 -0800 Subject: [PATCH] fix(magic-link): return additional fields in `/magic-link/verify` endpoint --- .../src/plugins/magic-link/index.ts | 12 +--- .../src/plugins/magic-link/magic-link.test.ts | 71 +++++++++++++++++++ 2 files changed, 74 insertions(+), 9 deletions(-) diff --git a/packages/better-auth/src/plugins/magic-link/index.ts b/packages/better-auth/src/plugins/magic-link/index.ts index 107f70a095..14ec966533 100644 --- a/packages/better-auth/src/plugins/magic-link/index.ts +++ b/packages/better-auth/src/plugins/magic-link/index.ts @@ -8,6 +8,7 @@ import * as z from "zod"; import { originCheck } from "../../api"; import { setSessionCookie } from "../../cookies"; import { generateRandomString } from "../../crypto"; +import { parseSessionOutput, parseUserOutput } from "../../db"; import { defaultKeyHasher } from "./utils"; declare module "@better-auth/core" { @@ -402,15 +403,8 @@ export const magicLink = (options: MagicLinkOptions) => { if (!ctx.query.callbackURL) { return ctx.json({ token: session.token, - user: { - id: user.id, - email: user.email, - emailVerified: user.emailVerified, - name: user.name, - image: user.image, - createdAt: user.createdAt, - updatedAt: user.updatedAt, - }, + user: parseUserOutput(ctx.context.options, user), + session: parseSessionOutput(ctx.context.options, session), }); } if (isNewUser) { diff --git a/packages/better-auth/src/plugins/magic-link/magic-link.test.ts b/packages/better-auth/src/plugins/magic-link/magic-link.test.ts index c80947980a..030dea6855 100644 --- a/packages/better-auth/src/plugins/magic-link/magic-link.test.ts +++ b/packages/better-auth/src/plugins/magic-link/magic-link.test.ts @@ -272,6 +272,77 @@ describe("magic link", async () => { expect(customGenerateToken).toHaveBeenCalled(); expect(verificationEmail.token).toBe("custom_token"); }); + + it("should return additional fields", async () => { + const { customFetchImpl, sessionSetter, auth } = await getTestInstance({ + user: { + additionalFields: { + foo: { + type: "string", + required: false, + }, + }, + }, + plugins: [ + magicLink({ + async sendMagicLink(data) { + verificationEmail = data; + }, + }), + ], + }); + + const client = createAuthClient({ + plugins: [magicLinkClient()], + fetchOptions: { + customFetchImpl, + }, + baseURL: "http://localhost:3000/api/auth", + }); + + const email = "test-email@test.com"; + await client.signIn.magicLink({ + email, + }); + + const headers = new Headers(); + const response = await client.magicLink.verify({ + query: { + token: new URL(verificationEmail.url).searchParams.get("token") || "", + }, + fetchOptions: { + onSuccess: sessionSetter(headers), + }, + }); + + expect(response.data?.user).toBeDefined(); + // @ts-expect-error + expect(response.data?.user.foo).toBeNull(); + + await auth.api.updateUser({ + body: { + foo: "bar", + }, + headers, + }); + + await client.signIn.magicLink({ + email, + }); + { + const response = await client.magicLink.verify({ + query: { + token: new URL(verificationEmail.url).searchParams.get("token")!, + }, + fetchOptions: { + onSuccess: sessionSetter(headers), + }, + }); + + // @ts-expect-error + expect(response.data?.user.foo).toBe("bar"); + } + }); }); describe("magic link verify", async () => {