@nauth-toolkit/mfa-totp 0.1.13 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,6 +37,28 @@ exports.TOTPService = void 0;
37
37
  const otplib_1 = require("otplib");
38
38
  const QRCode = __importStar(require("qrcode"));
39
39
  const core_1 = require("@nauth-toolkit/core");
40
+ /**
41
+ * TOTP (Time-based One-Time Password) Service
42
+ *
43
+ * Handles authenticator app functionality including:
44
+ * - Secret generation for new TOTP devices
45
+ * - QR code generation for easy setup
46
+ * - TOTP code validation with time window
47
+ * - Compatible with Google Authenticator, Authy, 1Password, etc.
48
+ *
49
+ * Uses industry-standard TOTP (RFC 6238) with configurable parameters.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * // Generate TOTP setup
54
+ * const setup = await totpService.generateSecret('user@example.com');
55
+ * // Returns: { secret, qrCode, manualEntryKey, issuer, accountName }
56
+ *
57
+ * // Verify TOTP code
58
+ * const isValid = totpService.verifyCode('base32secret', '123456');
59
+ * // Returns: true if code is valid
60
+ * ```
61
+ */
40
62
  class TOTPService {
41
63
  config;
42
64
  logger;
@@ -49,32 +71,80 @@ class TOTPService {
49
71
  constructor(config, logger) {
50
72
  this.config = config;
51
73
  this.logger = logger;
74
+ // Configure otplib with settings from config
52
75
  this.configureAuthenticator();
53
76
  }
77
+ // ============================================================================
78
+ // Configuration
79
+ // ============================================================================
80
+ /**
81
+ * Configure otplib authenticator with config settings
82
+ *
83
+ * Applies TOTP configuration from NAuthConfig or uses defaults.
84
+ * Called during service initialization.
85
+ *
86
+ * @private
87
+ */
54
88
  configureAuthenticator() {
55
89
  const totpConfig = this.getTOTPConfig();
56
90
  otplib_1.authenticator.options = {
57
91
  step: totpConfig.stepSeconds,
58
92
  window: totpConfig.window,
59
93
  digits: totpConfig.digits,
60
- algorithm: totpConfig.algorithm,
94
+ algorithm: totpConfig.algorithm, // Type cast - otplib types don't match our config
61
95
  };
62
96
  this.logger?.debug?.(`TOTP configured: step=${totpConfig.stepSeconds}s, window=${totpConfig.window}, digits=${totpConfig.digits}`);
63
97
  }
98
+ /**
99
+ * Get TOTP configuration with defaults
100
+ *
101
+ * @returns Complete TOTP configuration
102
+ * @private
103
+ */
64
104
  getTOTPConfig() {
65
105
  return {
66
106
  ...this.defaultConfig,
67
107
  ...this.config.mfa?.totp,
68
108
  };
69
109
  }
110
+ /**
111
+ * Get issuer name for TOTP URIs
112
+ *
113
+ * @returns Issuer name from config or default
114
+ * @private
115
+ */
70
116
  getIssuer() {
71
117
  return this.config.mfa?.issuer || 'nauth-toolkit';
72
118
  }
119
+ // ============================================================================
120
+ // Secret Generation
121
+ // ============================================================================
122
+ /**
123
+ * Generate TOTP secret and QR code for user setup
124
+ *
125
+ * Creates a new TOTP secret, generates QR code and manual entry key.
126
+ * User must scan QR code with authenticator app to complete setup.
127
+ *
128
+ * @param accountName - User's email or username (displayed in authenticator app)
129
+ * @returns Setup information including QR code and secret
130
+ * @throws {BadRequestException} If QR code generation fails
131
+ *
132
+ * @example
133
+ * ```typescript
134
+ * const setup = await totpService.generateSecret('user@example.com');
135
+ * // Client displays QR code and manual entry key
136
+ * // User scans QR with Google Authenticator, Authy, etc.
137
+ * ```
138
+ */
73
139
  async generateSecret(accountName) {
74
140
  this.logger?.log?.(`Generating TOTP secret for: ${accountName}`);
141
+ // Generate base32-encoded secret
75
142
  const secret = otplib_1.authenticator.generateSecret();
143
+ // Get issuer name
76
144
  const issuer = this.getIssuer();
145
+ // Generate otpauth URI for QR code
77
146
  const otpauthUrl = otplib_1.authenticator.keyuri(accountName, issuer, secret);
147
+ // Generate QR code as data URL
78
148
  let qrCode;
79
149
  try {
80
150
  qrCode = await QRCode.toDataURL(otpauthUrl);
@@ -83,6 +153,7 @@ class TOTPService {
83
153
  this.logger?.error?.('Failed to generate QR code', error);
84
154
  throw new core_1.NAuthException(core_1.AuthErrorCode.INTERNAL_ERROR, 'Failed to generate QR code');
85
155
  }
156
+ // Format secret for manual entry (groups of 4 characters)
86
157
  const manualEntryKey = this.formatSecretForManualEntry(secret);
87
158
  this.logger?.log?.(`TOTP secret generated successfully for: ${accountName}`);
88
159
  return {
@@ -93,16 +164,58 @@ class TOTPService {
93
164
  accountName,
94
165
  };
95
166
  }
167
+ /**
168
+ * Format secret for manual entry
169
+ *
170
+ * Converts base32 secret into groups of 4 characters for easy manual input.
171
+ *
172
+ * @param secret - Base32-encoded secret
173
+ * @returns Formatted secret (e.g., 'ABCD EFGH IJKL MNOP')
174
+ * @private
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * formatSecretForManualEntry('ABCDEFGHIJKLMNOP')
179
+ * // Returns: 'ABCD EFGH IJKL MNOP'
180
+ * ```
181
+ */
96
182
  formatSecretForManualEntry(secret) {
97
183
  return secret.match(/.{1,4}/g)?.join(' ') || secret;
98
184
  }
185
+ // ============================================================================
186
+ // Code Verification
187
+ // ============================================================================
188
+ /**
189
+ * Verify TOTP code against secret
190
+ *
191
+ * Validates a 6-digit TOTP code using time-based verification.
192
+ * Checks current time step plus configured window (before/after).
193
+ *
194
+ * SECURITY: Uses time window to account for clock drift and user delay.
195
+ * Default window of 1 checks 3 time steps (current, ±1).
196
+ *
197
+ * @param secret - Base32-encoded TOTP secret
198
+ * @param code - 6-digit TOTP code from authenticator app
199
+ * @returns True if code is valid within time window
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * // User enters code from Google Authenticator
204
+ * const isValid = totpService.verifyCode(user.totpSecret, '123456');
205
+ * if (isValid) {
206
+ * // Grant access
207
+ * }
208
+ * ```
209
+ */
99
210
  verifyCode(secret, code) {
100
211
  try {
212
+ // Remove spaces and validate format
101
213
  const cleanCode = code.replace(/\s/g, '');
102
214
  if (!/^\d{6}$/.test(cleanCode)) {
103
215
  this.logger?.warn?.('Invalid TOTP code format');
104
216
  return false;
105
217
  }
218
+ // Verify code using otplib
106
219
  const isValid = otplib_1.authenticator.verify({
107
220
  token: cleanCode,
108
221
  secret,
@@ -120,7 +233,25 @@ class TOTPService {
120
233
  return false;
121
234
  }
122
235
  }
236
+ /**
237
+ * Verify TOTP code with additional validation
238
+ *
239
+ * Extended verification that checks code format and provides detailed error messages.
240
+ *
241
+ * @param secret - Base32-encoded TOTP secret
242
+ * @param code - TOTP code to verify
243
+ * @returns Verification result with error message if invalid
244
+ *
245
+ * @example
246
+ * ```typescript
247
+ * const result = totpService.verifyCodeWithDetails(secret, '123456');
248
+ * if (!result.valid) {
249
+ * throw new BadRequestException(result.error);
250
+ * }
251
+ * ```
252
+ */
123
253
  verifyCodeWithDetails(secret, code) {
254
+ // Validate code format
124
255
  const cleanCode = code.replace(/\s/g, '');
125
256
  if (!cleanCode) {
126
257
  return { valid: false, error: 'Code is required' };
@@ -128,30 +259,82 @@ class TOTPService {
128
259
  if (!/^\d{6}$/.test(cleanCode)) {
129
260
  return { valid: false, error: 'Code must be 6 digits' };
130
261
  }
262
+ // Verify secret format
131
263
  if (!secret || secret.length < 16) {
132
264
  return { valid: false, error: 'Invalid secret' };
133
265
  }
266
+ // Verify code
134
267
  const isValid = this.verifyCode(secret, cleanCode);
135
268
  if (!isValid) {
136
269
  return { valid: false, error: 'Invalid or expired code' };
137
270
  }
138
271
  return { valid: true };
139
272
  }
273
+ // ============================================================================
274
+ // Utility Methods
275
+ // ============================================================================
276
+ /**
277
+ * Generate current TOTP code for secret
278
+ *
279
+ * FOR TESTING ONLY - Do not use in production authentication flow.
280
+ * This method generates the current valid code for a secret.
281
+ *
282
+ * @param secret - Base32-encoded TOTP secret
283
+ * @returns Current 6-digit TOTP code
284
+ *
285
+ * @example
286
+ * ```typescript
287
+ * // Testing only
288
+ * const code = totpService.generateCode(secret);
289
+ * // Returns: '123456'
290
+ * ```
291
+ */
140
292
  generateCode(secret) {
141
293
  return otplib_1.authenticator.generate(secret);
142
294
  }
295
+ /**
296
+ * Validate secret format
297
+ *
298
+ * Checks if a secret is valid base32 and has sufficient length.
299
+ *
300
+ * @param secret - Secret to validate
301
+ * @returns True if secret is valid
302
+ *
303
+ * @example
304
+ * ```typescript
305
+ * if (!totpService.isValidSecret(secret)) {
306
+ * throw new BadRequestException('Invalid TOTP secret');
307
+ * }
308
+ * ```
309
+ */
143
310
  isValidSecret(secret) {
144
311
  if (!secret || typeof secret !== 'string') {
145
312
  return false;
146
313
  }
314
+ // Check minimum length (16 characters for 80 bits of entropy)
147
315
  if (secret.length < 16) {
148
316
  return false;
149
317
  }
318
+ // Check if valid base32 (A-Z, 2-7, no padding for otplib)
150
319
  if (!/^[A-Z2-7]+$/.test(secret)) {
151
320
  return false;
152
321
  }
153
322
  return true;
154
323
  }
324
+ /**
325
+ * Get time remaining until next code
326
+ *
327
+ * Returns seconds until the current TOTP code expires.
328
+ * Useful for UI countdowns.
329
+ *
330
+ * @returns Seconds remaining (0-30 for default 30s step)
331
+ *
332
+ * @example
333
+ * ```typescript
334
+ * const remaining = totpService.getTimeRemaining();
335
+ * // Returns: 15 (seconds until code changes)
336
+ * ```
337
+ */
155
338
  getTimeRemaining() {
156
339
  const totpConfig = this.getTOTPConfig();
157
340
  const now = Math.floor(Date.now() / 1000);
@@ -1 +1 @@
1
- {"version":3,"file":"totp.service.js","sourceRoot":"","sources":["../../src/totp.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"totp.service.js","sourceRoot":"","sources":["../../src/totp.service.ts"],"names":[],"mappings":"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"}