Now.js Framework Documentation
SecurityManager
SecurityManager
Overview
SecurityManager is the security management system in Now.js Framework. It supports CSRF, JWT, Rate Limiting, and Content Security Policy.
When to use:
- Need to prevent CSRF attacks
- Need to manage JWT tokens
- Need rate limiting
- Need input sanitization
- Need CSP management
Why use it:
- ✅ CSRF protection (token-based)
- ✅ JWT management (validate, refresh)
- ✅ Rate limiting (per endpoint)
- ✅ Input sanitization (XSS prevention)
- ✅ Content Security Policy
- ✅ HTTP interceptors
- ✅ Form protection
Basic Usage
Initialization
await SecurityManager.init({
csrf: {
enabled: true,
tokenName: '_token',
headerName: 'X-CSRF-Token'
},
jwt: {
enabled: true,
storageName: 'auth_token',
autoRefresh: true
},
rateLimit: {
enabled: true,
globalLimit: 100,
windowMs: 15 * 60 * 1000 // 15 minutes
}
});CSRF Protection
Auto-inject in Forms
<form action="/api/submit" method="POST">
<!-- CSRF token will be injected automatically -->
<input type="text" name="email">
<button type="submit">Submit</button>
</form>Get CSRF Token
const token = SecurityManager.getCSRFToken();
console.log(token); // 'abc123...'Manual CSRF in Requests
// SecurityManager will auto-inject in ApiService
await ApiService.post('/api/data', {
name: 'John'
});
// Request will have X-CSRF-Token header automaticallyRefresh CSRF Token
await SecurityManager.refreshCSRFToken();JWT Management
Get JWT Token
const token = SecurityManager.getJWTToken();Validate Token
const isValid = SecurityManager.validateJWTToken(token);
if (!isValid) {
// Token expired or invalid
redirectToLogin();
}Refresh Token
await SecurityManager.refreshJWTToken();Clear Token (Logout)
SecurityManager.clearJWTToken();Auto-refresh Token
SecurityManager.init({
jwt: {
enabled: true,
autoRefresh: true,
refreshThreshold: 5 * 60 * 1000 // Refresh 5 mins before expiry
}
});Rate Limiting
Check Rate Limit
const result = SecurityManager.checkRateLimit('/api/login');
if (!result.allowed) {
console.log(`Rate limited. Retry after ${result.retryAfter}ms`);
}Per-Endpoint Limits
SecurityManager.init({
rateLimit: {
enabled: true,
globalLimit: 100,
perEndpoint: {
'/api/login': { limit: 5, windowMs: 60000 }, // 5 per minute
'/api/register': { limit: 3, windowMs: 60000 }, // 3 per minute
'/api/upload': { limit: 10, windowMs: 300000 } // 10 per 5 minutes
}
}
});Input Sanitization
Sanitize Input
// Prevent XSS
const safeInput = SecurityManager.sanitizeInput(userInput);
// '<script>alert("xss")</script>' => '<script>alert("xss")</script>'Sanitize Object
const safeData = SecurityManager.sanitizeRequestData({
name: '<script>alert("xss")</script>',
email: 'user@example.com'
});
// { name: '<script>...', email: 'user@example.com' }Content Security Policy
CSP Configuration
SecurityManager.init({
csp: {
enabled: true,
directives: {
'default-src': ["'self'"],
'script-src': ["'self'", "'unsafe-inline'"],
'style-src': ["'self'", "'unsafe-inline'"],
'img-src': ["'self'", "data:", "https:"],
'connect-src': ["'self'"],
'frame-src': ["'none'"],
'object-src': ["'none'"]
}
}
});CSP Violation Reporting
SecurityManager.init({
csp: {
enabled: true,
reportUri: '/api/csp-report'
}
});
// Listen for violations
EventManager.on('csp:violation', (violation) => {
console.log('CSP Violation:', violation);
});Configuration
await SecurityManager.init({
// CSRF
csrf: {
enabled: true,
tokenName: '_token',
headerName: 'X-CSRF-Token',
cookieName: 'XSRF-TOKEN',
tokenUrl: '/api/auth/csrf-token',
autoRefresh: true,
refreshInterval: 30 * 60 * 1000 // 30 minutes
},
// JWT
jwt: {
enabled: true,
cookieName: 'auth_token',
refreshCookieName: 'refresh_token',
storageKey: 'auth_jwt', // see the note below
autoRefresh: true,
refreshBeforeExpiry: 5 * 60 * 1000, // 5 minutes
refreshEndpoint: 'api/auth/refresh',
validateSignature: true,
algorithm: 'HS256',
issuer: window.location.hostname,
audience: window.location.hostname
},
// Rate Limiting
rateLimit: {
enabled: true,
storage: 'memory',
globalLimit: 100,
windowMs: 15 * 60 * 1000,
perEndpoint: {}
},
// CSP
csp: {
enabled: false,
directives: {}
}
});
jwt.storageKeymust not collide withAuthManager'stoken.storageKey.
The default is'auth_jwt', and it holds a JWT string.AuthManager
stores the user profile (a JSON object) under'auth_user'. Both used to
default to'auth_user':initJWT()then read the profile, failed to
validate it as a JWT, andclearJWTToken()deleted it on every page load — so
the cached profile never survived and the app could not start while offline.
If your app writes a JWT to'auth_user'itself, move it to'auth_jwt'
(or setstorageKeyto a third key of your own) when upgrading. In the usual
setup the real tokens are httpOnly cookies, so this key is rarely used at all.
API Reference
CSRF Methods
SecurityManager.getCSRFToken()
Get current CSRF token
Returns: string|null
SecurityManager.refreshCSRFToken()
Refresh CSRF token from server
Returns: Promise<string>
SecurityManager.injectCSRFIntoForm(form, token?)
Inject CSRF token into form
| Parameter | Type | Description |
|---|---|---|
form |
HTMLFormElement | Form element |
JWT Methods
SecurityManager.getJWTToken()
Get JWT token
Returns: string|null
SecurityManager.validateJWTToken(token)
Validate JWT token
| Parameter | Type | Description |
|---|---|---|
token |
string | JWT token |
Returns: boolean
SecurityManager.refreshJWTToken()
Refresh JWT token
Returns: Promise<string>
SecurityManager.clearJWTToken()
Clear JWT token (logout)
Rate Limit Methods
SecurityManager.checkRateLimit(endpoint, identifier?)
Check rate limit
| Parameter | Type | Description |
|---|---|---|
endpoint |
string | API endpoint |
identifier |
string | User identifier (optional) |
Returns: Object:
{
allowed: boolean,
remaining: number,
resetTime: number,
retryAfter: number
}Sanitization Methods
SecurityManager.sanitizeInput(value)
Sanitize input string
| Parameter | Type | Description |
|---|---|---|
value |
string | Input value |
Returns: string - Sanitized value
SecurityManager.sanitizeRequestData(data)
Sanitize object/array recursively
| Parameter | Type | Description |
|---|---|---|
data |
object/array | Data to sanitize |
Returns: object/array - Sanitized data
Data Attributes
| Attribute | Description |
|---|---|
data-csrf |
On a <form>: set false or disabled to skip CSRF injection for it |
Events
| Event | When Triggered | Detail |
|---|---|---|
security:initialized |
init() completed | {csrf, jwt} |
csrf:refreshed |
A new CSRF token was obtained | {token} |
csrf:retry |
CSRF rejected (419), giving callers a chance to resend | {token} |
jwt:refreshed |
A new JWT was obtained | {token} |
jwt:cleared |
The stored JWT was dropped | none |
csp:violation |
The browser reported a CSP violation | {directive, uri, source, line, timestamp} (sent directly, not wrapped) |
security:error |
A security error occurred | {message, error} |
security:destroyed |
destroy() completed | none |
Real-World Examples
Protected API Calls
// SecurityManager will auto-inject headers
async function saveProfile(data) {
try {
// CSRF and JWT headers will be added automatically
await ApiService.put('/api/profile', data);
NotificationManager.success('Saved');
} catch (error) {
if (error.status === 419) {
// CSRF token expired
await SecurityManager.refreshCSRFToken();
// Retry
return saveProfile(data);
}
throw error;
}
}Login with Rate Limiting
async function login(email, password) {
// Check rate limit
const limit = SecurityManager.checkRateLimit('/api/login');
if (!limit.allowed) {
throw new Error(`Try again in ${Math.ceil(limit.retryAfter / 1000)} seconds`);
}
const response = await ApiService.post('/api/login', {
email: SecurityManager.sanitizeInput(email),
password
});
return response;
}Form with CSRF Protection
<form id="contact-form" action="/api/contact" method="POST" data-security>
<input type="text" name="name" required>
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<button type="submit">Send Message</button>
</form>
<script>
// SecurityManager will:
// 1. Inject CSRF token
// 2. Sanitize inputs
// 3. Check rate limit
// ... automatically
</script>Common Pitfalls
⚠️ 1. Enable CSRF for Production
// ❌ CSRF disabled in production
SecurityManager.init({ csrf: { enabled: false } });
// ✅ Enable CSRF
SecurityManager.init({ csrf: { enabled: true } });⚠️ 2. JWT Token in Memory
// ❌ Don't store JWT in localStorage for sensitive data
jwt: { storageType: 'localStorage' }
// ✅ Use memory or httpOnly cookie
jwt: { storageType: 'memory' }⚠️ 3. Sanitize User Input
// ❌ Using user input directly
element.innerHTML = userInput;
// ✅ Sanitize first
element.innerHTML = SecurityManager.sanitizeInput(userInput);
// Or use textContent
element.textContent = userInput;Related Documentation
- AuthManager - Authentication
- ApiService - API calls
- HttpClient - HTTP client