@schemavaults/auth-react-provider 0.12.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +2 -0
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/use-mfa-factor-status-swr.d.ts +14 -0
- package/dist/hooks/use-mfa-factor-status-swr.js +36 -0
- package/dist/hooks/use-mfa-factor-status-swr.js.map +1 -0
- package/dist/hooks/use-mfa.d.ts +8 -9
- package/dist/hooks/use-mfa.js +44 -8
- package/dist/hooks/use-mfa.js.map +1 -1
- package/dist/hooks/use-webauthn-credentials-swr.d.ts +13 -0
- package/dist/hooks/use-webauthn-credentials-swr.js +35 -0
- package/dist/hooks/use-webauthn-credentials-swr.js.map +1 -0
- package/package.json +3 -3
package/dist/hooks/index.d.ts
CHANGED
|
@@ -28,8 +28,12 @@ export { useOnLogout } from "./use-on-logout";
|
|
|
28
28
|
export type * from "./use-on-logout";
|
|
29
29
|
export { useMfaStatusSwr } from "./use-mfa-status-swr";
|
|
30
30
|
export type * from "./use-mfa-status-swr";
|
|
31
|
+
export { useMfaFactorStatusSwr, MFA_STATUS_SWR_KEY_PREFIX, } from "./use-mfa-factor-status-swr";
|
|
32
|
+
export type * from "./use-mfa-factor-status-swr";
|
|
31
33
|
export { useMfa } from "./use-mfa";
|
|
32
34
|
export type * from "./use-mfa";
|
|
35
|
+
export { useWebauthnCredentialsSwr, WEBAUTHN_CREDENTIALS_SWR_KEY, } from "./use-webauthn-credentials-swr";
|
|
36
|
+
export type * from "./use-webauthn-credentials-swr";
|
|
33
37
|
export { useMyOrganizations, clearMyOrganizationsCache, } from "./use-my-organizations";
|
|
34
38
|
export type * from "./use-my-organizations";
|
|
35
39
|
export { useRedirectUrlConfiguration } from "./use-redirect-url-configuration";
|
package/dist/hooks/index.js
CHANGED
|
@@ -15,7 +15,9 @@ export { useDefaultAccessTokenAudiences } from "./use-default-access-token-audie
|
|
|
15
15
|
export { useAutoReacquireDefaultAccessTokens } from "./use-auto-reacquire-default-access-tokens";
|
|
16
16
|
export { useOnLogout } from "./use-on-logout";
|
|
17
17
|
export { useMfaStatusSwr } from "./use-mfa-status-swr";
|
|
18
|
+
export { useMfaFactorStatusSwr, MFA_STATUS_SWR_KEY_PREFIX, } from "./use-mfa-factor-status-swr";
|
|
18
19
|
export { useMfa } from "./use-mfa";
|
|
20
|
+
export { useWebauthnCredentialsSwr, WEBAUTHN_CREDENTIALS_SWR_KEY, } from "./use-webauthn-credentials-swr";
|
|
19
21
|
export { useMyOrganizations, clearMyOrganizationsCache, } from "./use-my-organizations";
|
|
20
22
|
export { useRedirectUrlConfiguration } from "./use-redirect-url-configuration";
|
|
21
23
|
//# sourceMappingURL=index.js.map
|
package/dist/hooks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,OAAO,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAGxE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG1D,OAAO,EAAE,wCAAwC,EAAE,MAAM,2CAA2C,CAAC;AAGrG,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAG5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAGzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAG/E,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAGrF,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AAEtF,OAAO,EAAE,mCAAmC,EAAE,MAAM,4CAA4C,CAAC;AAEjG,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGnC,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAGrC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGpD,OAAO,EAAE,8BAA8B,EAAE,MAAM,wBAAwB,CAAC;AAGxE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAG1D,OAAO,EAAE,wCAAwC,EAAE,MAAM,2CAA2C,CAAC;AAGrG,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAG5E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAGzE,OAAO,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAG/E,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAGrF,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EAAE,8BAA8B,EAAE,MAAM,sCAAsC,CAAC;AAEtF,OAAO,EAAE,mCAAmC,EAAE,MAAM,4CAA4C,CAAC;AAEjG,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvD,OAAO,EACL,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAGnC,OAAO,EACL,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,gCAAgC,CAAC;AAGxC,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAC1B,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MfaFactorType, MfaFactorStatusResponse } from "@schemavaults/auth-common";
|
|
2
|
+
import { type KeyedMutator } from "swr";
|
|
3
|
+
export declare const MFA_STATUS_SWR_KEY_PREFIX = "/api/user/mfa/status";
|
|
4
|
+
export interface UseMfaFactorStatusSwrResult {
|
|
5
|
+
data: MfaFactorStatusResponse | null;
|
|
6
|
+
isLoading: boolean;
|
|
7
|
+
refresh: KeyedMutator<MfaFactorStatusResponse | null>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Loads the current user's MFA enrollment status for a single factor type
|
|
11
|
+
* from /api/user/mfa/status/[factor_type]. Returns null when the user is
|
|
12
|
+
* unauthenticated.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useMfaFactorStatusSwr(factor_type: MfaFactorType): UseMfaFactorStatusSwrResult;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import useSWR from "swr";
|
|
3
|
+
import useAuth from "./use-auth";
|
|
4
|
+
import useCurrentUser from "./use-current-user";
|
|
5
|
+
const REFRESH_INTERVAL_MS = 60_000;
|
|
6
|
+
const DEDUPING_INTERVAL_MS = 15_000;
|
|
7
|
+
// Shared with useMfaStatusSwr so a single global mutate() over this prefix
|
|
8
|
+
// revalidates both the aggregate status and every per-factor-type status.
|
|
9
|
+
export const MFA_STATUS_SWR_KEY_PREFIX = "/api/user/mfa/status";
|
|
10
|
+
/**
|
|
11
|
+
* Loads the current user's MFA enrollment status for a single factor type
|
|
12
|
+
* from /api/user/mfa/status/[factor_type]. Returns null when the user is
|
|
13
|
+
* unauthenticated.
|
|
14
|
+
*/
|
|
15
|
+
export function useMfaFactorStatusSwr(factor_type) {
|
|
16
|
+
const auth = useAuth();
|
|
17
|
+
const inMemoryUser = useCurrentUser();
|
|
18
|
+
const clientRef = auth.ready ? auth.client : null;
|
|
19
|
+
const enabled = !!(auth.ready && clientRef?.current && inMemoryUser);
|
|
20
|
+
const { data, isLoading, mutate } = useSWR(enabled ? `${MFA_STATUS_SWR_KEY_PREFIX}/${factor_type}` : null, async () => {
|
|
21
|
+
const authClient = clientRef?.current ?? null;
|
|
22
|
+
if (!authClient)
|
|
23
|
+
return null;
|
|
24
|
+
return await authClient.getMfaStatusForFactorType(factor_type);
|
|
25
|
+
}, {
|
|
26
|
+
refreshInterval: REFRESH_INTERVAL_MS,
|
|
27
|
+
dedupingInterval: DEDUPING_INTERVAL_MS,
|
|
28
|
+
revalidateOnFocus: true,
|
|
29
|
+
});
|
|
30
|
+
return {
|
|
31
|
+
data: data ?? null,
|
|
32
|
+
isLoading,
|
|
33
|
+
refresh: mutate,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=use-mfa-factor-status-swr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-mfa-factor-status-swr.js","sourceRoot":"","sources":["../../src/hooks/use-mfa-factor-status-swr.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAOb,OAAO,MAA6B,MAAM,KAAK,CAAC;AAChD,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,cAAc,MAAM,0BAA0B,CAAC;AAEtD,MAAM,mBAAmB,GAAG,MAAM,CAAC;AACnC,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAEpC,2EAA2E;AAC3E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,yBAAyB,GAAG,sBAAsB,CAAC;AAQhE;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CACnC,WAA0B;IAE1B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,YAAY,GAAG,cAAc,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,EAAE,OAAO,IAAI,YAAY,CAAC,CAAC;IAErE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CACxC,OAAO,CAAC,CAAC,CAAC,GAAG,yBAAyB,IAAI,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI,EAC9D,KAAK,IAA6C,EAAE;QAClD,MAAM,UAAU,GACd,SAAS,EAAE,OAAO,IAAI,IAAI,CAAC;QAC7B,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAC7B,OAAO,MAAM,UAAU,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC;IACjE,CAAC,EACD;QACE,eAAe,EAAE,mBAAmB;QACpC,gBAAgB,EAAE,oBAAoB;QACtC,iBAAiB,EAAE,IAAI;KACxB,CACF,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,IAAI,IAAI,IAAI;QAClB,SAAS;QACT,OAAO,EAAE,MAAM;KAChB,CAAC;AACJ,CAAC"}
|
package/dist/hooks/use-mfa.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { MfaStatusResponse, MfaEnrollResponse, MfaVerifyEnrollmentResponse, AuthenticateResult } from "@schemavaults/auth-common";
|
|
1
|
+
import type { MfaStatusResponse, MfaEnrollResponse, MfaVerifyEnrollmentResponse, AuthenticateResult, MfaProof, WebauthnEnrollOptionsResponse, WebauthnAuthenticationOptionsResponse, WebauthnRegistrationResponse } from "@schemavaults/auth-common";
|
|
2
2
|
export interface UseMfaResult {
|
|
3
3
|
status: MfaStatusResponse | null;
|
|
4
4
|
isLoading: boolean;
|
|
@@ -6,14 +6,13 @@ export interface UseMfaResult {
|
|
|
6
6
|
enrollTotp: () => Promise<MfaEnrollResponse>;
|
|
7
7
|
confirmTotpEnrollment: (factor_id: string, code: string) => Promise<MfaVerifyEnrollmentResponse>;
|
|
8
8
|
removeFactor: (factor_id: string, code: string) => Promise<void>;
|
|
9
|
-
regenerateRecoveryCodes: (code: string) => Promise<MfaVerifyEnrollmentResponse>;
|
|
10
|
-
submitChallenge: (challenge_id: string, client_app_id: string, proof:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}) => Promise<AuthenticateResult>;
|
|
9
|
+
regenerateRecoveryCodes: (factor_id: string, code: string) => Promise<MfaVerifyEnrollmentResponse>;
|
|
10
|
+
submitChallenge: (challenge_id: string, client_app_id: string, proof: MfaProof) => Promise<AuthenticateResult>;
|
|
11
|
+
beginWebauthnEnrollment: () => Promise<WebauthnEnrollOptionsResponse>;
|
|
12
|
+
confirmWebauthnEnrollment: (factor_id: string, attestation: WebauthnRegistrationResponse, label?: string) => Promise<MfaVerifyEnrollmentResponse>;
|
|
13
|
+
removeWebauthnFactor: (factor_id: string, proof: MfaProof) => Promise<void>;
|
|
14
|
+
getWebauthnStepUpOptions: () => Promise<WebauthnAuthenticationOptionsResponse>;
|
|
15
|
+
getWebauthnAuthenticationOptions: (challenge_id: string, client_app_id: string) => Promise<WebauthnAuthenticationOptionsResponse>;
|
|
17
16
|
}
|
|
18
17
|
/**
|
|
19
18
|
* Read + mutate the current user's MFA enrollment. Mutators automatically
|
package/dist/hooks/use-mfa.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useCallback } from "react";
|
|
3
|
+
import { useSWRConfig } from "swr";
|
|
3
4
|
import useAuth from "./use-auth";
|
|
4
5
|
import { useMfaStatusSwr } from "./use-mfa-status-swr";
|
|
6
|
+
import { MFA_STATUS_SWR_KEY_PREFIX } from "./use-mfa-factor-status-swr";
|
|
5
7
|
function requireClient(auth) {
|
|
6
8
|
if (!auth.ready) {
|
|
7
9
|
throw new Error("Auth client is not ready yet.");
|
|
@@ -20,6 +22,12 @@ function requireClient(auth) {
|
|
|
20
22
|
export function useMfa() {
|
|
21
23
|
const auth = useAuth();
|
|
22
24
|
const { data, isLoading, refresh } = useMfaStatusSwr();
|
|
25
|
+
const { mutate: globalMutate } = useSWRConfig();
|
|
26
|
+
// Revalidate the aggregate status AND every per-factor-type status
|
|
27
|
+
// (e.g. /api/user/mfa/status/totp) so all MFA hooks reflect a mutation.
|
|
28
|
+
const refreshAllMfaStatus = useCallback(async () => {
|
|
29
|
+
await globalMutate((key) => typeof key === "string" && key.startsWith(MFA_STATUS_SWR_KEY_PREFIX));
|
|
30
|
+
}, [globalMutate]);
|
|
23
31
|
const enrollTotp = useCallback(async () => {
|
|
24
32
|
const client = requireClient(auth);
|
|
25
33
|
const result = await client.enrollTotp();
|
|
@@ -28,24 +36,47 @@ export function useMfa() {
|
|
|
28
36
|
const confirmTotpEnrollment = useCallback(async (factor_id, code) => {
|
|
29
37
|
const client = requireClient(auth);
|
|
30
38
|
const result = await client.confirmTotpEnrollment(factor_id, code);
|
|
31
|
-
await
|
|
39
|
+
await refreshAllMfaStatus();
|
|
32
40
|
return result;
|
|
33
|
-
}, [auth,
|
|
41
|
+
}, [auth, refreshAllMfaStatus]);
|
|
34
42
|
const removeFactor = useCallback(async (factor_id, code) => {
|
|
35
43
|
const client = requireClient(auth);
|
|
36
44
|
await client.removeFactor(factor_id, code);
|
|
37
|
-
await
|
|
38
|
-
}, [auth,
|
|
39
|
-
const regenerateRecoveryCodes = useCallback(async (code) => {
|
|
45
|
+
await refreshAllMfaStatus();
|
|
46
|
+
}, [auth, refreshAllMfaStatus]);
|
|
47
|
+
const regenerateRecoveryCodes = useCallback(async (factor_id, code) => {
|
|
40
48
|
const client = requireClient(auth);
|
|
41
|
-
const result = await client.regenerateRecoveryCodes(code);
|
|
42
|
-
await
|
|
49
|
+
const result = await client.regenerateRecoveryCodes(factor_id, code);
|
|
50
|
+
await refreshAllMfaStatus();
|
|
43
51
|
return result;
|
|
44
|
-
}, [auth,
|
|
52
|
+
}, [auth, refreshAllMfaStatus]);
|
|
45
53
|
const submitChallenge = useCallback(async (challenge_id, client_app_id, proof) => {
|
|
46
54
|
const client = requireClient(auth);
|
|
47
55
|
return await client.verifyMfaChallenge(challenge_id, client_app_id, proof);
|
|
48
56
|
}, [auth]);
|
|
57
|
+
const beginWebauthnEnrollment = useCallback(async () => {
|
|
58
|
+
const client = requireClient(auth);
|
|
59
|
+
return await client.beginWebauthnEnrollment();
|
|
60
|
+
}, [auth]);
|
|
61
|
+
const confirmWebauthnEnrollment = useCallback(async (factor_id, attestation, label) => {
|
|
62
|
+
const client = requireClient(auth);
|
|
63
|
+
const result = await client.confirmWebauthnEnrollment(factor_id, attestation, label);
|
|
64
|
+
await refreshAllMfaStatus();
|
|
65
|
+
return result;
|
|
66
|
+
}, [auth, refreshAllMfaStatus]);
|
|
67
|
+
const removeWebauthnFactor = useCallback(async (factor_id, proof) => {
|
|
68
|
+
const client = requireClient(auth);
|
|
69
|
+
await client.removeWebauthnFactor(factor_id, proof);
|
|
70
|
+
await refreshAllMfaStatus();
|
|
71
|
+
}, [auth, refreshAllMfaStatus]);
|
|
72
|
+
const getWebauthnStepUpOptions = useCallback(async () => {
|
|
73
|
+
const client = requireClient(auth);
|
|
74
|
+
return await client.getWebauthnStepUpOptions();
|
|
75
|
+
}, [auth]);
|
|
76
|
+
const getWebauthnAuthenticationOptions = useCallback(async (challenge_id, client_app_id) => {
|
|
77
|
+
const client = requireClient(auth);
|
|
78
|
+
return await client.getWebauthnAuthenticationOptions(challenge_id, client_app_id);
|
|
79
|
+
}, [auth]);
|
|
49
80
|
return {
|
|
50
81
|
status: data,
|
|
51
82
|
isLoading,
|
|
@@ -55,6 +86,11 @@ export function useMfa() {
|
|
|
55
86
|
removeFactor,
|
|
56
87
|
regenerateRecoveryCodes,
|
|
57
88
|
submitChallenge,
|
|
89
|
+
beginWebauthnEnrollment,
|
|
90
|
+
confirmWebauthnEnrollment,
|
|
91
|
+
removeWebauthnFactor,
|
|
92
|
+
getWebauthnStepUpOptions,
|
|
93
|
+
getWebauthnAuthenticationOptions,
|
|
58
94
|
};
|
|
59
95
|
}
|
|
60
96
|
//# sourceMappingURL=use-mfa.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-mfa.js","sourceRoot":"","sources":["../../src/hooks/use-mfa.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"use-mfa.js","sourceRoot":"","sources":["../../src/hooks/use-mfa.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { WebauthnCredentialSummary } from "@schemavaults/auth-common";
|
|
2
|
+
import { type KeyedMutator } from "swr";
|
|
3
|
+
export declare const WEBAUTHN_CREDENTIALS_SWR_KEY = "/api/user/mfa/status/webauthn/credentials";
|
|
4
|
+
export interface UseWebauthnCredentialsSwrResult {
|
|
5
|
+
data: WebauthnCredentialSummary[] | null;
|
|
6
|
+
isLoading: boolean;
|
|
7
|
+
refresh: KeyedMutator<WebauthnCredentialSummary[] | null>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Loads the current user's enrolled passkeys from /api/user/mfa/webauthn.
|
|
11
|
+
* Returns null when the user is unauthenticated.
|
|
12
|
+
*/
|
|
13
|
+
export declare function useWebauthnCredentialsSwr(): UseWebauthnCredentialsSwrResult;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import useSWR from "swr";
|
|
3
|
+
import useAuth from "./use-auth";
|
|
4
|
+
import useCurrentUser from "./use-current-user";
|
|
5
|
+
import { MFA_STATUS_SWR_KEY_PREFIX } from "./use-mfa-factor-status-swr";
|
|
6
|
+
const DEDUPING_INTERVAL_MS = 15_000;
|
|
7
|
+
// Share the MFA status key prefix so the existing refreshAllMfaStatus()
|
|
8
|
+
// invalidation in useMfa() also revalidates the passkey list after an
|
|
9
|
+
// enroll/remove mutation.
|
|
10
|
+
export const WEBAUTHN_CREDENTIALS_SWR_KEY = `${MFA_STATUS_SWR_KEY_PREFIX}/webauthn/credentials`;
|
|
11
|
+
/**
|
|
12
|
+
* Loads the current user's enrolled passkeys from /api/user/mfa/webauthn.
|
|
13
|
+
* Returns null when the user is unauthenticated.
|
|
14
|
+
*/
|
|
15
|
+
export function useWebauthnCredentialsSwr() {
|
|
16
|
+
const auth = useAuth();
|
|
17
|
+
const inMemoryUser = useCurrentUser();
|
|
18
|
+
const clientRef = auth.ready ? auth.client : null;
|
|
19
|
+
const enabled = !!(auth.ready && clientRef?.current && inMemoryUser);
|
|
20
|
+
const { data, isLoading, mutate } = useSWR(enabled ? WEBAUTHN_CREDENTIALS_SWR_KEY : null, async () => {
|
|
21
|
+
const authClient = clientRef?.current ?? null;
|
|
22
|
+
if (!authClient)
|
|
23
|
+
return null;
|
|
24
|
+
return await authClient.listWebauthnCredentials();
|
|
25
|
+
}, {
|
|
26
|
+
dedupingInterval: DEDUPING_INTERVAL_MS,
|
|
27
|
+
revalidateOnFocus: true,
|
|
28
|
+
});
|
|
29
|
+
return {
|
|
30
|
+
data: data ?? null,
|
|
31
|
+
isLoading,
|
|
32
|
+
refresh: mutate,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=use-webauthn-credentials-swr.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-webauthn-credentials-swr.js","sourceRoot":"","sources":["../../src/hooks/use-webauthn-credentials-swr.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAIb,OAAO,MAA6B,MAAM,KAAK,CAAC;AAChD,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,cAAc,MAAM,0BAA0B,CAAC;AACtD,OAAO,EAAE,yBAAyB,EAAE,MAAM,6BAA6B,CAAC;AAExE,MAAM,oBAAoB,GAAG,MAAM,CAAC;AAEpC,wEAAwE;AACxE,sEAAsE;AACtE,0BAA0B;AAC1B,MAAM,CAAC,MAAM,4BAA4B,GAAG,GAAG,yBAAyB,uBAAuB,CAAC;AAQhG;;;GAGG;AACH,MAAM,UAAU,yBAAyB;IACvC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,YAAY,GAAG,cAAc,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IAClD,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,SAAS,EAAE,OAAO,IAAI,YAAY,CAAC,CAAC;IAErE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,CAGxC,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,IAAI,EAC7C,KAAK,IAAiD,EAAE;QACtD,MAAM,UAAU,GACd,SAAS,EAAE,OAAO,IAAI,IAAI,CAAC;QAC7B,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QAC7B,OAAO,MAAM,UAAU,CAAC,uBAAuB,EAAE,CAAC;IACpD,CAAC,EACD;QACE,gBAAgB,EAAE,oBAAoB;QACtC,iBAAiB,EAAE,IAAI;KACxB,CACF,CAAC;IAEF,OAAO;QACL,IAAI,EAAE,IAAI,IAAI,IAAI;QAClB,SAAS;QACT,OAAO,EAAE,MAAM;KAChB,CAAC;AACJ,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schemavaults/auth-react-provider",
|
|
3
3
|
"description": "React hooks and components to make using the @schemavaults/auth-client-sdk a breeze",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.13.0",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"private": false,
|
|
7
7
|
"repository": {
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"types": "dist/index.d.ts",
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"zod": "3.25.8",
|
|
18
|
-
"@schemavaults/auth-client-sdk": "0.
|
|
18
|
+
"@schemavaults/auth-client-sdk": "0.11.0",
|
|
19
19
|
"@schemavaults/app-definitions": "0.7.1",
|
|
20
|
-
"@schemavaults/auth-common": "0.
|
|
20
|
+
"@schemavaults/auth-common": "0.13.0",
|
|
21
21
|
"cookies-next": "6.1.1",
|
|
22
22
|
"uuid": "11.0.3",
|
|
23
23
|
"swr": "2.3.4"
|