added back up functionality and ability to download latest back up, latest backup displayed in settings

This commit is contained in:
Ro 2020-08-13 12:53:51 -07:00
parent c90797433d
commit 682bc32a46
10 changed files with 144 additions and 3 deletions

View file

@ -4,6 +4,8 @@ import Render from '../../data/Render';
import Settings, { SETTINGS_FILE, SETTINGS_FOLKS } from '../../data/Settings'; import Settings, { SETTINGS_FILE, SETTINGS_FOLKS } from '../../data/Settings';
import Navigation from '../../data/Navigation'; import Navigation from '../../data/Navigation';
import Book from '../../data/Book'; import Book from '../../data/Book';
import Utils from '../../data/Utils';
import { util } from 'prettier';
const express = require('express'); const express = require('express');
const router = express.Router(); const router = express.Router();
const multer = require('multer'); const multer = require('multer');
@ -15,6 +17,7 @@ const render = new Render();
const book = new Book(); const book = new Book();
const settings = new Settings(); const settings = new Settings();
const nav = new Navigation(); const nav = new Navigation();
const utils = new Utils();
const uploadPath = const uploadPath =
'./public/assets/images/user/' + moment().format('YYYY') + '/' + moment().format('MM'); './public/assets/images/user/' + moment().format('YYYY') + '/' + moment().format('MM');
@ -204,6 +207,56 @@ router.post('/add-feature-background', background_upload, (req, res) => {
}); });
} }
}); });
/***
CREATE BACK UP
*/
router.post('/create-backup', (req, res) => {
auth.authCheck(req)
.then(() => {
utils
.createBackup()
.then(() => {
res.json({
type: DataEvent.API_BACKUP_CREATE,
message: "You're backed up. Hi fives"
});
})
.catch(err => {
res.json({
type: err.type,
message: err.message
});
});
})
.catch(err => {
res.json({
type: err.type,
message: err.message
});
});
});
router.get('/download-backup', (req, res) => {
var filePath = 'content/backup.zip'; // Or format the path using the `id` rest param
var fileName = 'backup.zip'; // The default name the browser will use
res.download(filePath, fileName);
//Make secure
/*
auth.authCheck(req)
.then(() => {
})
.catch(err => {
res.json({
type: err.type,
message: err.message
});
});
*/
});
module.exports = router; module.exports = router;
function getBookData() { function getBookData() {

View file

@ -7,6 +7,7 @@ const render = new Render();
const stringUtils = new StringUtils(); const stringUtils = new StringUtils();
const moment = require('moment'); const moment = require('moment');
const fs = require('fs-extra'); const fs = require('fs-extra');
const AdmZip = require('adm-zip');
export default class Utils { export default class Utils {
constructor() {} constructor() {}
@ -130,4 +131,28 @@ export default class Utils {
//console.log('ERROR', err); //console.log('ERROR', err);
}); });
} }
createBackup() {
//let self = this;
var response;
return new Promise(resolve => {
var zip = new AdmZip();
zip.addLocalFolder('public', 'public/');
zip.addLocalFolder('content/pages', 'pages/');
zip.addLocalFile('site/folks.json', 'settings/');
zip.addLocalFile('site/settings.json', 'settings/');
zip.addLocalFile('site/tags.json', 'settings/');
zip.writeZip('public/backup.zip');
fs.readJSON('site/settings.json').then(settings => {
settings.global.last_backup = moment(Date.now()).format();
fs.writeJSON('site/settings.json', settings);
});
response = {
type: '',
message: 'BACKUP CREATED'
};
resolve(response);
});
}
} }

View file

@ -4,6 +4,7 @@ const router = express.Router();
const FileHound = require('filehound'); const FileHound = require('filehound');
const fs = require('fs-extra'); const fs = require('fs-extra');
const settings = new Settings(); const settings = new Settings();
const moment = require('moment');
var config = []; var config = [];
//-------------------------- //--------------------------
// SETTINGS // SETTINGS
@ -39,6 +40,7 @@ router.get('/', function (req, res) {
status: true, status: true,
themes: themes, themes: themes,
settings: config, settings: config,
last_backup: moment(config.global.last_backup).fromNow(),
member: memberInfo[0] member: memberInfo[0]
}); });
} else { } else {

View file

@ -39,6 +39,21 @@ block main-content
input(type='text', name='base-title' id='settings-title', placeholder='site title', value=settings.global.title, autofocus) input(type='text', name='base-title' id='settings-title', placeholder='site title', value=settings.global.title, autofocus)
textarea(id="settings-desc" type='text', name='settings_desc' class='settings-dec', placeholder='description stuff', autofocus) textarea(id="settings-desc" type='text', name='settings_desc' class='settings-dec', placeholder='description stuff', autofocus)
=settings.global.descriptions =settings.global.descriptions
#member-utils.columns
#util-1.column
label MEMBER UTILS
br
button#create-backup CREATE BACKUP
br
-if(settings.global.last_backup != null)
br
| The last back up was
a(href='/api/v1/settings/download-backup')= last_backup
-else
br
span No back ups. Frowny face.
#util-2.column
<a href="">SOMETHING</a>
#option-settings.columns #option-settings.columns
#theme-settings.column #theme-settings.column
label THEMES label THEMES

5
package-lock.json generated
View file

@ -1590,6 +1590,11 @@
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.0.tgz", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.0.tgz",
"integrity": "sha512-ugTb7Lq7u4GfWSqqpwE0bGyoBZNMTok/zDBXxfEG0QM50jNlGhIWjRC1pPN7bvV1anhF+bs+/gNcRw+o55Evbg==" "integrity": "sha512-ugTb7Lq7u4GfWSqqpwE0bGyoBZNMTok/zDBXxfEG0QM50jNlGhIWjRC1pPN7bvV1anhF+bs+/gNcRw+o55Evbg=="
}, },
"adm-zip": {
"version": "0.4.16",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.16.tgz",
"integrity": "sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg=="
},
"agent-base": { "agent-base": {
"version": "4.2.1", "version": "4.2.1",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",

View file

@ -17,6 +17,7 @@
"node": ">=10.16.0" "node": ">=10.16.0"
}, },
"dependencies": { "dependencies": {
"adm-zip": "^0.4.16",
"bcrypt": "^5.0.0", "bcrypt": "^5.0.0",
"bluebird": "^3.7.2", "bluebird": "^3.7.2",
"body-parser": "latest", "body-parser": "latest",

View file

@ -77,6 +77,10 @@ export default class SettingsIndex {
for (i = 0, length = mailBtn.length; i < length; i++) { for (i = 0, length = mailBtn.length; i < length; i++) {
mailBtn[i].addEventListener('click', e => this.handleMailOptions(e)); mailBtn[i].addEventListener('click', e => this.handleMailOptions(e));
} }
//handle backup
document
.getElementById('create-backup')
.addEventListener('click', e => this.handleBackup(e));
} }
//-------------------------- //--------------------------
// event handlers // event handlers
@ -169,4 +173,17 @@ export default class SettingsIndex {
notify.alert(err, false); notify.alert(err, false);
}); });
} }
handleBackup(e) {
e.preventDefault();
e.stopPropagation();
let task = { task: 'create_backup' };
admin
.createBackup(task)
.then(r => {
notify.alert(r.message, true);
})
.catch(err => {
notify.alert(err, false);
});
}
} }

View file

@ -27,6 +27,7 @@ export const API_PAGE_WRITE = 'writingItDown';
export const API_PAGE_CREATE = 'writingNewEntry'; export const API_PAGE_CREATE = 'writingNewEntry';
export const API_PAGE_DELETE = 'erasingPage'; export const API_PAGE_DELETE = 'erasingPage';
export const API_SETTINGS_WRITE = 'savingSettings'; export const API_SETTINGS_WRITE = 'savingSettings';
export const API_BACKUP_CREATE = 'createBackup';
export const API_IMAGES_UPLOAD = 'uploadProfileImages'; export const API_IMAGES_UPLOAD = 'uploadProfileImages';
export const API_RENDER_PAGES = 'renderPages'; export const API_RENDER_PAGES = 'renderPages';
export const API_INIT = 'blogInit'; export const API_INIT = 'blogInit';

View file

@ -18,6 +18,8 @@ export const API_UPLOAD_AVATAR = '/api/v1/settings/add-avatar';
export const API_UPLOAD_BACKGROUND = '/api/v1/settings/add-feature-background'; export const API_UPLOAD_BACKGROUND = '/api/v1/settings/add-feature-background';
export const API_PUBLISH_PAGES = '/api/v1/settings/publish-pages'; export const API_PUBLISH_PAGES = '/api/v1/settings/publish-pages';
export const API_NAV_SYNC = '/api/v1/settings/nav-sync'; export const API_NAV_SYNC = '/api/v1/settings/nav-sync';
export const API_CREATE_BACKUP = '/api/v1/settings/create-backup';
export const API_DOWNLOAD_BACKUP = '/api/v1/settings/download-backup';
export const API_SEND_MAIL = '/api/v1/mailer'; export const API_SEND_MAIL = '/api/v1/mailer';
import * as DataEvent from '../com/events/DataEvent'; import * as DataEvent from '../com/events/DataEvent';
export default class APIUtils { export default class APIUtils {
@ -188,6 +190,23 @@ export default class APIUtils {
}); });
}); });
} }
createBackup(data) {
return new Promise((resolve, reject) => {
this._request(
API_CREATE_BACKUP,
DataEvent.API_BACKUP_CREATE,
REQUEST_TYPE_POST,
CONTENT_TYPE_JSON,
data
)
.then(result => {
resolve(result);
})
.catch(err => {
reject(err);
});
});
}
//-------------------------- //--------------------------
// private // private
//-------------------------- //--------------------------
@ -218,7 +237,8 @@ export default class APIUtils {
eventType === DataEvent.API_IMAGES_UPLOAD || eventType === DataEvent.API_IMAGES_UPLOAD ||
eventType === DataEvent.API_SETTINGS_WRITE || eventType === DataEvent.API_SETTINGS_WRITE ||
eventType === DataEvent.API_PAGE_DELETE || eventType === DataEvent.API_PAGE_DELETE ||
eventType === DataEvent.API_RENDER_PAGES eventType === DataEvent.API_RENDER_PAGES ||
eventType === DataEvent.API_BACKUP_CREATE
) )
request.setRequestHeader('x-access-token', self.token); request.setRequestHeader('x-access-token', self.token);

View file

@ -58,7 +58,7 @@
width 100% width 100%
height 45px height 45px
#member-settings, #site-settings, #option-settings #member-settings, #site-settings, #option-settings, #member-utils
background $primary background $primary
padding 5px padding 5px
border-radius 5px 0 5px 0 border-radius 5px 0 5px 0
@ -66,6 +66,8 @@
label label
font-family $monoType font-family $monoType
color $white color $white
span
color $secondary
input input
width 95% width 95%