diff --git a/app/routes/_auth+/login.tsx b/app/routes/_auth+/login.tsx index d01244912..5e27c606a 100644 --- a/app/routes/_auth+/login.tsx +++ b/app/routes/_auth+/login.tsx @@ -1,12 +1,15 @@ import { getFormProps, getInputProps, useForm } from '@conform-to/react' import { getZodConstraint, parseWithZod } from '@conform-to/zod' import { type SEOHandle } from '@nasa-gcn/remix-seo' -import { data, Form, Link, useSearchParams } from 'react-router' +import { startAuthentication } from '@simplewebauthn/browser' +import { useOptimistic, useState, useTransition } from 'react' +import { data, Form, Link, useNavigate, useSearchParams } from 'react-router' import { HoneypotInputs } from 'remix-utils/honeypot/react' import { z } from 'zod' import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx' import { CheckboxField, ErrorList, Field } from '#app/components/forms.tsx' import { Spacer } from '#app/components/spacer.tsx' +import { Icon } from '#app/components/ui/icon.tsx' import { StatusButton } from '#app/components/ui/status-button.tsx' import { login, requireAnonymous } from '#app/utils/auth.server.ts' import { @@ -14,7 +17,7 @@ import { providerNames, } from '#app/utils/connections.tsx' import { checkHoneypot } from '#app/utils/honeypot.server.ts' -import { useIsPending } from '#app/utils/misc.tsx' +import { getErrorMessage, useIsPending } from '#app/utils/misc.tsx' import { PasswordSchema, UsernameSchema } from '#app/utils/user-validation.ts' import { type Route } from './+types/login.ts' import { handleNewSession } from './login.server.ts' @@ -30,6 +33,10 @@ const LoginFormSchema = z.object({ remember: z.boolean().optional(), }) +const AuthenticationOptionsSchema = z.object({ + options: z.object({ challenge: z.string() }), +}) satisfies z.ZodType<{ options: PublicKeyCredentialRequestOptionsJSON }> + export async function loader({ request }: Route.LoaderArgs) { await requireAnonymous(request) return {} @@ -165,7 +172,15 @@ export default function LoginPage({ actionData }: Route.ComponentProps) { -