Skip to main content

Class: OTPStrategy

Defined in: src/auth/OTPStrategy.ts:92

Implements an strategy for authenticating a user with a One Time Password (OTP) that is sent to one of the user's verified contact methods. This allows for implementation of a password-less login flow. This strategy requires that an existing user account has already been registered with at least one verified contact method.

This strategy should not to be confused with Time-Based One Time Password (TOTP) authentication which uses a pre-shared security key, often stored on the user's device (e.g. authenticator app) or digital vault (e.g. 1Password, Bitwarden, etc.). For TOTP authentication, see TOTPStrategy.

The login flow has three phases:

  1. Discovery - The client requests a list of contacts for a given user id. The getContacts() callback is used to return the list of contacts.
  2. Challenge - The client requests a OTP token to be sent to the contact with a specified id. The OTP token is generated and sent to the contact using the notify() callback and stored in the session.
  3. Verify - The client submits the OTP token and contact id. The OTP token is verified against the one stored in the session, and the associated user is resolved using the getUser() callback.

The client sends request data either in the Authorization header or the request body in standard form-data format (e.g. id=<id>&token=<otp>). For example, the initial challenge request (step 2) can be sent as Authorization: otp id=<contact_id>. The final verification request (step 3) is then sent as Authorization: otp id=<contact_id>&token=<otp>.

WARNING: Allowing discovery (setting OTPStrategyOptions.allowDiscovery to true) is a potential side-channel attack allowing anyone to discover or gather partial contact information about a given user. For improved security, the returned list of contacts is partially obfuscated. However, enough information is still provided that an attacker may be able to harvest information anyway. For example, a phone number will be obfuscated from 818-867-5309 to ****5309. An email address will be obfuscated from john.smith@gmail.com to j****th@gmail.com.

Implements

  • AuthStrategy

Constructors

Constructor

new OTPStrategy(options): OTPStrategy

Defined in: src/auth/OTPStrategy.ts:97

Parameters

options

OTPStrategyOptions

Returns

OTPStrategy

Properties

name

readonly name: string = "otp"

Defined in: src/auth/OTPStrategy.ts:93

The unique name of the strategy used to register with the AuthMiddleware.

Implementation of

AuthStrategy.name

Methods

authenticate()

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

Defined in: src/auth/OTPStrategy.ts:102

Attempts to perform authentication with the given request data. If authentication was successful, returns an AuthResult containing the authentication details. If authentication fails and required is set to true throws an error, otherwise returns undefined.

Parameters

req

HttpRequest

The request containing data to attempt authentication with.

res

HttpResponse

The response to use when writing back directly to the client.

required?

boolean

Set to true to if authentication is required to pass, otherwise set to false.

Returns

Promise<AuthResult | undefined>

Implementation of

AuthStrategy.authenticate


authenticateSync()

authenticateSync(req, res, required?): AuthResult | undefined

Defined in: src/auth/OTPStrategy.ts:132

Attempts to perform authentication with the given request data. If authentication was successful, returns an AuthResult containing the authentication details. If authentication fails and required is set to true throws an error, otherwise returns undefined.

This is the synchronous version of authenticate that performs blocking based authentication.

Parameters

req

HttpRequest

The request containing data to attempt authentication with.

res

HttpResponse

The response to use when writing back directly to the client.

required?

boolean

Set to true to if authentication is required to pass, otherwise set to false.

Returns

AuthResult | undefined

Implementation of

AuthStrategy.authenticateSync


challenge()

protected challenge(payload, req, res): Promise<any>

Defined in: src/auth/OTPStrategy.ts:145

Parameters

payload

any

req

HttpRequest

res

HttpResponse

Returns

Promise<any>


discovery()

protected discovery(req, res): Promise<any>

Defined in: src/auth/OTPStrategy.ts:136

Parameters

req

HttpRequest

res

HttpResponse

Returns

Promise<any>


verify()

protected verify(payload, req, res): Promise<JWTUser | undefined>

Defined in: src/auth/OTPStrategy.ts:166

Parameters

payload

any

req

HttpRequest

res

HttpResponse

Returns

Promise<JWTUser | undefined>