diff --git a/examples/webauthn-default/src/components/WebAuthnDefaultExamplePage/DefaultExample/PasskeysPage/hooks/useAddPasskey.ts b/examples/webauthn-default/src/components/WebAuthnDefaultExamplePage/DefaultExample/PasskeysPage/hooks/useAddPasskey.ts
index aa9ba8f..b686615 100644
--- a/examples/webauthn-default/src/components/WebAuthnDefaultExamplePage/DefaultExample/PasskeysPage/hooks/useAddPasskey.ts
+++ b/examples/webauthn-default/src/components/WebAuthnDefaultExamplePage/DefaultExample/PasskeysPage/hooks/useAddPasskey.ts
@@ -3,6 +3,7 @@ import { useMutation } from '@tanstack/react-query';
import { queryClient } from '@workspace/common/client/api/components';
import { fetcher } from '@workspace/common/client/api/fetcher';
+import { parseUnknownError } from '@workspace/common/client/errors';
import { useSnack } from '@workspace/common/client/snackbar/hooks';
import { logger } from '@workspace/common/logger';
@@ -41,7 +42,11 @@ export function useAddPasskey() {
});
},
async onError(error: Error) {
- snack('error', error.message);
+ const parsedError = await parseUnknownError(error);
+
+ logger.error(parsedError);
+
+ snack('error', parsedError.message);
},
onSuccess() {
snack('success', 'Passkey has been successfully added.');
diff --git a/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/EmailVerificationCode/EmailVerificationCode.tsx b/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/EmailVerificationCode/EmailVerificationCode.tsx
new file mode 100644
index 0000000..14756e1
--- /dev/null
+++ b/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/EmailVerificationCode/EmailVerificationCode.tsx
@@ -0,0 +1,49 @@
+import type { ReactNode } from 'react';
+import { useRouter } from 'next/router';
+import { useQuery } from '@tanstack/react-query';
+import { applyActionCode } from 'firebase/auth';
+import { parseAsString, parseAsStringLiteral, useQueryStates } from 'nuqs';
+
+import { QueryLoader } from '@workspace/common/client/api/components';
+import { env } from '@workspace/common/client/env';
+import { auth } from '@workspace/common/client/firebase/config';
+
+import { useExampleRouter } from '../DefaultExampleRouter';
+
+export interface EmailVerificationCodeProps {
+ children: ReactNode;
+}
+
+export function EmailVerificationCode({ children }: EmailVerificationCodeProps) {
+ const [params] = useQueryStates({
+ apiKey: parseAsString,
+ mode: parseAsStringLiteral(['verifyEmail'] as const),
+ oobCode: parseAsString,
+ continueUrl: parseAsString,
+ });
+
+ const { push } = useRouter();
+ const { redirect } = useExampleRouter();
+
+ const result = useQuery({
+ queryKey: ['emailVerification', params],
+ queryFn: async () => {
+ const { mode, oobCode, continueUrl, apiKey } = params;
+
+ if (mode !== 'verifyEmail' || !oobCode || apiKey !== env.NEXT_PUBLIC_FIREBASE_API_KEY || !continueUrl) {
+ return null;
+ }
+
+ await applyActionCode(auth(), oobCode);
+ await auth().currentUser?.reload();
+
+ await push(continueUrl);
+
+ redirect('/login-with-password');
+
+ return null;
+ },
+ });
+
+ return {children};
+}
diff --git a/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/EmailVerificationCode/index.ts b/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/EmailVerificationCode/index.ts
new file mode 100644
index 0000000..9df64dc
--- /dev/null
+++ b/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/EmailVerificationCode/index.ts
@@ -0,0 +1 @@
+export * from './EmailVerificationCode';
diff --git a/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/LoginWithEmailAndPasswordPage/LoginWithEmailAndPasswordPage.tsx b/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/LoginWithEmailAndPasswordPage/LoginWithEmailAndPasswordPage.tsx
index 7518772..3262cce 100644
--- a/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/LoginWithEmailAndPasswordPage/LoginWithEmailAndPasswordPage.tsx
+++ b/examples/webauthn-upgrade/src/components/WebAuthnUpgradeExamplePage/UpgradeExample/LoginWithEmailAndPasswordPage/LoginWithEmailAndPasswordPage.tsx
@@ -1,3 +1,5 @@
+import { useQueryState } from 'nuqs';
+
import {
EmailField,
FieldsStack,
@@ -15,7 +17,13 @@ import { useLoginWithEmailAndPassword } from './hooks/useLoginWithEmailAndPasswo
import { loginFormSchema, type LoginFormSchema, type LoginFormValues } from './schema';
export const LoginWithEmailAndPasswordPage = () => {
- const login = useLoginWithEmailAndPassword();
+ const [email, setEmail] = useQueryState('email');
+ const login = useLoginWithEmailAndPassword({
+ onSuccess() {
+ setEmail(null);
+ },
+ });
+
const { redirect } = useExampleRouter();
return (
@@ -24,7 +32,12 @@ export const LoginWithEmailAndPasswordPage = () => {
Back
-