mirror of https://github.com/Lissy93/dashy.git
71 lines
2.8 KiB
JavaScript
71 lines
2.8 KiB
JavaScript
/**
|
|
* This file exports a function, used by the write config endpoint.
|
|
* It will make a backup of the users conf.yml file
|
|
* and then write their new config into the main conf.yml file.
|
|
* Finally, it will call a function with the status message
|
|
*/
|
|
const fsPromises = require('fs').promises;
|
|
const path = require('path');
|
|
|
|
module.exports = async (newConfig, render) => {
|
|
/* Either returns nothing (if using default path), or strips navigational characters from path */
|
|
const makeSafeFileName = (configObj) => {
|
|
if (!configObj || !configObj.filename) return undefined;
|
|
return configObj.filename.replaceAll('/', '').replaceAll('..', '');
|
|
};
|
|
|
|
// Path to config file (with navigational characters stripped)
|
|
const usersFileName = makeSafeFileName(newConfig);
|
|
|
|
// Path to user data directory
|
|
const userDataDirectory = process.env.USER_DATA_DIR || './user-data/';
|
|
|
|
// Define constants for the config file
|
|
const settings = {
|
|
defaultLocation: userDataDirectory,
|
|
backupLocation: process.env.BACKUP_DIR || path.join(userDataDirectory, 'config-backups'),
|
|
defaultFile: 'conf.yml',
|
|
filename: 'conf',
|
|
backupDenominator: '.backup.yml',
|
|
};
|
|
|
|
// Make the full file name and path to save the backup config file
|
|
const backupFilePath = `${path.normalize(settings.backupLocation)
|
|
}/${usersFileName || settings.filename}-`
|
|
+ `${Math.round(new Date() / 1000)}${settings.backupDenominator}`;
|
|
|
|
// The path where the main conf.yml should be read and saved to
|
|
const defaultFilePath = settings.defaultLocation + (usersFileName || settings.defaultFile);
|
|
|
|
// Returns a string confirming successful job
|
|
const getSuccessMessage = () => `Successfully backed up ${settings.defaultFile} to`
|
|
+ ` ${backupFilePath}, and updated the contents of ${defaultFilePath}`;
|
|
|
|
// Encoding options for writing to conf file
|
|
const writeFileOptions = { encoding: 'utf8' };
|
|
|
|
// Prepare the response returned by the API
|
|
const getRenderMessage = (success, errorMsg) => JSON.stringify({
|
|
success,
|
|
message: !success ? errorMsg : getSuccessMessage(),
|
|
});
|
|
|
|
// Create a backup of current config, and if backup dir doesn't yet exist, create it
|
|
await fsPromises
|
|
.mkdir(settings.backupLocation, { recursive: true })
|
|
.then(() => fsPromises.copyFile(defaultFilePath, backupFilePath))
|
|
.catch((error) => render(
|
|
getRenderMessage(false, `Unable to backup ${settings.defaultFile}: ${error}`),
|
|
));
|
|
|
|
// Writes the new content to the conf.yml file
|
|
await fsPromises
|
|
.writeFile(defaultFilePath, newConfig.config.toString(), writeFileOptions)
|
|
.catch((error) => render(
|
|
getRenderMessage(false, `Unable to write to ${settings.defaultFile}: ${error}`),
|
|
));
|
|
|
|
// If successful, then render hasn't yet been called- call it
|
|
await render(getRenderMessage(true));
|
|
};
|