require('dotenv').config(); const sql = require('mssql'); const AWS = require('aws-sdk'); const fs = require('fs'); const path = require('path'); const SambaClient = require('samba-client'); // AWS S3 Configuration const s3 = new AWS.S3({ accessKeyId: process.env.AWS_ACCESS_KEY_ID, secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, region: process.env.AWS_REGION }); // MSSQL Configuration const config = { user: process.env.MSSQL_USER, password: process.env.MSSQL_PASSWORD, server: process.env.MSSQL_SERVER, port: parseInt(process.env.MSSQL_PORT) || 1433, database: process.env.MSSQL_DATABASE, options: { encrypt: true, // Use this if you're on Windows Azure trustServerCertificate: true // Change to true for local dev / self-signed certs } }; // Backup file path const backupFilePath = process.env.BACKUP_FILE_PATH; // SMB Configuration const smbConfig = { address: process.env.SMB_ADDRESS, username: process.env.SMB_USERNAME, password: process.env.SMB_PASSWORD, domain: process.env.SMB_DOMAIN || '', // optional }; // Ensure download directory exists const downloadFile = process.env.SMB_DOWNLOAD_FILE; const localDownloadFile = process.env.SMB_LOCAL_DOWNLOAD_FILE; // Function to create database backup async function createDatabaseBackup() { try { console.log('Connecting to database...'); await sql.connect(config); console.log('Creating database backup...'); const backupQuery = ` BACKUP DATABASE [${process.env.MSSQL_DATABASE}] TO DISK = N'${backupFilePath}' WITH NOFORMAT, NOINIT, NAME = N'${process.env.MSSQL_DATABASE}-Vollständig Datenbank Sichern', SKIP, NOREWIND, NOUNLOAD, STATS = 10 `; const result = await sql.query(backupQuery); console.log('Database backup created successfully'); return backupFilePath; } catch (err) { console.error('Error creating database backup:', err); throw err; } finally { await sql.close(); } } // Function to download backup file from SMB share async function downloadBackupFile() { try { console.log('Downloading backup file from SMB share...'); // Create SMB client const client = new SambaClient(smbConfig); // Download file from SMB share await client.getFile(downloadFile, localDownloadFile); console.log('Backup file downloaded successfully to:', localDownloadFile); return localDownloadFile; } catch (err) { console.error('Error downloading backup file from SMB share:', err); throw err; } } // Function to upload backup to S3 async function uploadBackupToS3(filePath) { try { console.log('Uploading backup to S3...'); // Create a read stream for the file const fileStream = fs.createReadStream(filePath); // Handle stream errors fileStream.on('error', (err) => { console.error('File stream error:', err); throw err; }); // Create S3 upload parameters using stream const params = { Bucket: process.env.S3_BUCKET_NAME, Key: `backups/${process.env.MSSQL_DATABASE}_${new Date().toISOString().replace(/[:.]/g, '-')}.bak`, Body: fileStream }; // Upload file to S3 using stream const data = await s3.upload(params).promise(); console.log('Backup uploaded successfully to S3:', data.Location); return data.Location; } catch (err) { console.error('Error uploading backup to S3:', err); throw err; } } // Function to run backup process async function runBackupProcess() { try { console.log('Starting backup process at', new Date().toISOString()); // Create database backup await createDatabaseBackup(); // Download backup file from SMB share const localBackupFile = await downloadBackupFile(); // Upload backup to S3 const s3Url = await uploadBackupToS3(localBackupFile); console.log('Backup process completed successfully at', new Date().toISOString()); console.log('Backup available at:', s3Url); } catch (err) { console.error('Backup process failed:', err); } } // Run backup immediately when starting runBackupProcess(); // Schedule backup to run every 24 hours (86400000 milliseconds) // You can adjust this interval as needed setInterval(runBackupProcess, 86400000); console.log('Database backup service started. Running backups every 24 hours.');