https://github.com/nekzus/tokenly
Secure JWT token manager
https://github.com/nekzus/tokenly
access-token authentication cookie httponly jwt oauth refresh-token security token tyepscript
Last synced: 6 months ago
JSON representation
Secure JWT token manager
- Host: GitHub
- URL: https://github.com/nekzus/tokenly
- Owner: Nekzus
- License: mit
- Created: 2025-01-18T23:02:16.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-05-08T18:32:35.000Z (8 months ago)
- Last Synced: 2025-07-13T13:43:43.517Z (6 months ago)
- Topics: access-token, authentication, cookie, httponly, jwt, oauth, refresh-token, security, token, tyepscript
- Language: TypeScript
- Homepage: https://nekzus.github.io/tokenly/
- Size: 2.57 MB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: .github/README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE.md
Awesome Lists containing this project
README
# Tokenly 🔐
[](https://github.com/Nekzus/tokenly/actions/workflows/publish.yml)
[](https://www.npmjs.com/package/@nekzus/tokenly)
[](https://www.npmjs.com/package/@nekzus/tokenly)
[](https://www.npmjs.com/package/@nekzus/tokenly)
[](https://deepwiki.com/Nekzus/tokenly)
[](https://paypal.me/maseortega)
**Advanced JWT Token Management with Device Fingerprinting**
_Enterprise-grade security by default for modern applications_
## Contents
- [Features](#-features)
- [Installation](#-installation)
- [Quick Start](#-quick-start)
- [Configuration](#-configuration)
- [Security Features](#%EF%B8%8F-security-features)
- [API Reference](#-api-reference)
- [Environment Variables](#-environment-variables--secrets)
- [Best Practices](#-best-practices)
- [Contributing](#-contributing)
- [License](#-license)
## ✨ Features
- **Zero Configuration Required**: Works out of the box with secure defaults
- **Device Fingerprinting**: Unique identification of devices to prevent token
theft
- **Framework Agnostic**: Use with Express, Fastify, Koa, or any Node.js
framework
- **TypeScript First**: Full type safety and excellent IDE support
- **Production Ready**: Built for enterprise applications
## 📦 Installation
```bash
npm install @nekzus/tokenly
```
### Required Dependencies
```bash
npm install cookie-parser
```
> ⚠️ **Important**: `cookie-parser` is required for secure handling of refresh
> tokens with HttpOnly cookies.
## 🚀 Quick Start
```typescript
import { getClientIP, Tokenly } from "@nekzus/tokenly";
import cookieParser from "cookie-parser";
import dotenv from "dotenv";
// Load environment variables
dotenv.config();
// Initialize Express
const app = express();
// Required middleware for refresh tokens
app.use(cookieParser());
// Initialize Tokenly
const auth = new Tokenly({
accessTokenExpiry: "15m",
refreshTokenExpiry: "7d",
securityConfig: {
enableFingerprint: true,
maxDevices: 5,
},
});
// Generate token with fingerprinting
app.post("/login", (req, res) => {
const token = auth.generateAccessToken(
{ userId: "123", role: "user" },
undefined,
{
userAgent: req.headers["user-agent"] || "",
ip: getClientIP(req.headers),
},
);
res.json({ token });
});
```
## 🔧 Configuration
### Basic Configuration
```typescript
const auth = new Tokenly({
accessTokenExpiry: "15m", // 15 minutes
refreshTokenExpiry: "7d", // 7 days
securityConfig: {
enableFingerprint: true, // Enable device tracking
maxDevices: 5, // Max devices per user
},
});
```
### Advanced Security Configuration
```typescript
const auth = new Tokenly({
accessTokenExpiry: "5m", // Shorter token life
refreshTokenExpiry: "1d", // Daily refresh required
securityConfig: {
enableFingerprint: true, // Required for device tracking
enableBlacklist: true, // Enable token revocation
maxDevices: 3, // Strict device limit
},
});
```
## 🛡️ Security Features
### Device Fingerprinting
- **User Agent**: Browser/client identification
- **IP Address**: Client's IP address
- **Cryptographic Salt**: Unique per instance
- **Consistent Hashing**: Same device = Same fingerprint
### Token Management
- **Access Tokens**: Short-lived JWTs for API access
- **Refresh Tokens**: Long-lived tokens for session maintenance
- **Blacklisting**: Optional token revocation support
- **Expiration Control**: Configurable token lifetimes
### Security Events
```typescript
// Invalid Fingerprint Detection
auth.on("invalid_fingerprint", (event) => {
console.log(`Security Alert: Invalid fingerprint detected`);
console.log(`User: ${event.userId}`);
console.log(`IP: ${event.context.ip}`);
});
// Device Limit Reached
auth.on("max_devices_reached", (event) => {
console.log(`Device limit reached for user: ${event.userId}`);
console.log(`Current devices: ${event.context.currentDevices}`);
});
```
## 📘 API Reference
### Token Generation
```typescript
const token = auth.generateAccessToken(
payload: { userId: string; role: string },
options?: { fingerprint?: string; deviceId?: string },
context?: { userAgent: string; ip: string }
);
```
### IP Detection Helper
```typescript
import { getClientIP } from "@nekzus/tokenly";
const clientIP = getClientIP(headers, defaultIP);
```
Priority order:
1. `X-Real-IP`: Direct proxy IP
2. `X-Forwarded-For`: First IP in proxy chain
3. Default IP (if provided)
4. Empty string (fallback)
### Type Definitions
```typescript
interface AccessToken {
raw: string;
payload: {
userId: string;
role: string;
[key: string]: any;
};
}
interface InvalidFingerprintEvent {
type: "invalid_fingerprint";
userId: string;
token: string;
context: {
expectedFingerprint: string;
receivedFingerprint: string;
ip: string;
userAgent: string;
timestamp: string;
};
}
interface MaxDevicesEvent {
type: "max_devices_reached";
userId: string;
context: {
currentDevices: number;
maxAllowed: number;
ip: string;
userAgent: string;
timestamp: string;
};
}
```
## 🔑 Environment Variables & Secrets
### Required Variables
```env
# .env
JWT_SECRET_ACCESS=your_secure_access_token_secret
JWT_SECRET_REFRESH=your_secure_refresh_token_secret
```
When environment variables are not provided, Tokenly automatically:
- Generates cryptographically secure random secrets
- Uses SHA-256 for secret generation
- Implements secure entropy sources
- Creates unique secrets per instance
> ⚠️ **Important**: While auto-generated secrets are cryptographically secure,
> they regenerate on each application restart. This means all previously issued
> tokens will become invalid. For production environments, always provide
> permanent secrets through environment variables.
### Secret Generation
```bash
# Generate secure random secrets
node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"
```
### Security Guidelines
- Never commit secrets to version control
- Use different secrets for development and production
- Minimum length of 32 characters recommended
- Rotate secrets periodically in production
- Use secret management services when available
## 🔐 Best Practices
### Token Security
- Use short-lived access tokens (5-15 minutes)
- Implement refresh token rotation
- Enable blacklisting for critical applications
### Refresh Token Security
- Use HttpOnly cookies for refresh tokens
- Configure cookie-parser middleware
- Enable secure and sameSite options in production
- Implement proper CORS configuration when needed
### Device Management
- Enable fingerprinting for sensitive applications
- Set reasonable device limits per user
- Monitor security events
### IP Detection
- Configure proxy headers correctly
- Use `X-Real-IP` for single proxy setups
- Handle `X-Forwarded-For` for proxy chains
## 🤝 Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md)
for details.
## 📄 License
MIT © [Nekzus](https://github.com/Nekzus)