@joinmeow/cognito-passwordless-auth
Version:
Passwordless authentication with Amazon Cognito: FIDO2 (WebAuthn, support for Passkeys)
244 lines (243 loc) • 11.9 kB
TypeScript
import { StoredCredential } from "../fido2.js";
import { TokensFromStorage } from "../storage.js";
import { TokensFromRefresh, TokensFromSignIn } from "../model.js";
import { CognitoAccessTokenPayload, CognitoIdTokenPayload } from "../jwt-model.js";
import React from "react";
/** React hook that provides convenient access to the Passwordless lib's features */
export declare function usePasswordless(): {
/** The (raw) tokens: ID token, Access token and Refresh Token */
tokens: TokensFromStorage | undefined;
/** The JSON parsed ID and Access token */
tokensParsed: {
idToken: CognitoIdTokenPayload;
accessToken: CognitoAccessTokenPayload;
expireAt: Date;
} | undefined;
/** Is the UI currently refreshing tokens? */
isRefreshingTokens: boolean | undefined;
/** Execute (and reschedule) token refresh */
refreshTokens: (abort?: AbortSignal | undefined) => Promise<TokensFromRefresh>;
/** Force an immediate token refresh regardless of current token state */
forceRefreshTokens: (abort?: AbortSignal | undefined) => Promise<TokensFromRefresh>;
/** Mark the user as active to potentially trigger token refresh */
markUserActive: () => void;
/** Last error that occured */
lastError: Error | undefined;
/** The status of the most recent sign-in attempt */
signingInStatus: "STARTING_SIGN_IN_WITH_FIDO2" | "COMPLETING_SIGN_IN_WITH_FIDO2" | "SIGNING_IN_WITH_PASSWORD" | "SIGNING_IN_WITH_OTP" | "SIGNING_OUT" | "AUTHENTICATING_WITH_DEVICE" | "STARTING_SIGN_IN_WITH_REDIRECT" | "SIGNED_OUT" | "SIGNED_IN_WITH_FIDO2" | "SIGNED_IN_WITH_PASSWORD" | "SIGNED_IN_WITH_SRP_PASSWORD" | "SIGNED_IN_WITH_PLAINTEXT_PASSWORD" | "SIGNED_IN_WITH_OTP" | "FIDO2_SIGNIN_FAILED" | "SIGNIN_WITH_OTP_FAILED" | "PASSWORD_SIGNIN_FAILED" | "SIGNED_IN_WITH_REDIRECT" | "SIGNIN_WITH_REDIRECT_FAILED";
/** Are we currently busy signing in or out? */
busy: boolean;
/**
* The overall auth status, e.g. is the user signed in or not?
* Use this field to show the relevant UI, e.g. render a sign-in page,
* if the status equals "NOT_SIGNED_IN"
*/
signInStatus: string;
/** Is a user verifying platform authenticator available? E.g. Face ID or Touch */
userVerifyingPlatformAuthenticatorAvailable: boolean | undefined;
/** The user's registered FIDO2 credentials. Each credential provides `update` and `delete` methods */
fido2Credentials: Fido2Credential[] | undefined;
/** Are we currently creating a FIDO2 credential? */
creatingCredential: boolean;
/** The device key for remembered device authentication */
deviceKey: string | null;
/**
* Confirm a device for trusted device authentication.
* The device key must be available from a recent authentication response.
*/
confirmDevice: (deviceName: string) => Promise<{
UserConfirmationNecessary?: boolean | undefined;
}>;
/**
* Update the status of a device (remembered or not_remembered).
* Use this after getting userConfirmationNecessary=true in tokens
* to set the device as remembered based on user choice.
*/
updateDeviceStatus: ({ deviceKey, deviceRememberedStatus, }: {
deviceKey: string;
deviceRememberedStatus: "remembered" | "not_remembered";
}) => Promise<void>;
/**
* Forget a device to stop using it for trusted device authentication
* Note that this is different from just clearing the local device key
* as it also removes the device from the user's account on the server
*/
forgetDevice: (deviceKeyToForget?: string) => Promise<void>;
/**
* Clear the stored device key locally without removing it from the server
*/
clearDeviceKey: () => void;
/** Register a FIDO2 credential with the Relying Party */
fido2CreateCredential: (args_0: {
friendlyName: string | (() => string | Promise<string>);
}) => Promise<StoredCredential>;
/** Sign out */
signOut: (options?: {
skipTokenRevocation?: boolean | undefined;
} | undefined) => {
signedOut: Promise<void>;
abort: () => void;
};
/** Sign in with FIDO2 (e.g. Face ID or Touch) */
authenticateWithFido2: ({ username, credentials, clientMetadata, }?: {
/** Username, alias (e-mail, phone number) */
username?: string | undefined;
credentials?: {
id: string;
transports?: AuthenticatorTransport[] | undefined;
}[] | undefined;
clientMetadata?: Record<string, string> | undefined;
}) => {
signedIn: Promise<TokensFromSignIn>;
abort: () => void;
};
/** Sign in with username and password (using SRP: Secure Remote Password, where the password isn't sent over the wire) */
authenticateWithSRP: ({ username, password, smsMfaCode, otpMfaCode, newPassword, clientMetadata, rememberDevice, }: {
/**
* Username, or alias (e-mail, phone number)
*/
username: string;
password: string;
smsMfaCode?: (() => Promise<string>) | undefined;
otpMfaCode?: (() => Promise<string>) | undefined;
/**
* Provide a callback that resolves with a new password **when Cognito returns the
* `NEW_PASSWORD_REQUIRED` challenge**. Returning a promise lets you prompt the user
* only when necessary and keeps the authentication flow fully encapsulated.
*/
newPassword?: (() => Promise<string>) | undefined;
clientMetadata?: Record<string, string> | undefined;
/**
* Provide a callback that resolves to "true" if the user elected to remember
* this device (e.g. after entering the MFA code). The function is only invoked
* **after** Cognito tells us `UserConfirmationNecessary === true`.
* Similar to `otpMfaCode`, returning a promise lets you prompt the user
* during the authentication flow.
*/
rememberDevice?: (() => Promise<boolean>) | undefined;
}) => {
signedIn: Promise<TokensFromSignIn>;
abort: () => void;
};
/** Sign in with username and password (the password is sent in plaintext over the wire) */
authenticateWithPlaintextPassword: ({ username, password, smsMfaCode, otpMfaCode, clientMetadata, rememberDevice, }: {
/**
* Username, or alias (e-mail, phone number)
*/
username: string;
password: string;
smsMfaCode?: (() => Promise<string>) | undefined;
otpMfaCode?: (() => Promise<string>) | undefined;
clientMetadata?: Record<string, string> | undefined;
rememberDevice?: (() => Promise<boolean>) | undefined;
}) => {
signedIn: Promise<TokensFromSignIn>;
abort: () => void;
};
/** The current status of TOTP MFA for the user */
totpMfaStatus: {
enabled: boolean;
preferred: boolean;
availableMfaTypes: string[];
};
/** Refresh the TOTP MFA status - use this after enabling/disabling MFA */
refreshTotpMfaStatus: () => Promise<void>;
/** Milliseconds since the last user activity (mousemove, keydown, scroll, touch) */
timeSinceLastActivityMs: number | null;
/** Seconds (rounded) since the last user activity */
timeSinceLastActivitySeconds: number | null;
/** Sign in via Cognito Hosted UI (redirect, e.g. Google) */
signInWithRedirect: ({ provider, customState, oauthParams, }?: {
provider?: string | undefined;
customState?: string | undefined;
oauthParams?: Record<string, string> | undefined;
}) => void;
/** The current authentication method used for these tokens */
authMethod: "SRP" | "FIDO2" | "PLAINTEXT" | "REDIRECT" | undefined;
};
/** React hook that stores and gives access to the last 10 signed in users (from your configured storage) */
export declare function useLocalUserCache(): {
/** The current signed-in user */
currentUser: StoredUser | undefined;
/** Update the current user's FIDO2 preference */
updateFidoPreference: ({ useFido }: {
useFido: "YES" | "NO";
}) => void;
/** The list of the 10 last signed-in users in your configured storage (e.g. localStorage) */
lastSignedInUsers: StoredUser[] | undefined;
/** Clear the last signed in users from your configured storage (e.g. localStorage) */
clearLastSignedInUsers: () => void;
/** The status of the most recent sign-in attempt */
signingInStatus: "STARTING_SIGN_IN_WITH_FIDO2" | "COMPLETING_SIGN_IN_WITH_FIDO2" | "SIGNING_IN_WITH_PASSWORD" | "SIGNING_IN_WITH_OTP" | "SIGNING_OUT" | "AUTHENTICATING_WITH_DEVICE" | "STARTING_SIGN_IN_WITH_REDIRECT" | "SIGNED_OUT" | "SIGNED_IN_WITH_FIDO2" | "SIGNED_IN_WITH_PASSWORD" | "SIGNED_IN_WITH_SRP_PASSWORD" | "SIGNED_IN_WITH_PLAINTEXT_PASSWORD" | "SIGNED_IN_WITH_OTP" | "FIDO2_SIGNIN_FAILED" | "SIGNIN_WITH_OTP_FAILED" | "PASSWORD_SIGNIN_FAILED" | "SIGNED_IN_WITH_REDIRECT" | "SIGNIN_WITH_REDIRECT_FAILED";
/** The current authentication method */
authMethod: "SRP" | "FIDO2" | "PLAINTEXT" | "REDIRECT" | undefined;
};
export declare const PasswordlessContextProvider: (props: {
children: React.ReactNode;
enableLocalUserCache?: boolean;
errorFallback?: React.ReactNode;
}) => import("react/jsx-runtime").JSX.Element;
/** A FIDO2 credential (e.g. Face ID or Touch), with convenient methods for updating and deleting */
type Fido2Credential = StoredCredential & {
/** Update the friendly name of the credential */
update: (update: {
friendlyName: string;
}) => Promise<void>;
/** Delete the credential */
delete: () => Promise<void>;
/** The credential is currently being updated or deleted */
busy: boolean;
};
/** User Details stored in your configured storage (e.g. localStorage) */
type StoredUser = {
username: string;
email?: string;
useFido?: "YES" | "NO" | "ASK";
credentials?: {
id: string;
transports?: AuthenticatorTransport[];
}[];
/** Last authentication method used by this user */
authMethod?: "SRP" | "FIDO2" | "PLAINTEXT" | "REDIRECT";
};
/** React hook to turn state (or any variable) into a promise that can be awaited */
export declare function useAwaitableState<T>(state: T): {
/** Call to get the current awaitable (promise) */
awaitable: () => Promise<T>;
/** Resolve the current awaitable (promise) with the current value of state */
resolve: () => void;
/** Reject the current awaitable (promise) */
reject: (reason: Error) => void;
/** That value of awaitable (promise) once it resolves. This is undefined if (1) awaitable is not yet resolved or (2) the state has changed since awaitable was resolved */
awaited: {
value: T;
} | undefined;
};
/** React hook to manage TOTP MFA setup and verification for a user */
export declare function useTotpMfa(): {
/** Current status of the TOTP MFA setup process */
setupStatus: "IDLE" | "GENERATING" | "READY" | "VERIFYING" | "VERIFIED" | "ERROR";
/** Secret code generated for TOTP setup (to display to user) */
secretCode: string | undefined;
/** QR code URL that can be turned into a QR code for scanning */
qrCodeUrl: string | undefined;
/** Error message if something went wrong */
errorMessage: string | undefined;
/** Start the TOTP MFA setup process */
beginSetup: () => Promise<{
SecretCode: string;
} | null>;
/** Verify the TOTP code to complete setup */
verifySetup: (code: string, deviceName?: string) => Promise<{
Status: string;
}>;
/** Reset the setup state */
resetSetup: () => void;
/** Current status of TOTP MFA configuration for the user */
totpMfaStatus: {
enabled: boolean;
preferred: boolean;
availableMfaTypes: string[];
};
};
export {};