Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions jest.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,14 @@ import { TextEncoder, TextDecoder } from 'util';

(global as any).TextEncoder = TextEncoder;
(global as any).TextDecoder = TextDecoder;

(global as any).BroadcastChannel = class {
onmessage = null;
postMessage() {}
close() {}
};

beforeAll(() => {
jest.spyOn(console, 'error').mockImplementation(() => {});
jest.spyOn(console, 'warn').mockImplementation(() => {});
});
2 changes: 1 addition & 1 deletion src/AuthProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
} from 'react';

import { AuthMode, createFetchWithAuth } from './fetchWithAuth';
import LoadingSpinner from './LoadingSpinner';
import LoadingSpinner from './components/LoadingSpinner';
import { usePreviousSignIn } from './hooks/usePreviousSignIn';
import {
AuthenticatorTransportFuture,
Expand Down Expand Up @@ -189,7 +189,7 @@

useEffect(() => {
validateToken();
}, []);

Check warning on line 192 in src/AuthProvider.tsx

View workflow job for this annotation

GitHub Actions / test

React Hook useEffect has a missing dependency: 'validateToken'. Either include it or remove the dependency array

useEffect(() => {
if (user && isAuthenticated) {
Expand Down
20 changes: 12 additions & 8 deletions src/AuthRoutes.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { Navigate, Route, Routes } from 'react-router-dom';

import Login from '@/Login';
import MfaLogin from '@/MfaLogin';
import PassKeyLogin from '@/PassKeyLogin';
import RegisterPasskey from '@/RegisterPassKey';
import VerifyOTP from '@/VerifyOTP';
import Login from '@/views/Login';
import PassKeyLogin from '@/views/PassKeyLogin';
import PasskeyRegistration from '@/views/PassKeyRegistration';
import PhoneRegistration from '@/views/PhoneRegistration';
import EmailRegistration from '@/views/EmailRegistration';
import VerifyMagicLink from '@/views/VerifyMagicLink';
import MagicLinkSent from './components/MagicLinkSent';

export const AuthRoutes = () => (
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/passKeyLogin" element={<PassKeyLogin />} />
<Route path="/mfaLogin" element={<MfaLogin />} />
<Route path="/verifyOTP" element={<VerifyOTP />} />
<Route path="/registerPasskey" element={<RegisterPasskey />} />
<Route path="/verifyPhoneOTP" element={<PhoneRegistration />} />
<Route path="/verifyEmailOTP" element={<EmailRegistration />} />
<Route path="/verify-magiclink" element={<VerifyMagicLink />} />
<Route path="/registerPasskey" element={<PasskeyRegistration />} />
<Route path="/magic-link-sent" element={<MagicLinkSent />} />
<Route path="*" element={<Navigate to="/login" replace />} />
</Routes>
);
174 changes: 0 additions & 174 deletions src/MfaLogin.tsx

This file was deleted.

61 changes: 61 additions & 0 deletions src/components/AuthFallbackOptions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React from 'react';
import { isValidEmail, isValidPhoneNumber } from '../utils';

import styles from '../styles/login.module.css';

interface AuthFallbackOptionsProps {
identifier: string;
onMagicLink: () => void;
onPhoneOtp: () => void;
onPasskeyRetry: () => void;
}

const AuthFallbackOptions: React.FC<AuthFallbackOptionsProps> = ({
identifier,
onMagicLink,
onPhoneOtp,
onPasskeyRetry,
}) => {
const showMagicLink = isValidEmail(identifier);
const showPhoneOtp = isValidPhoneNumber(identifier);

return (
<div className={styles.fallbackCard}>
<div className={styles.fallbackHeader}>Passkeys unavailable on this device</div>

<p className={styles.fallbackDescription}>Choose another secure sign-in method.</p>

<div className={styles.fallbackActions}>
{showMagicLink && (
<button
type="button"
className={styles.fallbackActionButton}
onClick={onMagicLink}
>
<span className={styles.actionTitle}>Email Magic Link</span>
<span className={styles.actionSubtext}>
Send a secure sign-in link to your email
</span>
</button>
)}

{showPhoneOtp && (
<button
type="button"
className={styles.fallbackActionButton}
onClick={onPhoneOtp}
>
<span className={styles.actionTitle}>Text Message Code</span>
<span className={styles.actionSubtext}>Receive a one-time code via SMS</span>
</button>
)}
</div>

<button type="button" className={styles.linkButton} onClick={onPasskeyRetry}>
Try passkey anyway
</button>
</div>
);
};

export default AuthFallbackOptions;
File renamed without changes.
Loading
Loading