{"_id":"@bonapasogit-dev/jwt-manager","name":"@bonapasogit-dev/jwt-manager","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@bonapasogit-dev/jwt-manager","version":"1.0.0","description":"High-performance JWT lifecycle management with JTI validation","main":"dist/index.js","types":"dist/index.d.ts","repository":{"type":"git","url":"git+https://github.com/bonapasogit-dev/bonatools.git"},"scripts":{"build":"npx tsc","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run build"},"keywords":["jwt","jti","token","authentication","security"],"author":"","license":"MIT","dependencies":{"jsonwebtoken":"^9.0.2","ulid":"^2.3.0"},"devDependencies":{"@types/jsonwebtoken":"^9.0.6","@types/node":"^20.11.0","typescript":"^5.3.3","vitest":"^1.2.0"},"engines":{"node":">=18.0.0"},"_id":"@bonapasogit-dev/jwt-manager@1.0.0","gitHead":"e293b0ca2c31092732af20edeb1425a843cb79b2","bugs":{"url":"https://github.com/bonapasogit-dev/bonatools/issues"},"homepage":"https://github.com/bonapasogit-dev/bonatools#readme","_nodeVersion":"22.13.1","_npmVersion":"10.9.2","dist":{"integrity":"sha512-DnehcJL6t0jnUMfPS7Qyi9os8ce/mDylYrojFM1JQoCk+Qf72hscXQ75XstjSYX2H4D3o2EKuJlg63YVCfcjUw==","shasum":"c930c8ab14a7b6e421dc79874f2fcd9988cc08f9","tarball":"https://registry.npmjs.org/@bonapasogit-dev/jwt-manager/-/jwt-manager-1.0.0.tgz","fileCount":22,"unpackedSize":52368,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIH29U3BxmsuVbK1521v7bNdP0CtgJnJC5SJyYS0i7kDoAiEA16nb9vxhLKOklS0EHuMtev0CzFJy28SlmOPuBzbggBc="}]},"_npmUser":{"name":"vldcreation","email":"vicktordesrony@gmail.com"},"directories":{},"maintainers":[{"name":"vldcreation","email":"vicktordesrony@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/jwt-manager_1.0.0_1773763303581_0.45097588343697814"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-17T16:01:43.522Z","1.0.0":"2026-03-17T16:01:43.734Z","modified":"2026-03-17T16:01:43.958Z"},"maintainers":[{"name":"vldcreation","email":"vicktordesrony@gmail.com"}],"description":"High-performance JWT lifecycle management with JTI validation","homepage":"https://github.com/bonapasogit-dev/bonatools#readme","keywords":["jwt","jti","token","authentication","security"],"repository":{"type":"git","url":"git+https://github.com/bonapasogit-dev/bonatools.git"},"bugs":{"url":"https://github.com/bonapasogit-dev/bonatools/issues"},"license":"MIT","readme":"# @bonapasogit-dev/jwt-manager\n\nHigh-performance JWT lifecycle management library with JTI validation for preventing replay attacks and enabling token revocation.\n\n## Features\n\n- ✅ **JTI Validation** - Unique token IDs using ULID for collision-free identification\n- ✅ **Token Revocation** - Blacklist tokens before expiry\n- ✅ **One-Time Tokens** - Single-use tokens with automatic invalidation\n- ✅ **Security-First** - Enforces `aud`, `iss`, `exp` claims on all tokens\n- ✅ **Multiple Algorithms** - RS256, ES256, HS256, and more\n- ✅ **TypeScript** - Full type safety with comprehensive types\n\n## Installation\n\n```bash\nnpm install @bonapasogit-dev/jwt-manager\n```\n\n## Quick Start\n\n### Using HMAC (HS256)\n\n```typescript\nimport { createJwtManager } from '@bonapasogit-dev/jwt-manager';\n\nconst jwtManager = createJwtManager({\n    algorithm: 'HS256',\n    secret: 'your-secret-key-min-32-characters-long',\n});\n\n// Sign a token\nconst token = jwtManager.sign({\n    subject: 'user-123',\n    audience: 'my-app',\n    issuer: 'auth-service',\n    expiresIn: 3600, // 1 hour\n    claims: {\n        role: 'admin',\n    },\n});\n\n// Verify a token\nconst result = await jwtManager.verify(token);\nconsole.log(result.payload.sub); // 'user-123'\nconsole.log(result.payload.jti); // ULID (e.g., '01ARZ3NDEKTSV4RRFFQ69DT1FK')\n```\n\n### Using RSA (RS256) - Recommended for Production\n\n```typescript\nimport { createJwtManager } from '@bonapasogit-dev/jwt-manager';\nimport fs from 'fs';\n\nconst jwtManager = createJwtManager({\n    algorithm: 'RS256',\n    privateKey: fs.readFileSync('./private.pem', 'utf-8'),\n    publicKey: fs.readFileSync('./public.pem', 'utf-8'),\n});\n```\n\n## Token Revocation\n\nRevoke tokens before their natural expiry:\n\n```typescript\n// Revoke by JTI\nconst payload = jwtManager.decode(token);\nawait jwtManager.revoke(payload.jti, payload.exp);\n\n// Or revoke directly from token\nawait jwtManager.revokeToken(token);\n\n// Verification will now fail\ntry {\n    await jwtManager.verify(token);\n} catch (error) {\n    if (error instanceof JwtRevokedError) {\n        console.log('Token has been revoked');\n    }\n}\n```\n\n## One-Time Tokens\n\nCreate tokens that can only be used once (e.g., for password reset):\n\n```typescript\nconst oneTimeToken = jwtManager.sign({\n    subject: 'user-123',\n    audience: 'password-reset',\n    issuer: 'auth-service',\n    expiresIn: 900, // 15 minutes\n    oneTimeToken: true,\n});\n\n// First verification succeeds\nconst result = await jwtManager.verify(oneTimeToken);\n\n// Second verification throws JwtReplayError\ntry {\n    await jwtManager.verify(oneTimeToken);\n} catch (error) {\n    if (error instanceof JwtReplayError) {\n        console.log('Token already used');\n    }\n}\n```\n\n## Custom Token Store\n\nFor distributed systems, implement the `TokenStore` interface with Redis or PostgreSQL:\n\n```typescript\nimport { TokenStore, createJwtManager } from '@bonapasogit-dev/jwt-manager';\nimport Redis from 'ioredis';\n\nclass RedisTokenStore implements TokenStore {\n    private redis: Redis;\n\n    constructor(redis: Redis) {\n        this.redis = redis;\n    }\n\n    async add(jti: string, expiresAt: number): Promise<void> {\n        const ttl = expiresAt - Math.floor(Date.now() / 1000);\n        if (ttl > 0) {\n            await this.redis.setex(`jwt:revoked:${jti}`, ttl, '1');\n        }\n    }\n\n    async has(jti: string): Promise<boolean> {\n        const exists = await this.redis.exists(`jwt:revoked:${jti}`);\n        return exists === 1;\n    }\n\n    async remove(jti: string): Promise<void> {\n        await this.redis.del(`jwt:revoked:${jti}`);\n    }\n\n    async cleanup(): Promise<void> {\n        // Redis handles TTL automatically\n    }\n}\n\nconst jwtManager = createJwtManager({\n    algorithm: 'RS256',\n    privateKey: '...',\n    publicKey: '...',\n    tokenStore: new RedisTokenStore(new Redis()),\n});\n```\n\n## Error Handling\n\n```typescript\nimport {\n    JwtExpiredError,\n    JwtRevokedError,\n    JwtReplayError,\n    JwtInvalidSignatureError,\n    JwtInvalidClaimsError,\n    JwtMalformedError,\n    isJwtError,\n    JwtErrorCode,\n} from '@bonapasogit-dev/jwt-manager';\n\ntry {\n    const result = await jwtManager.verify(token);\n} catch (error) {\n    if (isJwtError(error)) {\n        switch (error.code) {\n            case JwtErrorCode.EXPIRED:\n                // Token has expired\n                break;\n            case JwtErrorCode.REVOKED:\n                // Token was revoked\n                break;\n            case JwtErrorCode.REPLAY:\n                // One-time token already used\n                break;\n            case JwtErrorCode.INVALID_SIGNATURE:\n                // Signature verification failed\n                break;\n            case JwtErrorCode.INVALID_CLAIMS:\n                // Missing or invalid claims\n                break;\n            case JwtErrorCode.MALFORMED:\n                // Token cannot be decoded\n                break;\n        }\n    }\n}\n```\n\n## API Reference\n\n### `JwtManager`\n\n#### `sign(options: SignOptions): string`\n\nGenerate a JWT with auto-injected `jti`, `iat`, `exp` claims.\n\n#### `verify(token: string, options?: VerifyOptions): Promise<VerifyResult>`\n\nVerify a JWT's signature, expiry, and JTI status.\n\n#### `revoke(jti: string, expiresAt: number): Promise<void>`\n\nAdd a JTI to the denylist.\n\n#### `revokeToken(token: string): Promise<void>`\n\nRevoke a token by decoding and extracting its JTI.\n\n#### `decode(token: string): JwtPayload | null`\n\nDecode without verification (for inspection only).\n\n#### `isRevoked(jti: string): Promise<boolean>`\n\nCheck if a JTI has been revoked.\n\n## Security Best Practices\n\n1. **Use Asymmetric Algorithms** - RS256/ES256 for shared environments\n2. **Rotate Keys Regularly** - Every 24-48 hours for production\n3. **Keep Secrets Secure** - Use environment variables or secret managers\n4. **Set Reasonable Expiry** - Balance security with user experience\n5. **Implement Token Refresh** - Short-lived access tokens + long-lived refresh tokens\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-037073bb1682011c89a4e1db78cdf8e9"}