Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebDAV: update to v5 #6780

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 41 additions & 71 deletions db.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion meshcentral.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'); }
Expand Down
Loading