mirror of https://github.com/Requarks/wiki.git
10 changed files with 404 additions and 3 deletions
Split View
Diff Options
-
13controllers/admin.js
-
73controllers/auth.js
-
13controllers/pages.js
-
17middlewares/flash.js
-
65models/auth.js
-
3package.json
-
173server.js
-
1views/auth/login.pug
-
21views/error.pug
-
28views/layout.pug
@ -0,0 +1,13 @@ |
|||
"use strict"; |
|||
|
|||
var express = require('express'); |
|||
var router = express.Router(); |
|||
|
|||
/** |
|||
* Admin |
|||
*/ |
|||
router.get('/', (req, res) => { |
|||
res.send('OK'); |
|||
}); |
|||
|
|||
module.exports = router; |
@ -0,0 +1,73 @@ |
|||
var express = require('express'); |
|||
var router = express.Router(); |
|||
var passport = require('passport'); |
|||
var ExpressBrute = require('express-brute'); |
|||
var ExpressBruteRedisStore = require('express-brute-redis'); |
|||
var moment = require('moment'); |
|||
|
|||
/** |
|||
* Setup Express-Brute |
|||
*/ |
|||
var EBstore = new ExpressBruteRedisStore({ |
|||
prefix: 'bf:', |
|||
client: red |
|||
}); |
|||
var bruteforce = new ExpressBrute(EBstore, { |
|||
freeRetries: 5, |
|||
minWait: 60 * 1000, |
|||
maxWait: 5 * 60 * 1000, |
|||
refreshTimeoutOnRequest: false, |
|||
failCallback(req, res, next, nextValidRequestDate) { |
|||
req.flash('alert', { |
|||
class: 'error', |
|||
title: 'Too many attempts!', |
|||
message: "You've made too many failed attempts in a short period of time, please try again " + moment(nextValidRequestDate).fromNow() + '.', |
|||
iconClass: 'fa-times' |
|||
}); |
|||
res.redirect('/login'); |
|||
} |
|||
}); |
|||
|
|||
/** |
|||
* Login form |
|||
*/ |
|||
router.get('/login', function(req, res, next) { |
|||
res.render('auth/login', { |
|||
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); } |
|||
|
|||
if (!user) { |
|||
req.flash('alert', { |
|||
class: 'error', |
|||
title: 'Invalid login', |
|||
message: "The email or password is invalid.", |
|||
iconClass: 'fa-times' |
|||
}); |
|||
return res.redirect('/login'); |
|||
} |
|||
|
|||
req.logIn(user, function(err) { |
|||
if (err) { return next(err); } |
|||
req.brute.reset(function () { |
|||
return res.redirect('/'); |
|||
}); |
|||
}); |
|||
|
|||
})(req, res, next); |
|||
}); |
|||
|
|||
/** |
|||
* Logout |
|||
*/ |
|||
router.get('/logout', function(req, res) { |
|||
req.logout(); |
|||
res.redirect('/'); |
|||
}); |
|||
|
|||
module.exports = router; |
@ -0,0 +1,13 @@ |
|||
"use strict"; |
|||
|
|||
var express = require('express'); |
|||
var router = express.Router(); |
|||
|
|||
/** |
|||
* Home |
|||
*/ |
|||
router.get('/', (req, res) => { |
|||
res.send('OK'); |
|||
}); |
|||
|
|||
module.exports = router; |
@ -0,0 +1,17 @@ |
|||
"use strict"; |
|||
|
|||
/** |
|||
* Flash middleware |
|||
* |
|||
* @param {Express Request} req Express Request object |
|||
* @param {Express Response} res Express Response object |
|||
* @param {Function} next Next callback function |
|||
* @return {any} void |
|||
*/ |
|||
module.exports = (req, res, next) => { |
|||
|
|||
res.locals.appflash = req.flash('alert'); |
|||
|
|||
next(); |
|||
|
|||
}; |
@ -0,0 +1,65 @@ |
|||
var LocalStrategy = require('passport-local').Strategy; |
|||
|
|||
module.exports = function(passport, appconfig) { |
|||
|
|||
// Serialization user methods
|
|||
|
|||
passport.serializeUser(function(user, done) { |
|||
done(null, user._id); |
|||
}); |
|||
|
|||
passport.deserializeUser(function(id, done) { |
|||
db.User.findById(id).then((user) => { |
|||
done(null, user); |
|||
}).catch((err) => { |
|||
done(err, null); |
|||
}); |
|||
}); |
|||
|
|||
// Setup local user authentication strategy
|
|||
|
|||
passport.use( |
|||
'local', |
|||
new LocalStrategy({ |
|||
usernameField : 'email', |
|||
passwordField : 'password', |
|||
passReqToCallback : true |
|||
}, |
|||
function(req, uEmail, uPassword, done) { |
|||
db.User.findOne({ 'email' : uEmail }).then((user) => { |
|||
if (user) { |
|||
user.validatePassword(uPassword).then((isValid) => { |
|||
return (isValid) ? done(null, user) : done(null, false); |
|||
}); |
|||
} else { |
|||
return done(null, false); |
|||
} |
|||
}).catch((err) => { |
|||
done(err); |
|||
}); |
|||
}) |
|||
); |
|||
|
|||
// Check for admin access
|
|||
|
|||
db.connectPromise.then(() => { |
|||
|
|||
db.User.count().then((count) => { |
|||
if(count < 1) { |
|||
winston.info('No administrator account found. Creating a new one...'); |
|||
db.User.new({ |
|||
email: appconfig.admin, |
|||
firstName: "Admin", |
|||
lastName: "Admin", |
|||
password: "admin123" |
|||
}).then(() => { |
|||
winston.info('Administrator account created successfully!'); |
|||
}).catch((ex) => { |
|||
winston.error('An error occured while creating administrator account: ' + ex); |
|||
}); |
|||
} |
|||
}); |
|||
|
|||
}); |
|||
|
|||
}; |
@ -0,0 +1 @@ |
|||
DUDE |
@ -0,0 +1,21 @@ |
|||
doctype html |
|||
html |
|||
head |
|||
meta(http-equiv='X-UA-Compatible', content='IE=edge') |
|||
meta(charset='UTF-8') |
|||
title= appconfig.title |
|||
|
|||
// Favicon |
|||
each favsize in [32, 96, 16] |
|||
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize href='/images/favicon-' + favsize + 'x' + favsize + '.png') |
|||
|
|||
// CSS |
|||
link(href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,600,700|Inconsolata', rel='stylesheet', type='text/css') |
|||
link(type='text/css', rel='stylesheet', href='/css/app.css') |
|||
|
|||
body(class='server-error') |
|||
#root |
|||
img(src='/images/logo-text_218x80.png') |
|||
h1 Oops, something went wrong |
|||
h4= message |
|||
pre #{error.stack} |
@ -0,0 +1,28 @@ |
|||
doctype html |
|||
html |
|||
head |
|||
meta(http-equiv='X-UA-Compatible', content='IE=edge') |
|||
meta(charset='UTF-8') |
|||
meta(name='theme-color', content='#009688') |
|||
meta(name='msapplication-TileColor', content='#009688') |
|||
title= appconfig.title |
|||
|
|||
// Favicon |
|||
each favsize in [32, 96, 16] |
|||
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize href='/images/favicon-' + favsize + 'x' + favsize + '.png') |
|||
|
|||
// CSS |
|||
link(type='text/css', rel='stylesheet', href='/css/libs.css') |
|||
link(type='text/css', rel='stylesheet', href='/css/app.css') |
|||
|
|||
block head |
|||
|
|||
body |
|||
#root |
|||
include ./common/header |
|||
include ./common/alerts |
|||
main |
|||
block content |
|||
include ./common/footer |
|||
|
|||
block outside |
Write
Preview
Loading…
Cancel
Save