{"_id":"@authcraft/totp-js","_rev":"2-25d132b1a1507311174b0e86776a4702","name":"@authcraft/totp-js","dist-tags":{"latest":"0.9.3"},"versions":{"0.9.1":{"name":"@authcraft/totp-js","version":"0.9.1","keywords":["totp","hotp","otp","2fa","two-factor","authentication","mfa","multi-factor","rfc6238","rfc4226","security","google-authenticator","time-based-one-time-password"],"author":{"name":"Pratiyush Kumar Singh","email":"pratiyush1@gmail.com"},"license":"MIT","_id":"@authcraft/totp-js@0.9.1","maintainers":[{"name":"secureotp","email":"pratiyush1@gmail.com"}],"homepage":"https://pratiyush.github.io/totp-js/","bugs":{"url":"https://github.com/Pratiyush/totp-js/issues"},"dist":{"shasum":"6b8bc44317d087e1411bd1ca6a534a65a2427ce7","tarball":"https://registry.npmjs.org/@authcraft/totp-js/-/totp-js-0.9.1.tgz","fileCount":9,"integrity":"sha512-MR8sDu9eK+NEqAZr6YN4dmx0t83ReuOr+z7Ir5UGmy6y/3hrr6BMGD2aZn3EJZIG8U+v7Y7le7TBLMbi14IKIw==","signatures":[{"sig":"MEYCIQDg3yYye8Baew3V57rGz9M4ISom/TDS0lVQu3XNFaC+ywIhAPsMakySRu2gndRzphQIfFgDg9pKQvWTzWWt7moEb/pw","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":104990},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","engines":{"node":">=22.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"gitHead":"1da97f0284d6a5c13a8d2e44dd16c20be5647a95","scripts":{"lint":"eslint src/ tests/","test":"vitest run","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build"},"_npmUser":{"name":"secureotp","email":"pratiyush1@gmail.com"},"repository":{"url":"git+https://github.com/Pratiyush/totp-js.git","type":"git"},"_npmVersion":"10.9.3","description":"Security-hardened TOTP/2FA library for JavaScript and TypeScript. RFC 6238 compliant with replay protection, constant-time verification, and zero runtime dependencies.","directories":{},"_nodeVersion":"22.18.0","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","eslint":"^9.0.0","vitest":"^4.1.2","typescript":"^6.0.2","@types/node":"^25.5.2","@vitest/coverage-v8":"^4.1.2","@typescript-eslint/parser":"^8.0.0","@typescript-eslint/eslint-plugin":"^8.0.0"},"_npmOperationalInternal":{"tmp":"tmp/totp-js_0.9.1_1775420986610_0.0877886500345395","host":"s3://npm-registry-packages-npm-production"}},"0.9.3":{"name":"@authcraft/totp-js","version":"0.9.3","description":"Security-hardened TOTP/2FA library for JavaScript and TypeScript. RFC 6238 compliant with replay protection, constant-time verification, and zero runtime dependencies.","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"scripts":{"build":"tsup","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","lint":"eslint src/ tests/","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"keywords":["totp","hotp","otp","2fa","two-factor","authentication","mfa","multi-factor","rfc6238","rfc4226","security","google-authenticator","time-based-one-time-password"],"author":{"name":"Pratiyush Kumar Singh","email":"pratiyush1@gmail.com"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/Pratiyush/totp-js.git"},"bugs":{"url":"https://github.com/Pratiyush/totp-js/issues"},"homepage":"https://pratiyush.github.io/totp-js/","engines":{"node":">=22.0.0"},"devDependencies":{"@types/node":"^25.5.2","@typescript-eslint/eslint-plugin":"^8.0.0","@typescript-eslint/parser":"^8.0.0","@vitest/coverage-v8":"^4.1.2","eslint":"^9.0.0","tsup":"^8.0.0","typescript":"^6.0.2","vitest":"^4.1.2"},"gitHead":"20e2e993620159e159c1c24ff15d9223800cf97f","_id":"@authcraft/totp-js@0.9.3","_nodeVersion":"24.14.1","_npmVersion":"11.11.0","dist":{"integrity":"sha512-PICnp7T2CoRjdhNi2d1YMWBfskx/QuObffsrts+CwQ5wyRRGAhHT4nxxr6wdR0rfEKwPjQluZn/bVvwMuWnBBQ==","shasum":"56014c2558ba5cc17d148296bcf0bab859e52a59","tarball":"https://registry.npmjs.org/@authcraft/totp-js/-/totp-js-0.9.3.tgz","fileCount":9,"unpackedSize":105210,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@authcraft%2ftotp-js@0.9.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFlDYodKa/g4edwj3jCBF2GLoFD0hrP+Y7rLN53HJZzyAiA6NU6hDh58NL470VP0m8f8Sbnix2OxBSVEcctRTcGk5A=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:3f0c42cb-300b-483b-b06e-512ec8d8bf51"}},"directories":{},"maintainers":[{"name":"secureotp","email":"pratiyush1@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/totp-js_0.9.3_1775422134681_0.971674274230609"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-05T20:29:46.545Z","modified":"2026-04-05T20:48:55.155Z","0.9.1":"2026-04-05T20:29:46.756Z","0.9.3":"2026-04-05T20:48:54.820Z"},"bugs":{"url":"https://github.com/Pratiyush/totp-js/issues"},"author":{"name":"Pratiyush Kumar Singh","email":"pratiyush1@gmail.com"},"license":"MIT","homepage":"https://pratiyush.github.io/totp-js/","keywords":["totp","hotp","otp","2fa","two-factor","authentication","mfa","multi-factor","rfc6238","rfc4226","security","google-authenticator","time-based-one-time-password"],"repository":{"type":"git","url":"git+https://github.com/Pratiyush/totp-js.git"},"description":"Security-hardened TOTP/2FA library for JavaScript and TypeScript. RFC 6238 compliant with replay protection, constant-time verification, and zero runtime dependencies.","maintainers":[{"name":"secureotp","email":"pratiyush1@gmail.com"}],"readme":"<div align=\"center\">\n\n<img src=\".github/assets/logo.png\" alt=\"totp-js logo\" width=\"200\">\n\n# totp-js\n\n**Security-hardened TOTP/2FA library for JavaScript and TypeScript**\n\n[![npm version](https://img.shields.io/npm/v/@authcraft/totp-js?style=flat-square)](https://www.npmjs.com/package/@authcraft/totp-js)\n[![Build](https://img.shields.io/github/actions/workflow/status/Pratiyush/totp-js/ci.yml?style=flat-square)](https://github.com/Pratiyush/totp-js/actions)\n[![Coverage](https://img.shields.io/codecov/c/github/Pratiyush/totp-js?style=flat-square)](https://codecov.io/gh/Pratiyush/totp-js)\n[![npm downloads](https://img.shields.io/npm/dm/@authcraft/totp-js?style=flat-square)](https://www.npmjs.com/package/@authcraft/totp-js)\n[![MIT License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](CONTRIBUTING.md)\n\nRFC 6238 (TOTP) and RFC 4226 (HOTP) compliant. Zero runtime dependencies.\nBuilt-in replay protection. Constant-time verification. Works with Node.js 18+.\n\n[Documentation](https://pratiyush.github.io/totp-js/) | [npm](https://www.npmjs.com/package/@authcraft/totp-js) | [API Reference](#api-reference)\n\n</div>\n\n---\n\n## Why totp-js?\n\nMost TOTP libraries give you the basics — generate a code, verify it. But production 2FA needs more:\n\n- **Replay protection** — prevent the same code from being used twice\n- **Constant-time verification** — prevent timing attacks that leak information\n- **Secure defaults** — preset configurations so you don't need to be a cryptography expert\n- **Zero dependencies** — no supply chain risk for your authentication layer\n\ntotp-js is the TypeScript counterpart to [totp-impl](https://github.com/Pratiyush/totp-impl) (Java), sharing the same security-first API design.\n\n## Install\n\n```bash\n# npm\nnpm install @authcraft/totp-js\n\n# yarn\nyarn add @authcraft/totp-js\n\n# pnpm\npnpm add @authcraft/totp-js\n```\n\n## Quick Start\n\n```typescript\nimport { TOTP, generateSecret } from '@authcraft/totp-js';\n\n// Generate a secret for the user\nconst secret = generateSecret();\n\n// Create a TOTP instance\nconst totp = TOTP.defaultInstance();\n\n// Generate a code\nconst code = totp.generate(secret);\nconsole.log(code); // \"482915\"\n\n// Verify a code\nconst isValid = totp.verify(secret, code);\nconsole.log(isValid); // true\n```\n\n## Replay Protection\n\nPrevent the same OTP from being used twice within its validity window:\n\n```typescript\nimport { TOTP, generateSecret, InMemoryReplayGuard } from '@authcraft/totp-js';\n\nconst guard = InMemoryReplayGuard.withDefaultRetention();\nconst totp = TOTP.create({ replayGuard: guard });\nconst secret = generateSecret();\n\nconst code = totp.generate(secret);\n\n// First verification — passes\ntotp.verify(secret, code, 'user-123'); // true\n\n// Same code, same user — blocked!\ntotp.verify(secret, code, 'user-123'); // false (replay detected)\n\n// Don't forget to clean up when done\nguard.destroy();\n```\n\n## QR Code URI\n\nGenerate `otpauth://` URIs for QR code scanning with Google Authenticator, Authy, etc.:\n\n```typescript\nimport { buildOtpauthUri, generateSecret } from '@authcraft/totp-js';\n\nconst secret = generateSecret();\nconst uri = buildOtpauthUri(secret, 'user@example.com', 'MyApp');\n// otpauth://totp/MyApp%3Auser%40example.com?secret=...&issuer=MyApp&algorithm=SHA1&digits=6&period=30\n```\n\n## Configuration\n\n### Preset Configurations\n\n```typescript\nimport { TOTP, defaultConfig, sha256Config, highSecurityConfig } from '@authcraft/totp-js';\n\n// Default: SHA1, 6 digits, 30s period, drift ±1\nconst standard = TOTP.create({ ...defaultConfig() });\n\n// SHA-256: recommended for new deployments\nconst sha256 = TOTP.create({ ...sha256Config() });\n\n// High security: SHA-512, 8 digits\nconst highSec = TOTP.create({ ...highSecurityConfig() });\n```\n\n### Custom Configuration\n\n```typescript\nimport { TOTP, Algorithm } from '@authcraft/totp-js';\n\nconst totp = TOTP.create({\n  algorithm: Algorithm.SHA256,\n  digits: 8,\n  period: 60,        // 60-second window\n  allowedDrift: 2,   // accept codes ±2 periods\n});\n```\n\n### Configuration Constraints\n\n| Parameter | Min | Max | Default |\n|-----------|-----|-----|---------|\n| `period` | 15s | 120s | 30s |\n| `digits` | 6 | 8 | 6 |\n| `allowedDrift` | 0 | 5 | 1 |\n\n## Detailed Verification\n\nGet more context about verification results:\n\n```typescript\nconst result = totp.verifyWithDetails(secret, code);\nconsole.log(result);\n// { valid: true, timeOffset: 0, message: 'Valid' }\n// { valid: false, timeOffset: 0, message: 'Invalid code' }\n// { valid: false, timeOffset: 1, message: 'Code already used' }\n```\n\n## Framework Integration\n\n### Express.js\n\n```typescript\nimport express from 'express';\nimport { TOTP, generateSecret, InMemoryReplayGuard, buildOtpauthUri } from '@authcraft/totp-js';\n\nconst app = express();\napp.use(express.json());\n\nconst guard = InMemoryReplayGuard.withDefaultRetention();\nconst totp = TOTP.create({ replayGuard: guard });\n\n// Setup 2FA for a user\napp.post('/2fa/setup', (req, res) => {\n  const secret = generateSecret();\n  const uri = buildOtpauthUri(secret, req.body.email, 'MyApp');\n  // Store secret in your database\n  res.json({ secret, qrUri: uri });\n});\n\n// Verify 2FA code\napp.post('/2fa/verify', (req, res) => {\n  const { userId, code, secret } = req.body;\n  const isValid = totp.verify(secret, code, userId);\n  res.json({ valid: isValid });\n});\n```\n\n### Next.js API Route\n\n```typescript\n// app/api/2fa/verify/route.ts\nimport { NextResponse } from 'next/server';\nimport { TOTP, InMemoryReplayGuard } from '@authcraft/totp-js';\n\nconst guard = InMemoryReplayGuard.withDefaultRetention();\nconst totp = TOTP.create({ replayGuard: guard });\n\nexport async function POST(request: Request) {\n  const { secret, code, userId } = await request.json();\n  const isValid = totp.verify(secret, code, userId);\n  return NextResponse.json({ valid: isValid });\n}\n```\n\n### NestJS\n\n```typescript\nimport { Injectable } from '@nestjs/common';\nimport { TOTP, generateSecret, InMemoryReplayGuard, buildOtpauthUri } from '@authcraft/totp-js';\n\n@Injectable()\nexport class TwoFactorService {\n  private readonly totp: TOTP;\n  private readonly guard: InMemoryReplayGuard;\n\n  constructor() {\n    this.guard = InMemoryReplayGuard.withDefaultRetention();\n    this.totp = TOTP.create({ replayGuard: this.guard });\n  }\n\n  setup(email: string) {\n    const secret = generateSecret();\n    const uri = buildOtpauthUri(secret, email, 'MyApp');\n    return { secret, qrUri: uri };\n  }\n\n  verify(secret: string, code: string, userId: string): boolean {\n    return this.totp.verify(secret, code, userId);\n  }\n}\n```\n\n### Fastify\n\n```typescript\nimport Fastify from 'fastify';\nimport { TOTP, generateSecret, InMemoryReplayGuard } from '@authcraft/totp-js';\n\nconst app = Fastify();\nconst guard = InMemoryReplayGuard.withDefaultRetention();\nconst totp = TOTP.create({ replayGuard: guard });\n\napp.post('/2fa/verify', async (request, reply) => {\n  const { secret, code, userId } = request.body as any;\n  const isValid = totp.verify(secret, code, userId);\n  return { valid: isValid };\n});\n```\n\n## Secret Generation\n\n```typescript\nimport { generateSecret, generateRawSecret, isValidSecret, Algorithm } from '@authcraft/totp-js';\n\n// Default (SHA1, 20 bytes)\nconst secret = generateSecret();\n\n// Algorithm-appropriate size\nconst sha256Secret = generateSecret(Algorithm.SHA256); // 32 bytes\nconst sha512Secret = generateSecret(Algorithm.SHA512); // 64 bytes\n\n// Raw bytes for custom encoding\nconst rawBytes = generateRawSecret(32);\n\n// Validate existing secrets\nisValidSecret(secret); // true\nisValidSecret('abc');   // false (too short)\n```\n\n## API Reference\n\n### TOTP\n\n| Method | Description |\n|--------|-------------|\n| `TOTP.create(options?)` | Create with custom options |\n| `TOTP.defaultInstance()` | Create with defaults (SHA1, 6 digits, 30s) |\n| `generate(secret)` | Generate code for current time |\n| `generateAt(secret, timestamp)` | Generate code for specific timestamp (ms) |\n| `generateForCounter(secret, counter)` | Generate code for specific counter |\n| `verify(secret, code, userId?)` | Verify code (with optional replay guard) |\n| `verifyWithDetails(secret, code, userId?)` | Verify with detailed result |\n| `getCurrentCounter()` | Get current time counter |\n| `getSecondsRemaining()` | Seconds until next code |\n\n### Configuration\n\n| Preset | Algorithm | Digits | Period | Drift |\n|--------|-----------|--------|--------|-------|\n| `defaultConfig()` | SHA-1 | 6 | 30s | ±1 |\n| `sha256Config()` | SHA-256 | 6 | 30s | ±1 |\n| `highSecurityConfig()` | SHA-512 | 8 | 30s | ±1 |\n\n### Algorithm Support\n\n| Algorithm | Key Size | Recommended For |\n|-----------|----------|-----------------|\n| SHA-1 | 20 bytes | Legacy compatibility (Google Authenticator default) |\n| SHA-256 | 32 bytes | New deployments (recommended) |\n| SHA-512 | 64 bytes | Maximum security |\n\n## Security Features\n\n- **Constant-time comparison** using `crypto.timingSafeEqual()` — prevents timing attacks\n- **Replay protection** via `InMemoryReplayGuard` — prevents code reuse\n- **Secret validation** — enforces minimum 128-bit entropy (16 bytes)\n- **No sensitive data in errors** — error messages never contain secrets or codes\n- **Zero runtime dependencies** — minimized attack surface\n\n## Building from Source\n\n```bash\ngit clone https://github.com/Pratiyush/totp-js.git\ncd totp-js\nnpm install\nnpm run build\nnpm test\n```\n\n## Links\n\n- [Documentation](https://pratiyush.github.io/totp-js/) — GitHub Pages with interactive demo\n- [npm](https://www.npmjs.com/package/@authcraft/totp-js) — `npm install @authcraft/totp-js`\n- [GitHub](https://github.com/Pratiyush/totp-js) — Source code, issues, PRs\n- [totp-impl](https://github.com/Pratiyush/totp-impl) — Java counterpart ([Maven Central](https://central.sonatype.com/artifact/io.github.pratiyush/totp-lib))\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## License\n\n[MIT](LICENSE) — Pratiyush Kumar Singh\n","readmeFilename":"README.md"}