diff --git a/.gitignore b/.gitignore index 11b5578..1e9f36a 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,8 @@ coverage/ temp/ tmp/ *.tmp +backend/temp/* +!backend/temp/.gitkeep # MinIO configuration .mc/ diff --git a/backend/docker-entrypoint.sh b/backend/docker-entrypoint.sh index d2f4b81..d47211a 100755 --- a/backend/docker-entrypoint.sh +++ b/backend/docker-entrypoint.sh @@ -6,5 +6,10 @@ if [ ! -d "/app/logs" ]; then mkdir -p /app/logs fi +# Ensure temp directory exists +if [ ! -d "/app/temp" ]; then + mkdir -p /app/temp +fi + # Start the application exec node src/app.js \ No newline at end of file diff --git a/backend/src/services/minio.service.js b/backend/src/services/minio.service.js index e6b8bef..93d838f 100644 --- a/backend/src/services/minio.service.js +++ b/backend/src/services/minio.service.js @@ -12,7 +12,7 @@ const execAsync = util.promisify(exec); class MinIOService { constructor(alias = config.minio.defaultAlias) { this.alias = alias; - this.tempDir = path.join(__dirname, '../../../temp'); + this.tempDir = process.env.TEMP_DIR || path.join(__dirname, '../../temp'); this.ensureTempDir(); } diff --git a/backend/src/utils/logger.js b/backend/src/utils/logger.js index cba7988..1774f4a 100644 --- a/backend/src/utils/logger.js +++ b/backend/src/utils/logger.js @@ -1,10 +1,20 @@ const winston = require('winston'); const DailyRotateFile = require('winston-daily-rotate-file'); const path = require('path'); +const fs = require('fs'); const config = require('../config'); const logDir = process.env.LOG_DIR || path.join(__dirname, '../../logs'); +// Ensure log directory exists +try { + if (!fs.existsSync(logDir)) { + fs.mkdirSync(logDir, { recursive: true }); + } +} catch (error) { + console.error('Failed to create log directory:', error); +} + // Define log format const logFormat = winston.format.combine( winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), @@ -72,22 +82,30 @@ const logger = winston.createLogger({ }); // Create audit logger for security events -const auditLogger = winston.createLogger({ - level: 'info', - format: logFormat, - transports: [ - new DailyRotateFile({ - filename: path.join(logDir, 'audit-%DATE%.log'), - datePattern: 'YYYY-MM-DD', - maxSize: '20m', - maxFiles: '90d', - }) - ], -}); +let auditLogger; +if (config.app.env === 'production') { + auditLogger = winston.createLogger({ + level: 'info', + format: logFormat, + transports: [ + new DailyRotateFile({ + filename: path.join(logDir, 'audit-%DATE%.log'), + datePattern: 'YYYY-MM-DD', + maxSize: '20m', + maxFiles: '90d', + }) + ], + exitOnError: false, + }); +} else { + // In development, just use the main logger for audit events + auditLogger = logger; +} // Helper function for audit logging const logAudit = (action, { userId, ip, resource, status, details = {} }) => { - auditLogger.info({ + const auditEntry = { + audit: true, action, userId, ip, @@ -95,7 +113,13 @@ const logAudit = (action, { userId, ip, resource, status, details = {} }) => { status, details, timestamp: new Date().toISOString(), - }); + }; + + if (config.app.env === 'production') { + auditLogger.info(auditEntry); + } else { + logger.info('AUDIT:', auditEntry); + } }; module.exports = {