Skip to content

otplib API Documentation / @otplib/totp / TOTPVerifyOptions

Type Alias: TOTPVerifyOptions

TOTPVerifyOptions = TOTPGenerateOptions & object

Defined in: totp/src/types.ts:81

Required options for TOTP verification

Requires secret, token, and crypto for verification.

Type Declaration

afterTimeStep?

readonly optional afterTimeStep: number

Minimum time step for replay protection (optional)

Specifies an exclusive lower bound for valid time steps. Time steps less than or equal to this value will be rejected during verification. This prevents reuse of TOTP codes from previously verified time steps.

Per RFC 6238, time step T = floor((CurrentUnixTime - T0) / X), where X is the period. This is the time step number, not a Unix timestamp.

Validation:

  • Must be a non-negative integer
  • Cannot be greater than current time step plus window
  • Throws on invalid values (fail-fast for development)

Use case: Track the time step from each successful verification and pass it as afterTimeStep in subsequent verifications to prevent replay attacks.

Examples

typescript
// First verification
const result1 = await verify({ secret, token, crypto });
// result1 = { valid: true, delta: 0, timeStep: 41152263, epoch: 1234578900 }
await saveLastTimeStep(result1.timeStep);

// Subsequent verification - rejects codes from time step 41152263 and earlier
const lastTimeStep = await getLastTimeStep();
const result2 = await verify({
  secret,
  token: newToken,
  crypto,
  afterTimeStep: lastTimeStep, // Reject timeStep <= 41152263
});
typescript
// Current time step: 41152263, window: 1
verify({
  secret,
  token,
  crypto,
  afterTimeStep: 41152262, // Rejects 41152262 and earlier
  epochTolerance: 30,       // Allows 41152263, 41152264 (within window)
});

epochTolerance?

readonly optional epochTolerance: number | [number, number]

Time tolerance in seconds (default: 0 = current period only)

Accepts tokens that were or will be valid within the specified tolerance of the current time. This aligns with RFC 6238's transmission delay concept.

See

RFC 6238 Section 5.2

  • Number: symmetric tolerance (same for past and future) epochTolerance: 5 checks [epoch - 5, epoch + 5]

  • Tuple [past, future]: asymmetric tolerance epochTolerance: [5, 0] checks [epoch - 5, epoch] (RFC-compliant, past only) epochTolerance: [5, 10] checks [epoch - 5, epoch + 10]

Examples

typescript
// RFC-compliant (transmission delay only, past tokens)
epochTolerance: [5, 0]

// High security (banking, critical systems)
epochTolerance: 5  // or [5, 5] symmetric

// Standard (most 2FA implementations)
epochTolerance: 30

// Lenient (poor network, user-friendly)
epochTolerance: 60
With period=30 and epochTolerance=[5, 0] (RFC-compliant):

Period N-1         | Period N (current)  | Period N+1
[token A valid]    | [token B valid]     | [token C valid]
                   |                     |
At epoch in period N:
- If 0-5 sec into period:  A valid, B valid
- If 6-29 sec into period: B valid only
(Future tokens never accepted)

token

readonly token: string

The OTP token to verify

Released under the MIT License.