@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
216 lines • 6.4 kB
TypeScript
import { PasskeySummary, UpdatePasskeyRequest } from '@frank-auth/client';
import { AuthError } from '../provider/types';
export interface UsePasskeysReturn {
passkeys: PasskeySummary[];
isSupported: boolean;
isAvailable: boolean;
isLoaded: boolean;
isLoading: boolean;
error: AuthError | null;
beginRegistration: (name?: string) => Promise<PasskeyRegistrationData>;
finishRegistration: (registrationData: PasskeyRegistrationData, credential: any) => Promise<PasskeySummary>;
registerPasskey: (name?: string) => Promise<PasskeySummary>;
beginAuthentication: () => Promise<PasskeyAuthenticationData>;
finishAuthentication: (authenticationData: PasskeyAuthenticationData, credential: any) => Promise<AuthenticationResult>;
authenticateWithPasskey: () => Promise<AuthenticationResult>;
updatePasskey: (passkeyId: string, updates: UpdatePasskeyRequest) => Promise<PasskeySummary>;
deletePasskey: (passkeyId: string) => Promise<void>;
renamePasskey: (passkeyId: string, name: string) => Promise<PasskeySummary>;
primaryPasskey: PasskeySummary | null;
passkeyCount: number;
refreshPasskeys: () => Promise<void>;
checkSupport: () => Promise<boolean>;
}
export interface PasskeyRegistrationData {
challenge: string;
options: PublicKeyCredentialCreationOptions;
sessionId?: string;
}
export interface PasskeyAuthenticationData {
challenge: string;
options: PublicKeyCredentialRequestOptions;
sessionId?: string;
}
export interface AuthenticationResult {
success: boolean;
session?: any;
user?: any;
error?: string;
}
/**
* Comprehensive passkeys hook for WebAuthn/FIDO2 authentication
*
* @example Basic passkey registration
* ```tsx
* import { usePasskeys } from '@frank-auth/react';
*
* function PasskeySetup() {
* const {
* isSupported,
* isAvailable,
* registerPasskey,
* passkeys,
* isLoading
* } = usePasskeys();
*
* const handleRegisterPasskey = async () => {
* try {
* const passkey = await registerPasskey('My Security Key');
* console.log('Passkey registered:', passkey);
* } catch (error) {
* console.error('Registration failed:', error);
* }
* };
*
* if (!isSupported) {
* return <div>Passkeys are not supported in this browser</div>;
* }
*
* if (!isAvailable) {
* return <div>No authenticators available</div>;
* }
*
* return (
* <div>
* <h3>Your Passkeys ({passkeys.length})</h3>
* {passkeys.map(passkey => (
* <div key={passkey.id}>
* <span>{passkey.name}</span>
* <span>Created: {passkey.createdAt}</span>
* </div>
* ))}
* <button onClick={handleRegisterPasskey} disabled={isLoading}>
* Add New Passkey
* </button>
* </div>
* );
* }
* ```
*
* @example Passkey authentication
* ```tsx
* function PasskeySignIn() {
* const { authenticateWithPasskey, isSupported } = usePasskeys();
*
* const handleSignIn = async () => {
* try {
* const result = await authenticateWithPasskey();
* if (result.success) {
* console.log('Signed in successfully:', result.user);
* }
* } catch (error) {
* console.error('Authentication failed:', error);
* }
* };
*
* if (!isSupported) {
* return <div>Passkey authentication not supported</div>;
* }
*
* return (
* <button onClick={handleSignIn}>
* Sign in with Passkey
* </button>
* );
* }
* ```
*
* @example Passkey management
* ```tsx
* function PasskeyManagement() {
* const {
* passkeys,
* deletePasskey,
* renamePasskey,
* updatePasskey
* } = usePasskeys();
*
* const [editingId, setEditingId] = useState(null);
* const [newName, setNewName] = useState('');
*
* const handleRename = async (passkeyId) => {
* try {
* await renamePasskey(passkeyId, newName);
* setEditingId(null);
* setNewName('');
* } catch (error) {
* console.error('Rename failed:', error);
* }
* };
*
* const handleDelete = async (passkeyId) => {
* if (confirm('Are you sure you want to delete this passkey?')) {
* try {
* await deletePasskey(passkeyId);
* } catch (error) {
* console.error('Delete failed:', error);
* }
* }
* };
*
* return (
* <div>
* {passkeys.map(passkey => (
* <div key={passkey.id}>
* {editingId === passkey.id ? (
* <div>
* <input
* value={newName}
* onChange={(e) => setNewName(e.target.value)}
* defaultValue={passkey.name}
* />
* <button onClick={() => handleRename(passkey.id)}>
* Save
* </button>
* <button onClick={() => setEditingId(null)}>
* Cancel
* </button>
* </div>
* ) : (
* <div>
* <span>{passkey.name}</span>
* <span>Last used: {passkey.lastUsedAt}</span>
* <button onClick={() => {
* setEditingId(passkey.id);
* setNewName(passkey.name);
* }}>
* Rename
* </button>
* <button onClick={() => handleDelete(passkey.id)}>
* Delete
* </button>
* </div>
* )}
* </div>
* ))}
* </div>
* );
* }
* ```
*/
export declare function usePasskeys(): UsePasskeysReturn;
/**
* Hook for passkey registration flow
*/
export declare function usePasskeyRegistration(): {
register: (name?: string) => Promise<PasskeySummary>;
state: "idle" | "success" | "error" | "registering";
isSupported: boolean;
isAvailable: boolean;
isLoading: boolean;
error: AuthError | null;
canRegister: boolean;
};
/**
* Hook for passkey authentication flow
*/
export declare function usePasskeyAuthentication(): {
authenticate: () => Promise<AuthenticationResult>;
state: "idle" | "success" | "error" | "authenticating";
isSupported: boolean;
isAvailable: boolean;
isLoading: boolean;
error: AuthError | null;
canAuthenticate: boolean;
};
//# sourceMappingURL=use-passkeys.d.ts.map