diff --git a/src/App.test.tsx b/src/App.test.tsx index ff9af23..cfe0d2e 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -402,6 +402,27 @@ describe('OTP verification and validation', () => { await waitFor(() => expect(localStorage.getItem('token')).toBe('otp-token')); expect(await screen.findByText('OTP validated successfully')).toBeInTheDocument(); + await expectCodeVisible('UNUSED-CODE'); + }); + + it('loads invites after 2FA even when no token is returned', async () => { + server.use( + http.post(`${API_HOST}/api/auth/login`, () => + HttpResponse.json({ otp_enabled: true, otp_verified: true }) + ), + http.post(`${API_HOST}/api/auth/otp/validate`, () => HttpResponse.json({})) + ); + + render(); + fillLogin('twofa'); + await waitFor(() => + expect(screen.getByText('Two-Factor Authentication')).toBeInTheDocument() + ); + + fireEvent.change(screen.getByPlaceholderText('000000'), { target: { value: '123456' } }); + fireEvent.click(screen.getByRole('button', { name: 'Validate' })); + + await expectCodeVisible('UNUSED-CODE'); }); }); @@ -438,7 +459,7 @@ describe('used-by handle', () => { expect(link).toHaveAttribute('href', 'https://bsky.app/profile/alice.bsky.social'); }); - it('falls back to a dash when the API returns no handle', async () => { + it('falls back to the DID when the API returns no handle', async () => { const noHandle = [ { ...didInvites[0], uses: [{ usedBy: 'did:plc:abc', usedAt: '2026-01-25T08:12:55.280Z' }] }, ]; @@ -450,6 +471,8 @@ describe('used-by handle', () => { await expectCodeVisible('DID-CODE'); expect(screen.queryByRole('link', { name: 'alice.bsky.social' })).not.toBeInTheDocument(); + const link = screen.getAllByRole('link', { name: 'did:plc:abc' })[0]; + expect(link).toHaveAttribute('href', 'https://bsky.app/profile/did:plc:abc'); }); }); diff --git a/src/App.tsx b/src/App.tsx index 8c0e7df..6ed841b 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -415,9 +415,8 @@ function App() { URL.revokeObjectURL(url); }; - const isAdminPage = page === 'Admins'; useEffect(() => { - if (!token) { + if (page !== 'Home' && page !== 'Admins') { return; } let cancelled = false; @@ -433,7 +432,7 @@ function App() { return () => { cancelled = true; }; - }, [token, isAdminPage, fetchInvites, fetchAdmins]); + }, [page, fetchInvites, fetchAdmins]); useEffect(() => { if (!notice) { @@ -836,7 +835,7 @@ function App() { const status = getStatus(invite); const usedAt = getUsedAt(invite); const usedBy = getUsedBy(invite); - const resolvedHandle = getUsedByHandle(invite); + const usedByLabel = getUsedByHandle(invite) || usedBy; const accountStatus = getAccountStatus(invite); return (
- {resolvedHandle ? ( + {usedByLabel ? ( - {resolvedHandle} + {usedByLabel} ) : ( '-' @@ -902,14 +901,9 @@ function App() { {invite.uses?.[0]?.usedByEmail || '-'} - + {usedBy ? ( - - {usedBy} - + {usedBy} ) : ( '-' )} @@ -942,7 +936,7 @@ function App() { const status = getStatus(invite); const usedAt = getUsedAt(invite); const usedBy = getUsedBy(invite); - const resolvedHandle = getUsedByHandle(invite); + const usedByLabel = getUsedByHandle(invite) || usedBy; const accountStatus = getAccountStatus(invite); return (

- {resolvedHandle ? ( + {usedByLabel ? ( - {resolvedHandle} + {usedByLabel} ) : ( '-' @@ -1030,7 +1024,7 @@ function App() {

DID

-

+

{usedBy || '-'}