Fix jwt-token
This commit is contained in:
@@ -71,6 +71,7 @@ services:
|
|||||||
STORE_RAW_PAYLOAD: ${STORE_RAW_PAYLOAD:-false}
|
STORE_RAW_PAYLOAD: ${STORE_RAW_PAYLOAD:-false}
|
||||||
RATE_LIMIT_WINDOW_MS: ${RATE_LIMIT_WINDOW_MS:-900000}
|
RATE_LIMIT_WINDOW_MS: ${RATE_LIMIT_WINDOW_MS:-900000}
|
||||||
RATE_LIMIT_MAX_REQUESTS: ${RATE_LIMIT_MAX_REQUESTS:-1000}
|
RATE_LIMIT_MAX_REQUESTS: ${RATE_LIMIT_MAX_REQUESTS:-1000}
|
||||||
|
SECURITY_LOG_DIR: /app/logs
|
||||||
ports:
|
ports:
|
||||||
- "3002:3001"
|
- "3002:3001"
|
||||||
volumes:
|
volumes:
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
const { Tenant } = require('../models');
|
const { Tenant } = require('../models');
|
||||||
const MultiTenantAuth = require('./multi-tenant-auth');
|
const MultiTenantAuth = require('./multi-tenant-auth');
|
||||||
|
const securityLogger = require('./logger');
|
||||||
|
|
||||||
class IPRestrictionMiddleware {
|
class IPRestrictionMiddleware {
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -220,7 +221,12 @@ class IPRestrictionMiddleware {
|
|||||||
|
|
||||||
if (!isAllowed) {
|
if (!isAllowed) {
|
||||||
// Log the access attempt for security auditing
|
// Log the access attempt for security auditing
|
||||||
console.log(`[SECURITY AUDIT] ${new Date().toISOString()} - IP ${clientIP} denied access to tenant ${tenantId} - User-Agent: ${req.headers['user-agent']}`);
|
securityLogger.logIPRestriction(
|
||||||
|
clientIP,
|
||||||
|
tenantId,
|
||||||
|
req.headers['user-agent'],
|
||||||
|
true // denied
|
||||||
|
);
|
||||||
|
|
||||||
return res.status(403).json({
|
return res.status(403).json({
|
||||||
success: false,
|
success: false,
|
||||||
|
|||||||
106
server/middleware/logger.js
Normal file
106
server/middleware/logger.js
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
class SecurityLogger {
|
||||||
|
constructor() {
|
||||||
|
// Default to logs directory, but allow override via environment
|
||||||
|
this.logDir = process.env.SECURITY_LOG_DIR || path.join(__dirname, '..', 'logs');
|
||||||
|
this.logFile = path.join(this.logDir, 'security-audit.log');
|
||||||
|
|
||||||
|
// Ensure log directory exists
|
||||||
|
this.ensureLogDirectory();
|
||||||
|
}
|
||||||
|
|
||||||
|
ensureLogDirectory() {
|
||||||
|
try {
|
||||||
|
if (!fs.existsSync(this.logDir)) {
|
||||||
|
fs.mkdirSync(this.logDir, { recursive: true });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to create log directory:', error.message);
|
||||||
|
// Fallback to console logging only
|
||||||
|
this.logFile = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logSecurityEvent(level, message, metadata = {}) {
|
||||||
|
const timestamp = new Date().toISOString();
|
||||||
|
const logEntry = {
|
||||||
|
timestamp,
|
||||||
|
level: level.toUpperCase(),
|
||||||
|
message,
|
||||||
|
...metadata
|
||||||
|
};
|
||||||
|
|
||||||
|
// Always log to console for immediate visibility
|
||||||
|
console.log(`[SECURITY AUDIT] ${timestamp} - ${message}`);
|
||||||
|
|
||||||
|
// Also log to file if available
|
||||||
|
if (this.logFile) {
|
||||||
|
try {
|
||||||
|
const logLine = JSON.stringify(logEntry) + '\n';
|
||||||
|
fs.appendFileSync(this.logFile, logLine);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to write to security log file:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logIPRestriction(ip, tenant, userAgent, denied = true) {
|
||||||
|
const action = denied ? 'denied access to' : 'granted access to';
|
||||||
|
this.logSecurityEvent('WARNING', `IP ${ip} ${action} tenant ${tenant}`, {
|
||||||
|
type: 'IP_RESTRICTION',
|
||||||
|
ip,
|
||||||
|
tenant,
|
||||||
|
userAgent: userAgent || 'unknown',
|
||||||
|
denied
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
logAuthFailure(reason, metadata = {}) {
|
||||||
|
this.logSecurityEvent('ERROR', `Authentication failure: ${reason}`, {
|
||||||
|
type: 'AUTH_FAILURE',
|
||||||
|
reason,
|
||||||
|
...metadata
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
logSuspiciousActivity(activity, metadata = {}) {
|
||||||
|
this.logSecurityEvent('CRITICAL', `Suspicious activity detected: ${activity}`, {
|
||||||
|
type: 'SUSPICIOUS_ACTIVITY',
|
||||||
|
activity,
|
||||||
|
...metadata
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get recent security events for monitoring
|
||||||
|
getRecentEvents(count = 100) {
|
||||||
|
if (!this.logFile || !fs.existsSync(this.logFile)) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const content = fs.readFileSync(this.logFile, 'utf8');
|
||||||
|
const lines = content.trim().split('\n').filter(line => line);
|
||||||
|
|
||||||
|
return lines
|
||||||
|
.slice(-count)
|
||||||
|
.map(line => {
|
||||||
|
try {
|
||||||
|
return JSON.parse(line);
|
||||||
|
} catch {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.filter(Boolean);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to read security log file:', error.message);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Singleton instance
|
||||||
|
const securityLogger = new SecurityLogger();
|
||||||
|
|
||||||
|
module.exports = securityLogger;
|
||||||
Reference in New Issue
Block a user