-
Notifications
You must be signed in to change notification settings - Fork 330
Add e2e tests for extraFields and consumeMagicCode #2394
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
134 changes: 134 additions & 0 deletions
134
client/packages/core/__tests__/src/auth-extra-fields.e2e.test.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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<string> { | ||
| 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); | ||
| }, | ||
| ); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add explicit HTTP status assertions before JSON parsing.
Line 20, Line 94, and Line 118 parse JSON unconditionally. If backend/auth/deploy is misconfigured, failures become noisy parse errors instead of clear request failures.
🔧 Suggested patch
async function generateMagicCode( appId: string, adminToken: string, email: string, ): Promise<string> { const res = await fetch(`${apiUrl}/admin/magic_code`, { @@ body: JSON.stringify({ email }), }); + if (!res.ok) { + throw new Error(`/admin/magic_code failed (${res.status}): ${await res.text()}`); + } const data = await res.json(); return data.code; } @@ const res = await fetch( `${apiUrl}/admin/verify_magic_code?app_id=${appId}`, { @@ }, ); + if (!res.ok) { + throw new Error( + `/admin/verify_magic_code failed (${res.status}): ${await res.text()}`, + ); + } const data = await res.json(); @@ const res2 = await fetch( `${apiUrl}/admin/verify_magic_code?app_id=${appId}`, { @@ }, ); + if (!res2.ok) { + throw new Error( + `/admin/verify_magic_code failed (${res2.status}): ${await res2.text()}`, + ); + } const data2 = await res2.json();Also applies to: 94-109, 118-129
🤖 Prompt for AI Agents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitty / not-neccesary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nezaj, understood — acknowledged and moving on!🧠 Learnings used