Skip to main content

Abstract Class: BaseAuthMFARoute<U, S, A>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:55

Extended by​

Type Parameters​

U​

U extends User

S​

S extends Secret

A​

A extends Alias

Constructors​

Constructor​

new BaseAuthMFARoute<U, S, A>(): BaseAuthMFARoute<U, S, A>

Returns​

BaseAuthMFARoute<U, S, A>

Properties​

aliasClass​

abstract protected aliasClass: any

Defined in: auth/src/routes/BaseAuthMFARoute.ts:56


aliasRepo?​

protected optional aliasRepo?: RepoUtils<A>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:63


auditLogUtils?​

protected optional auditLogUtils?: AuditLogUtils

Defined in: auth/src/routes/BaseAuthMFARoute.ts:66


authMiddleware?​

protected optional authMiddleware?: AuthMiddleware

Defined in: auth/src/routes/BaseAuthMFARoute.ts:69


defaultScopes​

protected defaultScopes: string[] = []

Defined in: auth/src/routes/BaseAuthMFARoute.ts:72


fido2Config​

protected fido2Config: PasskeyConfig

Defined in: auth/src/routes/BaseAuthMFARoute.ts:80

The relying party configuration to use for the FIDO2 secondary authentication method. See BaseAuthFIDO2Route/BaseSecretRoute.fido2Config for the primary-auth/registration counterparts of this configuration.


jwtConfig?​

protected optional jwtConfig?: any

Defined in: auth/src/routes/BaseAuthMFARoute.ts:87


logger​

protected logger: any

Defined in: auth/src/routes/BaseAuthMFARoute.ts:90


messagingUtils?​

protected optional messagingUtils?: MessagingUtils

Defined in: auth/src/routes/BaseAuthMFARoute.ts:93


passwordConfig​

protected passwordConfig: PasswordConfig

Defined in: auth/src/routes/BaseAuthMFARoute.ts:96


rateLimiter?​

protected optional rateLimiter?: RateLimiter

Defined in: auth/src/routes/BaseAuthMFARoute.ts:99


secretClass​

abstract protected secretClass: any

Defined in: auth/src/routes/BaseAuthMFARoute.ts:57


secretRepo?​

protected optional secretRepo?: RepoUtils<S>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:101


template​

protected template: string = "login-otp"

Defined in: auth/src/routes/BaseAuthMFARoute.ts:104

The name of the messaging template to use for sending notifications.


tokenUtils?​

protected optional tokenUtils?: TokenUtils

Defined in: auth/src/routes/BaseAuthMFARoute.ts:107


totpConfig​

protected totpConfig: TOTPConfig

Defined in: auth/src/routes/BaseAuthMFARoute.ts:114

Only encryption_key is read here — the rest of TOTPConfig (digits/period/algorithm/etc.) is captured onto each TOTPSecret at registration time by BaseSecretRoute, not re-read at login.


trustedProxies​

protected trustedProxies: string[] = []

Defined in: auth/src/routes/BaseAuthMFARoute.ts:117


userClass​

abstract protected userClass: any

Defined in: auth/src/routes/BaseAuthMFARoute.ts:58


userRepo?​

protected optional userRepo?: RepoUtils<U>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:119


userUtils?​

protected optional userUtils?: UserUtils<U, A>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:121

Methods​

authenticate()​

authenticate(user, req, res): Promise<AuthResult | undefined>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:195

Authenticates the user using HTTP MFA and returns a JSON Web Token access token to be used with future API requests.

Parameters​

user​

JWTUser

req​

HttpRequest

res​

HttpResponse

Returns​

Promise<AuthResult | undefined>


consumeRecoveryCode()​

protected consumeRecoveryCode(uid, codeIndex, req?): Promise<void>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:591

Persists that the recovery code at codeIndex within the identified recovery-codes secret has been consumed, so it can never be verified again. Called once, only after MFAStrategy.verifyRecoveryCode() has already matched the submitted code against that entry's hash.

Closes the same TOCTOU race described on updateSecretTimeStep() above: two concurrent requests submitting the identical still-unused recovery code both pass verifyRecoveryCode()'s in-memory hash check before either reaches here. Re-checking usedAt against a fresh read - combined with the existing optimistic-locking version check on the write - means only the first to actually persist the consumption wins; the loser throws rather than silently authenticating a second session on a code that's already been spent.

Parameters​

uid​

string

The unique id of the recovery-codes secret the matched entry belongs to.

codeIndex​

number

The index, within that secret's codes array, of the entry that was matched.

req?​

HttpRequest

The source HTTP request, used only to record the source IP on the auth.recovery_code.used event below.

Returns​

Promise<void>


convertAliasToMethod()​

protected convertAliasToMethod(alias, obfuscate?): MFAMethod | undefined

Defined in: auth/src/routes/BaseAuthMFARoute.ts:208

Parameters​

alias​

Alias

obfuscate?​

boolean

Returns​

MFAMethod | undefined


convertAliasToWhatsAppMethod()​

protected convertAliasToWhatsAppMethod(alias, obfuscate?): MFAMethod | undefined

Defined in: auth/src/routes/BaseAuthMFARoute.ts:251

Converts a verified phone alias into its WhatsApp MFAMethod, delivering the code over WhatsApp instead of SMS. Its id is derived from the alias's uid (see toWhatsAppMethodId()) so it is selectable and resolvable independently of the same alias's SMS method, whose id is the plain alias uid. The caller is responsible for only using this while WhatsApp is configured (see isWhatsAppConfigured()).

Parameters​

alias​

Alias

The alias to convert.

obfuscate?​

boolean

Set to true to obfuscate the contact, as for convertAliasToMethod().

Returns​

MFAMethod | undefined

The method, or undefined if alias isn't a verified phone.


convertSecretToMethod()​

protected convertSecretToMethod(secret, redact?): MFAMethod | undefined

Defined in: auth/src/routes/BaseAuthMFARoute.ts:279

Converts a Secret into the MFAMethod shape MFAStrategy understands.

Parameters​

secret​

S

The secret to convert.

redact?​

boolean

Set to true when the result will be sent to the (not-yet-authenticated-for-phase-3) client, e.g. via getMethods()'s res.json({uid, methods}) in phase 1 — this replaces RECOVERY_CODES' data (which would otherwise be its raw array of code hashes) with just a remaining count. Left false for internal lookups (getMethod()) that need the real data to actually verify a submission against. FIDO2/TOTP data is passed through unredacted either way — a FIDO2 credential's public key and a TOTP secret aren't attacker-usable read out of context the way a recovery code's hash array structurally is, and the client already possesses/generated both.

Returns​

MFAMethod | undefined


getCredentialById()​

protected getCredentialById(credentialId): Promise<StoredPasskeyCredential | undefined>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:317

Retrieves a previously-registered FIDO2 credential by its ID, for verifying a FIDO2 secondary authentication challenge response.

Parameters​

credentialId​

string

The unique id of the FIDO2 credential to retrieve.

Returns​

Promise<StoredPasskeyCredential | undefined>


getMethod()​

protected getMethod(id, userUid): Promise<MFAMethod | undefined>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:341

Retrieves the user's secondary authentication method for a given id. Only returns a method that actually belongs to uid — this is what stops one user's 2FA challenge from being triggered/consumed using another user's authentication method.

Parameters​

id​

string

The unique id of the secondary auth method to retrieve.

userUid​

string

The unique id of the user the method must belong to.

Returns​

Promise<MFAMethod | undefined>


getMethods()​

protected getMethods(uid): Promise<MFAMethod[]>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:389

Retrieves the list of secondary authentication methods for the user with the given id. This list is sent to the user and so should be obfuscated where reasonable so as to limit discovery when a password has been compromised.

Parameters​

uid​

string

The unique identifier of the user.

Returns​

Promise<MFAMethod[]>


getUser()​

protected getUser(uid): Promise<JWTUser | undefined>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:449

Retrieves the user with the given unique id.

Parameters​

uid​

string

The unique id of the user to retrieve.

Returns​

Promise<JWTUser | undefined>

The user if found, otherwise undefined.


initialize()​

protected initialize(): Promise<void>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:127

Called on server startup to initialize the route with any defaults.

Returns​

Promise<void>


notifyContact()​

protected notifyContact(contact, totp): Promise<void>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:456

Parameters​

contact​

OTPContact

totp​

string

Returns​

Promise<void>


obfuscateAlias()​

protected obfuscateAlias(alias, type): string

Defined in: auth/src/routes/BaseAuthMFARoute.ts:484

Obfuscates the given alias and returns the obfuscated value.

Parameters​

alias​

string

type​

AliasType

Returns​

string


updateCredentialCounter()​

protected updateCredentialCounter(credentialId, newCounter): Promise<void>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:509

Persists the updated signature counter for the given FIDO2 credential after a successful MFA challenge. Called on every successful FIDO2 secondary authentication to guard against cloned authenticators.

Parameters​

credentialId​

string

The unique id of the credential to update.

newCounter​

number

The new signature counter value to persist.

Returns​

Promise<void>


updateSecretTimeStep()​

protected updateSecretTimeStep(uid, timeStep): Promise<void>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:547

Persists the given time step as the last one successfully used for the identified TOTP secret, so a captured/replayed token can't be reused within its validity window.

Closes a TOCTOU race between two concurrent phase-3 requests both holding the same valid code: each independently verifies the submitted token before either one reaches this method, so verification alone can't tell them apart. Re-checking lastTimeStep against a fresh read here - combined with RepoUtils.update()'s existing optimistic-locking version check, which still protects the case where both readers see the same pre-update state - means at most one of the two ever succeeds in claiming this time step; the loser throws instead of silently letting a second session authenticate on an already-used code.

Parameters​

uid​

string

The unique id of the stored secret that was verified.

timeStep​

number

The RFC 6238 time step at which the token was verified.

Returns​

Promise<void>


verify()​

protected verify(name, password): Promise<JWTUser | undefined>

Defined in: auth/src/routes/BaseAuthMFARoute.ts:637

Parameters​

name​

string

password​

string

Returns​

Promise<JWTUser | undefined>