-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathuseRemovePasskey.ts
More file actions
71 lines (59 loc) · 2.64 KB
/
Copy pathuseRemovePasskey.ts
File metadata and controls
71 lines (59 loc) · 2.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { startAuthentication } from '@simplewebauthn/browser';
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 { useAuthUser } from '@workspace/common/client/example/components';
import type { PostRemovalDialogProps } from '@workspace/common/client/passkeys/components';
import { useSnack } from '@workspace/common/client/snackbar/hooks';
import { logger } from '@workspace/common/logger';
import type { StartRemovalResponseData } from '~pages/api/webauthn/remove/options';
import type { VerifyRemovalRequestData, VerifyRemovalResponseData } from '~pages/api/webauthn/remove/verify';
/**
* Remove a passkey from the user's account. User must verify their identity before removing the passkey.
*/
export function useRemovePasskey(openDialog: (data: PostRemovalDialogProps['data']) => void) {
const snack = useSnack();
const authUser = useAuthUser();
return useMutation({
mutationFn: async (passkeyId: string) => {
try {
const {
data: { publicKeyOptions },
} = await fetcher<StartRemovalResponseData>({
method: 'GET',
url: '/webauthn/remove/options',
});
logger.info('/webauthn/remove/options', publicKeyOptions);
const result = await startAuthentication({
optionsJSON: publicKeyOptions,
});
logger.info('WebAuthn API result:', result);
const {
data: { passkey },
} = await fetcher<VerifyRemovalResponseData>({
method: 'POST',
url: '/webauthn/remove/verify',
body: {
authenticationResponse: result,
passkeyId,
} satisfies VerifyRemovalRequestData,
});
if (passkey.provider) {
openDialog({
provider: passkey.provider,
rpId: passkey.rpId,
username: authUser?.email!,
});
}
await queryClient.invalidateQueries({
queryKey: ['passkeys'],
});
} catch (error) {
const parsedError = await parseUnknownError(error);
snack('error', parsedError.message);
logger.error(error);
}
},
});
}