mirror of https://github.com/requarks/wiki
parent
a508b2a7f4
commit
414dc386d6
@ -0,0 +1,24 @@
|
|||||||
|
# Change Log
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
### Added
|
||||||
|
- Change log
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Fixed issue with social accounts with empty name
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Updated dependencies + snyk policy
|
||||||
|
- Conversion to Standard JS compliant code
|
||||||
|
|
||||||
|
## [v1.0-beta.2] - 2017-01-30
|
||||||
|
### Added
|
||||||
|
- Save own profile under My Account
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Updated dependencies + snyk policy
|
||||||
|
|
||||||
|
[Unreleased]: https://github.com/Requarks/wiki/compare/v1.0-beta.2...HEAD
|
||||||
|
[v1.0-beta.2]: https://github.com/Requarks/wiki/releases/tag/v1.0-beta.2
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,16 +1,16 @@
|
|||||||
|
|
||||||
function setInputSelection(input, startPos, endPos) {
|
function setInputSelection (input, startPos, endPos) {
|
||||||
input.focus();
|
input.focus()
|
||||||
if (typeof input.selectionStart != "undefined") {
|
if (typeof input.selectionStart !== 'undefined') {
|
||||||
input.selectionStart = startPos;
|
input.selectionStart = startPos
|
||||||
input.selectionEnd = endPos;
|
input.selectionEnd = endPos
|
||||||
} else if (document.selection && document.selection.createRange) {
|
} else if (document.selection && document.selection.createRange) {
|
||||||
// IE branch
|
// IE branch
|
||||||
input.select();
|
input.select()
|
||||||
var range = document.selection.createRange();
|
var range = document.selection.createRange()
|
||||||
range.collapse(true);
|
range.collapse(true)
|
||||||
range.moveEnd("character", endPos);
|
range.moveEnd('character', endPos)
|
||||||
range.moveStart("character", startPos);
|
range.moveStart('character', startPos)
|
||||||
range.select();
|
range.select()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,11 +1,9 @@
|
|||||||
|
|
||||||
function makeSafePath(rawPath) {
|
function makeSafePath (rawPath) {
|
||||||
|
let rawParts = _.split(_.trim(rawPath), '/')
|
||||||
let rawParts = _.split(_.trim(rawPath), '/');
|
|
||||||
rawParts = _.map(rawParts, (r) => {
|
rawParts = _.map(rawParts, (r) => {
|
||||||
return _.kebabCase(_.deburr(_.trim(r)));
|
return _.kebabCase(_.deburr(_.trim(r)))
|
||||||
});
|
})
|
||||||
|
|
||||||
return _.join(_.filter(rawParts, (r) => { return !_.isEmpty(r); }), '/');
|
|
||||||
|
|
||||||
|
return _.join(_.filter(rawParts, (r) => { return !_.isEmpty(r) }), '/')
|
||||||
}
|
}
|
@ -1,7 +1,5 @@
|
|||||||
"use strict";
|
'use strict'
|
||||||
|
|
||||||
jQuery( document ).ready(function( $ ) {
|
jQuery(document).ready(function ($) {
|
||||||
|
$('#login-user').focus()
|
||||||
$('#login-user').focus();
|
})
|
||||||
|
|
||||||
});
|
|
||||||
|
@ -1,29 +1,27 @@
|
|||||||
|
|
||||||
//-> Create New Document
|
// -> Create New Document
|
||||||
|
|
||||||
let suggestedCreatePath = currentBasePath + '/new-page';
|
let suggestedCreatePath = currentBasePath + '/new-page'
|
||||||
|
|
||||||
$('.btn-create-prompt').on('click', (ev) => {
|
$('.btn-create-prompt').on('click', (ev) => {
|
||||||
$('#txt-create-prompt').val(suggestedCreatePath);
|
$('#txt-create-prompt').val(suggestedCreatePath)
|
||||||
$('#modal-create-prompt').toggleClass('is-active');
|
$('#modal-create-prompt').toggleClass('is-active')
|
||||||
setInputSelection($('#txt-create-prompt').get(0), currentBasePath.length + 1, suggestedCreatePath.length);
|
setInputSelection($('#txt-create-prompt').get(0), currentBasePath.length + 1, suggestedCreatePath.length)
|
||||||
$('#txt-create-prompt').removeClass('is-danger').next().addClass('is-hidden');
|
$('#txt-create-prompt').removeClass('is-danger').next().addClass('is-hidden')
|
||||||
});
|
})
|
||||||
|
|
||||||
$('#txt-create-prompt').on('keypress', (ev) => {
|
$('#txt-create-prompt').on('keypress', (ev) => {
|
||||||
if(ev.which === 13) {
|
if (ev.which === 13) {
|
||||||
$('.btn-create-go').trigger('click');
|
$('.btn-create-go').trigger('click')
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
$('.btn-create-go').on('click', (ev) => {
|
$('.btn-create-go').on('click', (ev) => {
|
||||||
|
let newDocPath = makeSafePath($('#txt-create-prompt').val())
|
||||||
let newDocPath = makeSafePath($('#txt-create-prompt').val());
|
if (_.isEmpty(newDocPath)) {
|
||||||
if(_.isEmpty(newDocPath)) {
|
$('#txt-create-prompt').addClass('is-danger').next().removeClass('is-hidden')
|
||||||
$('#txt-create-prompt').addClass('is-danger').next().removeClass('is-hidden');
|
|
||||||
} else {
|
} else {
|
||||||
$('#txt-create-prompt').parent().addClass('is-loading');
|
$('#txt-create-prompt').parent().addClass('is-loading')
|
||||||
window.location.assign('/create/' + newDocPath);
|
window.location.assign('/create/' + newDocPath)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
});
|
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
|
|
||||||
if($('#page-type-create').length) {
|
if ($('#page-type-create').length) {
|
||||||
|
let pageEntryPath = $('#page-type-create').data('entrypath')
|
||||||
|
|
||||||
let pageEntryPath = $('#page-type-create').data('entrypath');
|
// -> Discard
|
||||||
|
|
||||||
//-> Discard
|
|
||||||
|
|
||||||
$('.btn-create-discard').on('click', (ev) => {
|
$('.btn-create-discard').on('click', (ev) => {
|
||||||
$('#modal-create-discard').toggleClass('is-active');
|
$('#modal-create-discard').toggleClass('is-active')
|
||||||
});
|
})
|
||||||
|
|
||||||
//=include ../components/editor.js
|
|
||||||
|
|
||||||
|
// =include ../components/editor.js
|
||||||
}
|
}
|
@ -1,14 +1,12 @@
|
|||||||
|
|
||||||
if($('#page-type-edit').length) {
|
if ($('#page-type-edit').length) {
|
||||||
|
let pageEntryPath = $('#page-type-edit').data('entrypath')
|
||||||
|
|
||||||
let pageEntryPath = $('#page-type-edit').data('entrypath');
|
// -> Discard
|
||||||
|
|
||||||
//-> Discard
|
|
||||||
|
|
||||||
$('.btn-edit-discard').on('click', (ev) => {
|
$('.btn-edit-discard').on('click', (ev) => {
|
||||||
$('#modal-edit-discard').toggleClass('is-active');
|
$('#modal-edit-discard').toggleClass('is-active')
|
||||||
});
|
})
|
||||||
|
|
||||||
//=include ../components/editor.js
|
|
||||||
|
|
||||||
|
// =include ../components/editor.js
|
||||||
}
|
}
|
@ -1,18 +1,16 @@
|
|||||||
|
|
||||||
if($('#page-type-source').length) {
|
if ($('#page-type-source').length) {
|
||||||
|
var scEditor = ace.edit('source-display')
|
||||||
|
scEditor.setTheme('ace/theme/tomorrow_night')
|
||||||
|
scEditor.getSession().setMode('ace/mode/markdown')
|
||||||
|
scEditor.setOption('fontSize', '14px')
|
||||||
|
scEditor.setOption('hScrollBarAlwaysVisible', false)
|
||||||
|
scEditor.setOption('wrap', true)
|
||||||
|
scEditor.setReadOnly(true)
|
||||||
|
scEditor.renderer.updateFull()
|
||||||
|
|
||||||
var scEditor = ace.edit("source-display");
|
let currentBasePath = ($('#page-type-source').data('entrypath') !== 'home') ? $('#page-type-source').data('entrypath') : ''
|
||||||
scEditor.setTheme("ace/theme/tomorrow_night");
|
|
||||||
scEditor.getSession().setMode("ace/mode/markdown");
|
|
||||||
scEditor.setOption('fontSize', '14px');
|
|
||||||
scEditor.setOption('hScrollBarAlwaysVisible', false);
|
|
||||||
scEditor.setOption('wrap', true);
|
|
||||||
scEditor.setReadOnly(true);
|
|
||||||
scEditor.renderer.updateFull();
|
|
||||||
|
|
||||||
let currentBasePath = ($('#page-type-source').data('entrypath') !== 'home') ? $('#page-type-source').data('entrypath') : '';
|
|
||||||
|
|
||||||
//=include ../modals/create.js
|
|
||||||
//=include ../modals/move.js
|
|
||||||
|
|
||||||
|
// =include ../modals/create.js
|
||||||
|
// =include ../modals/move.js
|
||||||
}
|
}
|
@ -1,9 +1,7 @@
|
|||||||
|
|
||||||
if($('#page-type-view').length) {
|
if ($('#page-type-view').length) {
|
||||||
|
let currentBasePath = ($('#page-type-view').data('entrypath') !== 'home') ? $('#page-type-view').data('entrypath') : ''
|
||||||
let currentBasePath = ($('#page-type-view').data('entrypath') !== 'home') ? $('#page-type-view').data('entrypath') : '';
|
|
||||||
|
|
||||||
//=include ../modals/create.js
|
|
||||||
//=include ../modals/move.js
|
|
||||||
|
|
||||||
|
// =include ../modals/create.js
|
||||||
|
// =include ../modals/move.js
|
||||||
}
|
}
|
@ -1,80 +1,80 @@
|
|||||||
var express = require('express');
|
'use strict'
|
||||||
var router = express.Router();
|
|
||||||
var passport = require('passport');
|
const express = require('express')
|
||||||
var ExpressBrute = require('express-brute');
|
const router = express.Router()
|
||||||
var ExpressBruteMongooseStore = require('express-brute-mongoose');
|
const passport = require('passport')
|
||||||
var moment = require('moment');
|
const ExpressBrute = require('express-brute')
|
||||||
|
const ExpressBruteMongooseStore = require('express-brute-mongoose')
|
||||||
|
const moment = require('moment')
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setup Express-Brute
|
* Setup Express-Brute
|
||||||
*/
|
*/
|
||||||
var EBstore = new ExpressBruteMongooseStore(db.Bruteforce);
|
const EBstore = new ExpressBruteMongooseStore(db.Bruteforce)
|
||||||
var bruteforce = new ExpressBrute(EBstore, {
|
const bruteforce = new ExpressBrute(EBstore, {
|
||||||
freeRetries: 5,
|
freeRetries: 5,
|
||||||
minWait: 60 * 1000,
|
minWait: 60 * 1000,
|
||||||
maxWait: 5 * 60 * 1000,
|
maxWait: 5 * 60 * 1000,
|
||||||
refreshTimeoutOnRequest: false,
|
refreshTimeoutOnRequest: false,
|
||||||
failCallback(req, res, next, nextValidRequestDate) {
|
failCallback (req, res, next, nextValidRequestDate) {
|
||||||
req.flash('alert', {
|
req.flash('alert', {
|
||||||
class: 'error',
|
class: 'error',
|
||||||
title: 'Too many attempts!',
|
title: 'Too many attempts!',
|
||||||
message: "You've made too many failed attempts in a short period of time, please try again " + moment(nextValidRequestDate).fromNow() + '.',
|
message: "You've made too many failed attempts in a short period of time, please try again " + moment(nextValidRequestDate).fromNow() + '.',
|
||||||
iconClass: 'fa-times'
|
iconClass: 'fa-times'
|
||||||
});
|
})
|
||||||
res.redirect('/login');
|
res.redirect('/login')
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Login form
|
* Login form
|
||||||
*/
|
*/
|
||||||
router.get('/login', function(req, res, next) {
|
router.get('/login', function (req, res, next) {
|
||||||
res.render('auth/login', {
|
res.render('auth/login', {
|
||||||
usr: res.locals.usr
|
usr: res.locals.usr
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
router.post('/login', bruteforce.prevent, function(req, res, next) {
|
|
||||||
passport.authenticate('local', function(err, user, info) {
|
|
||||||
|
|
||||||
if (err) { return next(err); }
|
router.post('/login', bruteforce.prevent, function (req, res, next) {
|
||||||
|
passport.authenticate('local', function (err, user, info) {
|
||||||
|
if (err) { return next(err) }
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
req.flash('alert', {
|
req.flash('alert', {
|
||||||
title: 'Invalid login',
|
title: 'Invalid login',
|
||||||
message: "The email or password is invalid."
|
message: 'The email or password is invalid.'
|
||||||
});
|
})
|
||||||
return res.redirect('/login');
|
return res.redirect('/login')
|
||||||
}
|
}
|
||||||
|
|
||||||
req.logIn(user, function(err) {
|
req.logIn(user, function (err) {
|
||||||
if (err) { return next(err); }
|
if (err) { return next(err) }
|
||||||
req.brute.reset(function () {
|
req.brute.reset(function () {
|
||||||
return res.redirect('/');
|
return res.redirect('/')
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
})(req, res, next)
|
||||||
})(req, res, next);
|
})
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Social Login
|
* Social Login
|
||||||
*/
|
*/
|
||||||
|
|
||||||
router.get('/login/ms', passport.authenticate('windowslive', { scope: ['wl.signin', 'wl.basic', 'wl.emails'] }));
|
router.get('/login/ms', passport.authenticate('windowslive', { scope: ['wl.signin', 'wl.basic', 'wl.emails'] }))
|
||||||
router.get('/login/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
|
router.get('/login/google', passport.authenticate('google', { scope: ['profile', 'email'] }))
|
||||||
router.get('/login/facebook', passport.authenticate('facebook', { scope: ['public_profile', 'email'] }));
|
router.get('/login/facebook', passport.authenticate('facebook', { scope: ['public_profile', 'email'] }))
|
||||||
|
|
||||||
router.get('/login/ms/callback', passport.authenticate('windowslive', { failureRedirect: '/login', successRedirect: '/' }));
|
router.get('/login/ms/callback', passport.authenticate('windowslive', { failureRedirect: '/login', successRedirect: '/' }))
|
||||||
router.get('/login/google/callback', passport.authenticate('google', { failureRedirect: '/login', successRedirect: '/' }));
|
router.get('/login/google/callback', passport.authenticate('google', { failureRedirect: '/login', successRedirect: '/' }))
|
||||||
router.get('/login/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/login', successRedirect: '/' }));
|
router.get('/login/facebook/callback', passport.authenticate('facebook', { failureRedirect: '/login', successRedirect: '/' }))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logout
|
* Logout
|
||||||
*/
|
*/
|
||||||
router.get('/logout', function(req, res) {
|
router.get('/logout', function (req, res) {
|
||||||
req.logout();
|
req.logout()
|
||||||
res.redirect('/');
|
res.redirect('/')
|
||||||
});
|
})
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router
|
||||||
|
@ -1,184 +1,160 @@
|
|||||||
"use strict";
|
'use strict'
|
||||||
|
|
||||||
var express = require('express');
|
const express = require('express')
|
||||||
var router = express.Router();
|
const router = express.Router()
|
||||||
|
|
||||||
var readChunk = require('read-chunk'),
|
const readChunk = require('read-chunk')
|
||||||
fileType = require('file-type'),
|
const fileType = require('file-type')
|
||||||
Promise = require('bluebird'),
|
const Promise = require('bluebird')
|
||||||
fs = Promise.promisifyAll(require('fs-extra')),
|
const fs = Promise.promisifyAll(require('fs-extra'))
|
||||||
path = require('path'),
|
const path = require('path')
|
||||||
_ = require('lodash');
|
const _ = require('lodash')
|
||||||
|
|
||||||
var validPathRe = new RegExp("^([a-z0-9\\/-]+\\.[a-z0-9]+)$");
|
const validPathRe = new RegExp('^([a-z0-9\\/-]+\\.[a-z0-9]+)$')
|
||||||
var validPathThumbsRe = new RegExp("^([0-9]+\\.png)$");
|
const validPathThumbsRe = new RegExp('^([0-9]+\\.png)$')
|
||||||
|
|
||||||
// ==========================================
|
// ==========================================
|
||||||
// SERVE UPLOADS FILES
|
// SERVE UPLOADS FILES
|
||||||
// ==========================================
|
// ==========================================
|
||||||
|
|
||||||
router.get('/t/*', (req, res, next) => {
|
router.get('/t/*', (req, res, next) => {
|
||||||
|
let fileName = req.params[0]
|
||||||
let fileName = req.params[0];
|
if (!validPathThumbsRe.test(fileName)) {
|
||||||
if(!validPathThumbsRe.test(fileName)) {
|
return res.sendStatus(404).end()
|
||||||
return res.sendStatus(404).end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: Authentication-based access
|
// todo: Authentication-based access
|
||||||
|
|
||||||
res.sendFile(fileName, {
|
res.sendFile(fileName, {
|
||||||
root: lcdata.getThumbsPath(),
|
root: lcdata.getThumbsPath(),
|
||||||
dotfiles: 'deny'
|
dotfiles: 'deny'
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
res.status(err.status).end();
|
res.status(err.status).end()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
})
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/img', lcdata.uploadImgHandler, (req, res, next) => {
|
router.post('/img', lcdata.uploadImgHandler, (req, res, next) => {
|
||||||
|
let destFolder = _.chain(req.body.folder).trim().toLower().value()
|
||||||
let destFolder = _.chain(req.body.folder).trim().toLower().value();
|
|
||||||
|
|
||||||
upl.validateUploadsFolder(destFolder).then((destFolderPath) => {
|
upl.validateUploadsFolder(destFolder).then((destFolderPath) => {
|
||||||
|
if (!destFolderPath) {
|
||||||
if(!destFolderPath) {
|
res.json({ ok: false, msg: 'Invalid Folder' })
|
||||||
res.json({ ok: false, msg: 'Invalid Folder' });
|
return true
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.map(req.files, (f) => {
|
Promise.map(req.files, (f) => {
|
||||||
|
let destFilename = ''
|
||||||
let destFilename = '';
|
let destFilePath = ''
|
||||||
let destFilePath = '';
|
|
||||||
|
|
||||||
return lcdata.validateUploadsFilename(f.originalname, destFolder, true).then((fname) => {
|
return lcdata.validateUploadsFilename(f.originalname, destFolder, true).then((fname) => {
|
||||||
|
destFilename = fname
|
||||||
|
destFilePath = path.resolve(destFolderPath, destFilename)
|
||||||
|
|
||||||
destFilename = fname;
|
return readChunk(f.path, 0, 262)
|
||||||
destFilePath = path.resolve(destFolderPath, destFilename);
|
|
||||||
|
|
||||||
return readChunk(f.path, 0, 262);
|
|
||||||
|
|
||||||
}).then((buf) => {
|
}).then((buf) => {
|
||||||
|
// -> Check MIME type by magic number
|
||||||
|
|
||||||
//-> Check MIME type by magic number
|
let mimeInfo = fileType(buf)
|
||||||
|
if (!_.includes(['image/png', 'image/jpeg', 'image/gif', 'image/webp'], mimeInfo.mime)) {
|
||||||
let mimeInfo = fileType(buf);
|
return Promise.reject(new Error('Invalid file type.'))
|
||||||
if(!_.includes(['image/png', 'image/jpeg', 'image/gif', 'image/webp'], mimeInfo.mime)) {
|
|
||||||
return Promise.reject(new Error('Invalid file type.'));
|
|
||||||
}
|
}
|
||||||
return true;
|
return true
|
||||||
|
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
|
// -> Move file to final destination
|
||||||
|
|
||||||
//-> Move file to final destination
|
return fs.moveAsync(f.path, destFilePath, { clobber: false })
|
||||||
|
|
||||||
return fs.moveAsync(f.path, destFilePath, { clobber: false });
|
|
||||||
|
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
return {
|
return {
|
||||||
ok: true,
|
ok: true,
|
||||||
filename: destFilename,
|
filename: destFilename,
|
||||||
filesize: f.size
|
filesize: f.size
|
||||||
};
|
}
|
||||||
}).reflect();
|
}).reflect()
|
||||||
|
|
||||||
}, {concurrency: 3}).then((results) => {
|
}, {concurrency: 3}).then((results) => {
|
||||||
let uplResults = _.map(results, (r) => {
|
let uplResults = _.map(results, (r) => {
|
||||||
if(r.isFulfilled()) {
|
if (r.isFulfilled()) {
|
||||||
return r.value();
|
return r.value()
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
msg: r.reason().message
|
msg: r.reason().message
|
||||||
};
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
res.json({ ok: true, results: uplResults });
|
})
|
||||||
return true;
|
res.json({ ok: true, results: uplResults })
|
||||||
|
return true
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
res.json({ ok: false, msg: err.message });
|
res.json({ ok: false, msg: err.message })
|
||||||
return true;
|
return true
|
||||||
});
|
})
|
||||||
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
router.post('/file', lcdata.uploadFileHandler, (req, res, next) => {
|
router.post('/file', lcdata.uploadFileHandler, (req, res, next) => {
|
||||||
|
let destFolder = _.chain(req.body.folder).trim().toLower().value()
|
||||||
let destFolder = _.chain(req.body.folder).trim().toLower().value();
|
|
||||||
|
|
||||||
upl.validateUploadsFolder(destFolder).then((destFolderPath) => {
|
upl.validateUploadsFolder(destFolder).then((destFolderPath) => {
|
||||||
|
if (!destFolderPath) {
|
||||||
if(!destFolderPath) {
|
res.json({ ok: false, msg: 'Invalid Folder' })
|
||||||
res.json({ ok: false, msg: 'Invalid Folder' });
|
return true
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Promise.map(req.files, (f) => {
|
Promise.map(req.files, (f) => {
|
||||||
|
let destFilename = ''
|
||||||
let destFilename = '';
|
let destFilePath = ''
|
||||||
let destFilePath = '';
|
|
||||||
|
|
||||||
return lcdata.validateUploadsFilename(f.originalname, destFolder, false).then((fname) => {
|
return lcdata.validateUploadsFilename(f.originalname, destFolder, false).then((fname) => {
|
||||||
|
destFilename = fname
|
||||||
|
destFilePath = path.resolve(destFolderPath, destFilename)
|
||||||
|
|
||||||
destFilename = fname;
|
// -> Move file to final destination
|
||||||
destFilePath = path.resolve(destFolderPath, destFilename);
|
|
||||||
|
|
||||||
//-> Move file to final destination
|
|
||||||
|
|
||||||
return fs.moveAsync(f.path, destFilePath, { clobber: false });
|
|
||||||
|
|
||||||
|
return fs.moveAsync(f.path, destFilePath, { clobber: false })
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
return {
|
return {
|
||||||
ok: true,
|
ok: true,
|
||||||
filename: destFilename,
|
filename: destFilename,
|
||||||
filesize: f.size
|
filesize: f.size
|
||||||
};
|
}
|
||||||
}).reflect();
|
}).reflect()
|
||||||
|
|
||||||
}, {concurrency: 3}).then((results) => {
|
}, {concurrency: 3}).then((results) => {
|
||||||
let uplResults = _.map(results, (r) => {
|
let uplResults = _.map(results, (r) => {
|
||||||
if(r.isFulfilled()) {
|
if (r.isFulfilled()) {
|
||||||
return r.value();
|
return r.value()
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
ok: false,
|
ok: false,
|
||||||
msg: r.reason().message
|
msg: r.reason().message
|
||||||
};
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
res.json({ ok: true, results: uplResults });
|
})
|
||||||
return true;
|
res.json({ ok: true, results: uplResults })
|
||||||
|
return true
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
res.json({ ok: false, msg: err.message });
|
res.json({ ok: false, msg: err.message })
|
||||||
return true;
|
return true
|
||||||
});
|
})
|
||||||
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
router.get('/*', (req, res, next) => {
|
router.get('/*', (req, res, next) => {
|
||||||
|
let fileName = req.params[0]
|
||||||
let fileName = req.params[0];
|
if (!validPathRe.test(fileName)) {
|
||||||
if(!validPathRe.test(fileName)) {
|
return res.sendStatus(404).end()
|
||||||
return res.sendStatus(404).end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo: Authentication-based access
|
// todo: Authentication-based access
|
||||||
|
|
||||||
res.sendFile(fileName, {
|
res.sendFile(fileName, {
|
||||||
root: git.getRepoPath() + '/uploads/',
|
root: git.getRepoPath() + '/uploads/',
|
||||||
dotfiles: 'deny'
|
dotfiles: 'deny'
|
||||||
}, (err) => {
|
}, (err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
res.status(err.status).end();
|
res.status(err.status).end()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
})
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router
|
||||||
|
@ -1,95 +1,95 @@
|
|||||||
"use strict";
|
'use strict'
|
||||||
|
|
||||||
module.exports = (socket) => {
|
const _ = require('lodash')
|
||||||
|
|
||||||
if(!socket.request.user.logged_in) {
|
module.exports = (socket) => {
|
||||||
return;
|
if (!socket.request.user.logged_in) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------
|
// -----------------------------------------
|
||||||
// SEARCH
|
// SEARCH
|
||||||
//-----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
socket.on('search', (data, cb) => {
|
socket.on('search', (data, cb) => {
|
||||||
cb = cb || _.noop;
|
cb = cb || _.noop
|
||||||
entries.search(data.terms).then((results) => {
|
entries.search(data.terms).then((results) => {
|
||||||
return cb(results) || true;
|
return cb(results) || true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
//-----------------------------------------
|
// -----------------------------------------
|
||||||
// UPLOADS
|
// UPLOADS
|
||||||
//-----------------------------------------
|
// -----------------------------------------
|
||||||
|
|
||||||
socket.on('uploadsGetFolders', (data, cb) => {
|
socket.on('uploadsGetFolders', (data, cb) => {
|
||||||
cb = cb || _.noop;
|
cb = cb || _.noop
|
||||||
upl.getUploadsFolders().then((f) => {
|
upl.getUploadsFolders().then((f) => {
|
||||||
return cb(f) || true;
|
return cb(f) || true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
socket.on('uploadsCreateFolder', (data, cb) => {
|
socket.on('uploadsCreateFolder', (data, cb) => {
|
||||||
cb = cb || _.noop;
|
cb = cb || _.noop
|
||||||
upl.createUploadsFolder(data.foldername).then((f) => {
|
upl.createUploadsFolder(data.foldername).then((f) => {
|
||||||
return cb(f) || true;
|
return cb(f) || true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
socket.on('uploadsGetImages', (data, cb) => {
|
socket.on('uploadsGetImages', (data, cb) => {
|
||||||
cb = cb || _.noop;
|
cb = cb || _.noop
|
||||||
upl.getUploadsFiles('image', data.folder).then((f) => {
|
upl.getUploadsFiles('image', data.folder).then((f) => {
|
||||||
return cb(f) || true;
|
return cb(f) || true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
socket.on('uploadsGetFiles', (data, cb) => {
|
socket.on('uploadsGetFiles', (data, cb) => {
|
||||||
cb = cb || _.noop;
|
cb = cb || _.noop
|
||||||
upl.getUploadsFiles('binary', data.folder).then((f) => {
|
upl.getUploadsFiles('binary', data.folder).then((f) => {
|
||||||
return cb(f) || true;
|
return cb(f) || true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
socket.on('uploadsDeleteFile', (data, cb) => {
|
socket.on('uploadsDeleteFile', (data, cb) => {
|
||||||
cb = cb || _.noop;
|
cb = cb || _.noop
|
||||||
upl.deleteUploadsFile(data.uid).then((f) => {
|
upl.deleteUploadsFile(data.uid).then((f) => {
|
||||||
return cb(f) || true;
|
return cb(f) || true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
socket.on('uploadsFetchFileFromURL', (data, cb) => {
|
socket.on('uploadsFetchFileFromURL', (data, cb) => {
|
||||||
cb = cb || _.noop;
|
cb = cb || _.noop
|
||||||
upl.downloadFromUrl(data.folder, data.fetchUrl).then((f) => {
|
upl.downloadFromUrl(data.folder, data.fetchUrl).then((f) => {
|
||||||
return cb({ ok: true }) || true;
|
return cb({ ok: true }) || true
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
return cb({
|
return cb({
|
||||||
ok: false,
|
ok: false,
|
||||||
msg: err.message
|
msg: err.message
|
||||||
}) || true;
|
}) || true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
socket.on('uploadsRenameFile', (data, cb) => {
|
socket.on('uploadsRenameFile', (data, cb) => {
|
||||||
cb = cb || _.noop;
|
cb = cb || _.noop
|
||||||
upl.moveUploadsFile(data.uid, data.folder, data.filename).then((f) => {
|
upl.moveUploadsFile(data.uid, data.folder, data.filename).then((f) => {
|
||||||
return cb({ ok: true }) || true;
|
return cb({ ok: true }) || true
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
return cb({
|
return cb({
|
||||||
ok: false,
|
ok: false,
|
||||||
msg: err.message
|
msg: err.message
|
||||||
}) || true;
|
}) || true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
socket.on('uploadsMoveFile', (data, cb) => {
|
socket.on('uploadsMoveFile', (data, cb) => {
|
||||||
cb = cb || _.noop;
|
cb = cb || _.noop
|
||||||
upl.moveUploadsFile(data.uid, data.folder).then((f) => {
|
upl.moveUploadsFile(data.uid, data.folder).then((f) => {
|
||||||
return cb({ ok: true }) || true;
|
return cb({ ok: true }) || true
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
return cb({
|
return cb({
|
||||||
ok: false,
|
ok: false,
|
||||||
msg: err.message
|
msg: err.message
|
||||||
}) || true;
|
}) || true
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
}
|
||||||
};
|
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
// TODO
|
@ -1,11 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
let path = require('path'),
|
|
||||||
fs = require('fs');
|
|
||||||
|
|
||||||
// ========================================
|
|
||||||
// Load global modules
|
|
||||||
// ========================================
|
|
||||||
|
|
||||||
global._ = require('lodash');
|
|
||||||
global.winston = require('winston');
|
|
Loading…
Reference in new issue