From d67b4fd91dda1b77f76b3ed442d73faa4e39b4f5 Mon Sep 17 00:00:00 2001 From: Joe Averbukh Date: Thu, 19 Mar 2026 18:35:09 -0700 Subject: [PATCH 1/2] Add e2e tests for extraFields and consumeMagicCode --- .../src/auth-extra-fields.e2e.test.ts | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 client/packages/core/__tests__/src/auth-extra-fields.e2e.test.ts diff --git a/client/packages/core/__tests__/src/auth-extra-fields.e2e.test.ts b/client/packages/core/__tests__/src/auth-extra-fields.e2e.test.ts new file mode 100644 index 0000000000..7d9616db95 --- /dev/null +++ b/client/packages/core/__tests__/src/auth-extra-fields.e2e.test.ts @@ -0,0 +1,134 @@ +import { expect } from 'vitest'; +import { i } from '../../src'; +import { makeE2ETest, apiUrl } from './utils/e2e'; + +const schema = i.schema({ + entities: { + $users: i.entity({ + email: i.string().unique().indexed().optional(), + username: i.string().unique().indexed().optional(), + displayName: i.string().optional(), + }), + }, +}); + +async function generateMagicCode( + appId: string, + adminToken: string, + email: string, +): Promise { + const res = await fetch(`${apiUrl}/admin/magic_code`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'app-id': appId, + authorization: `Bearer ${adminToken}`, + }, + body: JSON.stringify({ email }), + }); + const data = await res.json(); + return data.code; +} + +const authTest = makeE2ETest({ schema }); + +authTest( + 'new user with extraFields gets fields written and created=true', + async ({ db, appId, adminToken }) => { + const email = `new-${Date.now()}@test.com`; + + const code = await generateMagicCode(appId, adminToken, email); + const res = await db.auth.signInWithMagicCode({ + email, + code, + extraFields: { username: 'cool_user', displayName: 'Cool User' }, + }); + + expect(res.created).toBe(true); + + const { data } = await db.queryOnce({ $users: {} }); + const user = data.$users.find((u: any) => u.email === email); + expect(user).toBeDefined(); + expect(user!.username).toBe('cool_user'); + expect(user!.displayName).toBe('Cool User'); + }, +); + +authTest( + 'returning user gets created=false', + async ({ db, appId, adminToken }) => { + const email = `returning-${Date.now()}@test.com`; + + // First sign in -- creates user + const code1 = await generateMagicCode(appId, adminToken, email); + const res1 = await db.auth.signInWithMagicCode({ email, code: code1 }); + expect(res1.created).toBe(true); + + // Second sign in -- existing user + const code2 = await generateMagicCode(appId, adminToken, email); + const res2 = await db.auth.signInWithMagicCode({ email, code: code2 }); + expect(res2.created).toBe(false); + }, +); + +authTest( + 'sign in without extraFields works (backwards compat)', + async ({ db, appId, adminToken }) => { + const email = `compat-${Date.now()}@test.com`; + + const code = await generateMagicCode(appId, adminToken, email); + const res = await db.auth.signInWithMagicCode({ email, code }); + + expect(res.user).toBeDefined(); + expect(res.user.email).toBe(email); + }, +); + +authTest( + 'admin verify_magic_code returns { user, created } for checkMagicCode', + async ({ db: _db, appId, adminToken }) => { + const email = `admin-consume-${Date.now()}@test.com`; + const code = await generateMagicCode(appId, adminToken, email); + + // Hit the admin endpoint directly (same as admin SDK checkMagicCode) + const res = await fetch( + `${apiUrl}/admin/verify_magic_code?app_id=${appId}`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + authorization: `Bearer ${adminToken}`, + }, + body: JSON.stringify({ + email, + code, + 'extra-fields': { username: 'admin_user' }, + }), + }, + ); + const data = await res.json(); + + // Response should have user nested (not splatted) and created flag + expect(data.user).toBeDefined(); + expect(data.user.email).toBe(email); + expect(data.created).toBe(true); + + // Second call -- existing user + const code2 = await generateMagicCode(appId, adminToken, email); + const res2 = await fetch( + `${apiUrl}/admin/verify_magic_code?app_id=${appId}`, + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + authorization: `Bearer ${adminToken}`, + }, + body: JSON.stringify({ email, code: code2 }), + }, + ); + const data2 = await res2.json(); + + expect(data2.user).toBeDefined(); + expect(data2.created).toBe(false); + }, +); From 8a83be9ef043f7f46f0b7ecd1b286fcc77782940 Mon Sep 17 00:00:00 2001 From: Joe Averbukh Date: Fri, 20 Mar 2026 15:38:29 -0700 Subject: [PATCH 2/2] bump v0.22.168 --- client/packages/version/src/version.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/packages/version/src/version.ts b/client/packages/version/src/version.ts index b917f15cc6..402a2289bf 100644 --- a/client/packages/version/src/version.ts +++ b/client/packages/version/src/version.ts @@ -2,6 +2,6 @@ // Update the version here and merge your code to main to // publish a new version of all of the packages to npm. -const version = 'v0.22.167'; +const version = 'v0.22.168'; export { version };