diff --git a/package-lock.json b/package-lock.json index 9289441..f57295a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@seamless-auth/react", - "version": "0.0.7", + "version": "0.0.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@seamless-auth/react", - "version": "0.0.7", + "version": "0.0.8", "license": "AGPL-3.0-only", "dependencies": { "@simplewebauthn/browser": "^13.1.0", @@ -5784,9 +5784,9 @@ } }, "node_modules/flatted": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.1.tgz", - "integrity": "sha512-IxfVbRFVlV8V/yRaGzk0UVIcsKKHMSfYw66T/u4nTwlWteQePsxe//LjudR1AMX4tZW3WFCh3Zqa/sjlqpbURQ==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, diff --git a/package.json b/package.json index 1b0f2b4..2fb6419 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@seamless-auth/react", - "version": "0.0.7", + "version": "0.0.8", "description": "A drop-in authentication solution for modern React applications.", "type": "module", "exports": { diff --git a/src/AuthProvider.tsx b/src/AuthProvider.tsx index 651bce6..53fac7b 100644 --- a/src/AuthProvider.tsx +++ b/src/AuthProvider.tsx @@ -9,7 +9,6 @@ import React, { } from 'react'; import { AuthMode, createFetchWithAuth } from './fetchWithAuth'; -import LoadingSpinner from './components/LoadingSpinner'; import { usePreviousSignIn } from './hooks/usePreviousSignIn'; import { AuthenticatorTransportFuture, @@ -42,6 +41,7 @@ export interface AuthContextType { credentials: Credential[]; updateCredential: (credential: Credential) => Promise; deleteCredential: (credentialId: string) => Promise; + loading: boolean; } export interface Credential { @@ -136,6 +136,7 @@ export const AuthProvider: React.FC = ({ const hasRole = (role: string) => user?.roles?.includes(role); const validateToken = async () => { + setLoading(true); try { const response = await fetchWithAuth(`users/me`, { method: 'GET', @@ -197,19 +198,12 @@ export const AuthProvider: React.FC = ({ } }, [user, isAuthenticated, markSignedIn]); - if (loading) { - return ( -
- ; -
- ); - } - return ( { - return ( -
-
-
- ); -}; - -export default LoadingSpinner; diff --git a/src/components/OtpInput.tsx b/src/components/OtpInput.tsx index 038c41d..1d17591 100644 --- a/src/components/OtpInput.tsx +++ b/src/components/OtpInput.tsx @@ -4,16 +4,28 @@ import styles from '@/styles/otpInput.module.css'; interface Props { length?: number; value: string; + inputMode?: 'numeric' | 'text'; onChange: (value: string) => void; } -const OtpInput: React.FC = ({ length = 6, value, onChange }) => { +const OtpInput: React.FC = ({ + length = 6, + value, + inputMode = 'numeric', + onChange, +}) => { const inputs = useRef>([]); const values = value.split('').concat(Array(length).fill('')).slice(0, length); const handleChange = (index: number, char: string) => { - if (!/^\d?$/.test(char)) return; + if (inputMode === 'numeric') { + if (!/^\d?$/.test(char)) return; + } + + if (inputMode === 'text') { + if (!/[a-z]/i.test(char)) return; + } const newValue = value.substring(0, index) + char + value.substring(index + 1); @@ -48,7 +60,7 @@ const OtpInput: React.FC = ({ length = 6, value, onChange }) => { key={i} ref={el => (inputs.current[i] = el)} type="text" - inputMode="numeric" + inputMode={inputMode} maxLength={1} value={digit || ''} className={styles.otpInput} diff --git a/src/views/EmailRegistration.tsx b/src/views/EmailRegistration.tsx index ba04668..75a9acd 100644 --- a/src/views/EmailRegistration.tsx +++ b/src/views/EmailRegistration.tsx @@ -6,6 +6,7 @@ import styles from '@/styles/verifyOTP.module.css'; import { createFetchWithAuth } from '@/fetchWithAuth'; import { isPasskeySupported } from '@/utils'; import { useInternalAuth } from '@/context/InternalAuthContext'; +import OtpInput from '@/components/OtpInput'; const EmailRegistration: React.FC = () => { const navigate = useNavigate(); @@ -129,16 +130,11 @@ const EmailRegistration: React.FC = () => { — Code expires in {formatTime(emailTimeLeft)} - - setEmailOtp(e.target.value)} - className={styles.input} - required + onChange={setEmailOtp} + inputMode="text" />