diff --git a/db.js b/db.js index 81ea222cf6..0e39de2767 100644 --- a/db.js +++ b/db.js @@ -3776,84 +3776,54 @@ module.exports.CreateDB = function (parent, func) { } } - // Perform cloud backup - obj.performCloudBackup = function (filename, func) { - // WebDAV Backup - if ((typeof parent.config.settings.autobackup == 'object') && (typeof parent.config.settings.autobackup.webdav == 'object')) { - parent.debug( 'backup', 'Entering WebDAV backup'); - if (func) { func('Entering WebDAV backup.'); } - - const xdateTimeSort = function (a, b) { if (a.xdate > b.xdate) return 1; if (a.xdate < b.xdate) return -1; return 0; } + async function webDAVBackup(filename, func) { + try { + const webDAV = await import ('webdav'); + const wdConfig = parent.config.settings.autobackup.webdav; + const client = webDAV.createClient(wdConfig.url, { + username: wdConfig.username, + password: wdConfig.password, + maxContentLength: Infinity, + maxBodyLength: Infinity + }); // Fetch the folder name - var webdavfolderName = 'MeshCentral-Backups'; - if (typeof parent.config.settings.autobackup.webdav.foldername == 'string') { webdavfolderName = parent.config.settings.autobackup.webdav.foldername; } + let webdavfolderName = 'MeshCentral-Backups'; + if (typeof wdConfig.foldername == 'string') { webdavfolderName = wdConfig.foldername; } - // Clean up our WebDAV folder - function performWebDavCleanup(client) { - if ((typeof parent.config.settings.autobackup.webdav.maxfiles == 'number') && (parent.config.settings.autobackup.webdav.maxfiles > 1)) { - let fileName = parent.config.settings.autobackup.backupname; + if (await client.exists(webdavfolderName) === false) { + await client.createDirectory(webdavfolderName, { recursive: true}); + } else { + // Clean up our WebDAV folder + if ((typeof wdConfig.maxfiles == 'number') && (wdConfig.maxfiles > 1)) { + const fileName = parent.config.settings.autobackup.backupname; //only files matching our backupfilename - let directoryItems = client.getDirectoryContents(webdavfolderName, { deep: false, glob: "/**/" + fileName + "*.zip" }); - directoryItems.then( - function (files) { - for (var i in files) { files[i].xdate = new Date(files[i].lastmod); } - files.sort(xdateTimeSort); - parent.debug('backup','WebDAV filtered directory contents: ' + JSON.stringify(files, null, 4)); - while (files.length >= parent.config.settings.autobackup.webdav.maxfiles) { - let delFile = files.shift().filename; - client.deleteFile(delFile).then(function (state) { - parent.debug('backup','WebDAV file deleted: ' + delFile); - if (func) { func('WebDAV file deleted: ' + delFile); } - }).catch(function (err) { - console.error(err); - if (func) { func('WebDAV (deleteFile) error: ' + err.message); } - }); - } - } - ).catch(function (err) { - console.error(err); - if (func) { func('WebDAV (getDirectoryContents) error: ' + err.message); } - }); + let files = await client.getDirectoryContents(webdavfolderName, { deep: false, glob: "/**/" + fileName + "*.zip" }); + const xdateTimeSort = function (a, b) { if (a.xdate > b.xdate) return 1; if (a.xdate < b.xdate) return -1; return 0; } + for (const i in files) { files[i].xdate = new Date(files[i].lastmod); } + files.sort(xdateTimeSort); + while (files.length >= wdConfig.maxfiles) { + let delFile = files.shift().filename; + await client.deleteFile(delFile); + console.log('WebDAV file deleted: ' + delFile); if (func) { func('WebDAV file deleted: ' + delFile); } + } } } - // Upload to the WebDAV folder - function performWebDavUpload(client, filepath) { - require('fs').stat(filepath, function(err,stat){ - var fileStream = require('fs').createReadStream(filepath); - fileStream.on('close', function () { console.log('WebDAV upload completed: ' + webdavfolderName + '/' + require('path').basename(filepath)); if (func) { func('WebDAV upload completed: ' + webdavfolderName + '/' + require('path').basename(filepath)); } }) - fileStream.on('error', function (err) { console.error(err); if (func) { func('WebDAV (fileUpload) error: ' + err.message); } }) - fileStream.pipe(client.createWriteStream('/' + webdavfolderName + '/' + require('path').basename(filepath), { headers: { "Content-Length": stat.size } })); - parent.debug('backup', 'Uploading using WebDAV to: ' + parent.config.settings.autobackup.webdav.url); - if (func) { func('Uploading using WebDAV to: ' + parent.config.settings.autobackup.webdav.url); } - }); - } + const { pipeline } = require('stream/promises'); + await pipeline(fs.createReadStream(filename), client.createWriteStream('/' + webdavfolderName + '/' + path.basename(filename))); + console.log('WebDAV upload completed: ' + webdavfolderName + '/' + path.basename(filename)); if (func) { func('WebDAV upload completed: ' + webdavfolderName + '/' + path.basename(filename)); } + } + catch(err) { + console.error('WebDAV error: ' + err.message); if (func) { func('WebDAV error: ' + err.message);} + } + } - const { createClient } = require('webdav'); - const client = createClient(parent.config.settings.autobackup.webdav.url, { - username: parent.config.settings.autobackup.webdav.username, - password: parent.config.settings.autobackup.webdav.password, - maxContentLength: Infinity, - maxBodyLength: Infinity - }); - client.exists(webdavfolderName).then(function(a){ - if(a){ - performWebDavCleanup(client); - performWebDavUpload(client, filename); - }else{ - client.createDirectory(webdavfolderName, {recursive: true}).then(function (a) { - console.log('backup','WebDAV folder created: ' + webdavfolderName); - if (func) { func('WebDAV folder created: ' + webdavfolderName); } - performWebDavUpload(client, filename); - }).catch(function (err) { - console.error(err); - if (func) { func('WebDAV (createDirectory) error: ' + err.message); } - }); - } - }).catch(function (err) { - console.error(err); - if (func) { func('WebDAV (exists) error: ' + err.message); } - }); + // Perform cloud backup + obj.performCloudBackup = function (filename, func) { + // WebDAV Backup + if ((typeof parent.config.settings.autobackup == 'object') && (typeof parent.config.settings.autobackup.webdav == 'object')) { + parent.debug( 'backup', 'Entering WebDAV backup'); if (func) { func('Entering WebDAV backup.'); } + webDAVBackup(filename, func); } // Google Drive Backup diff --git a/meshcentral.js b/meshcentral.js index b5af6d1b02..0bb5ab217a 100644 --- a/meshcentral.js +++ b/meshcentral.js @@ -4281,7 +4281,7 @@ function mainStart() { if (typeof config.settings.autobackup.googledrive == 'object') { modules.push('googleapis@128.0.0'); } // Enable WebDAV Support if (typeof config.settings.autobackup.webdav == 'object') { - if ((typeof config.settings.autobackup.webdav.url != 'string') || (typeof config.settings.autobackup.webdav.username != 'string') || (typeof config.settings.autobackup.webdav.password != 'string')) { addServerWarning("Missing WebDAV parameters.", 2, null, !args.launch); } else { modules.push('webdav@4.11.4'); } + if ((typeof config.settings.autobackup.webdav.url != 'string') || (typeof config.settings.autobackup.webdav.username != 'string') || (typeof config.settings.autobackup.webdav.password != 'string')) { addServerWarning("Missing WebDAV parameters.", 2, null, !args.launch); } else { modules.push('webdav@5.8.0'); } } // Enable S3 Support if (typeof config.settings.autobackup.s3 == 'object') { modules.push('minio@8.0.2'); }