Integration to Requarks Core
This commit is contained in:
155
libs/auth.js
155
libs/auth.js
@@ -1,155 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const LocalStrategy = require('passport-local').Strategy;
|
||||
const GoogleStrategy = require('passport-google-oauth20').Strategy;
|
||||
const WindowsLiveStrategy = require('passport-windowslive').Strategy;
|
||||
const FacebookStrategy = require('passport-facebook').Strategy;
|
||||
const _ = require('lodash');
|
||||
|
||||
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) => {
|
||||
if(user) {
|
||||
done(null, user);
|
||||
} else {
|
||||
done(new Error('User not found.'), null);
|
||||
}
|
||||
return true;
|
||||
}).catch((err) => {
|
||||
done(err, null);
|
||||
});
|
||||
});
|
||||
|
||||
// Local Account
|
||||
|
||||
if(appconfig.auth.local && appconfig.auth.local.enabled) {
|
||||
|
||||
passport.use('local',
|
||||
new LocalStrategy({
|
||||
usernameField : 'email',
|
||||
passwordField : 'password'
|
||||
},
|
||||
(uEmail, uPassword, done) => {
|
||||
db.User.findOne({ email: uEmail, provider: 'local' }).then((user) => {
|
||||
if(user) {
|
||||
return user.validatePassword(uPassword).then(() => {
|
||||
return done(null, user) || true;
|
||||
}).catch((err) => {
|
||||
return done(err, null);
|
||||
});
|
||||
} else {
|
||||
return done(new Error('Invalid Login'), null);
|
||||
}
|
||||
}).catch((err) => {
|
||||
done(err, null) ;
|
||||
});
|
||||
}
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
// Google ID
|
||||
|
||||
if(appconfig.auth.google && appconfig.auth.google.enabled) {
|
||||
|
||||
passport.use('google',
|
||||
new GoogleStrategy({
|
||||
clientID: appconfig.auth.google.clientId,
|
||||
clientSecret: appconfig.auth.google.clientSecret,
|
||||
callbackURL: appconfig.host + '/login/google/callback'
|
||||
},
|
||||
(accessToken, refreshToken, profile, cb) => {
|
||||
db.User.processProfile(profile).then((user) => {
|
||||
return cb(null, user) || true;
|
||||
}).catch((err) => {
|
||||
return cb(err, null) || true;
|
||||
});
|
||||
}
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
// Microsoft Accounts
|
||||
|
||||
if(appconfig.auth.microsoft && appconfig.auth.microsoft.enabled) {
|
||||
|
||||
passport.use('windowslive',
|
||||
new WindowsLiveStrategy({
|
||||
clientID: appconfig.auth.microsoft.clientId,
|
||||
clientSecret: appconfig.auth.microsoft.clientSecret,
|
||||
callbackURL: appconfig.host + '/login/ms/callback'
|
||||
},
|
||||
function(accessToken, refreshToken, profile, cb) {
|
||||
db.User.processProfile(profile).then((user) => {
|
||||
return cb(null, user) || true;
|
||||
}).catch((err) => {
|
||||
return cb(err, null) || true;
|
||||
});
|
||||
}
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
// Facebook
|
||||
|
||||
if(appconfig.auth.facebook && appconfig.auth.facebook.enabled) {
|
||||
|
||||
passport.use('facebook',
|
||||
new FacebookStrategy({
|
||||
clientID: appconfig.auth.facebook.clientId,
|
||||
clientSecret: appconfig.auth.facebook.clientSecret,
|
||||
callbackURL: appconfig.host + '/login/facebook/callback',
|
||||
profileFields: ['id', 'displayName', 'email']
|
||||
},
|
||||
function(accessToken, refreshToken, profile, cb) {
|
||||
db.User.processProfile(profile).then((user) => {
|
||||
return cb(null, user) || true;
|
||||
}).catch((err) => {
|
||||
return cb(err, null) || true;
|
||||
});
|
||||
}
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
// Check for admin access
|
||||
|
||||
db.onReady.then(() => {
|
||||
|
||||
db.User.count().then((c) => {
|
||||
if(c < 1) {
|
||||
winston.info('[' + PROCNAME + '][AUTH] No administrator account found. Creating a new one...');
|
||||
db.User.hashPassword('admin123').then((pwd) => {
|
||||
return db.User.create({
|
||||
provider: 'local',
|
||||
email: appconfig.admin,
|
||||
name: "Administrator",
|
||||
password: pwd,
|
||||
rights: [{
|
||||
role: 'admin',
|
||||
path: '/',
|
||||
exact: false,
|
||||
deny: false
|
||||
}]
|
||||
});
|
||||
}).then(() => {
|
||||
winston.info('[' + PROCNAME + '][AUTH] Administrator account created successfully!');
|
||||
}).catch((err) => {
|
||||
winston.error('[' + PROCNAME + '][AUTH] An error occured while creating administrator account:');
|
||||
winston.error(err);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
|
||||
});
|
||||
|
||||
};
|
@@ -1,56 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var fs = require('fs'),
|
||||
yaml = require('js-yaml'),
|
||||
_ = require('lodash');
|
||||
|
||||
/**
|
||||
* Load Application Configuration
|
||||
*
|
||||
* @param {String} confPath Path to the configuration file
|
||||
* @return {Object} Application Configuration
|
||||
*/
|
||||
module.exports = (confPath) => {
|
||||
|
||||
var appconfig = {};
|
||||
|
||||
try {
|
||||
appconfig = yaml.safeLoad(fs.readFileSync(confPath, 'utf8'));
|
||||
} catch (ex) {
|
||||
winston.error(ex);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Merge with defaults
|
||||
|
||||
appconfig = _.defaultsDeep(appconfig, {
|
||||
title: "Requarks Wiki",
|
||||
host: "http://localhost",
|
||||
port: process.env.PORT,
|
||||
auth: {
|
||||
local: { enabled: true },
|
||||
microsoft: { enabled: false },
|
||||
google: { enabled: false },
|
||||
facebook: { enabled: false },
|
||||
},
|
||||
db: "mongodb://localhost/wiki",
|
||||
redis: null,
|
||||
sessionSecret: null,
|
||||
admin: null
|
||||
});
|
||||
|
||||
// List authentication strategies
|
||||
|
||||
appconfig.authStrategies = {
|
||||
list: _.filter(appconfig.auth, ['enabled', true]),
|
||||
socialEnabled: (_.chain(appconfig.auth).omit('local').reject({ enabled: false }).value().length > 0)
|
||||
}
|
||||
if(appconfig.authStrategies.list.length < 1) {
|
||||
winston.error(new Error('You must enable at least 1 authentication strategy!'));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
|
||||
return appconfig;
|
||||
|
||||
};
|
@@ -151,7 +151,18 @@ const parseContent = (content) => {
|
||||
|
||||
let output = mkdown.render(content);
|
||||
let cr = cheerio.load(output);
|
||||
cr('table').addClass('table is-bordered is-striped is-narrow');
|
||||
|
||||
//-> Style table headers
|
||||
|
||||
//cr('table').addClass('table is-bordered is-striped is-narrow');
|
||||
|
||||
//-> Remove links in headers
|
||||
|
||||
cr('h1 > a:not(.toc-anchor), h2 > a:not(.toc-anchor), h3 > a:not(.toc-anchor)').each((i, elm) => {
|
||||
let txtLink = cr(elm).text();
|
||||
cr(elm).replaceWith(txtLink);
|
||||
});
|
||||
|
||||
output = cr.html();
|
||||
|
||||
return output;
|
||||
|
@@ -1,64 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const modb = require('mongoose'),
|
||||
fs = require("fs"),
|
||||
path = require("path"),
|
||||
_ = require('lodash');
|
||||
|
||||
/**
|
||||
* MongoDB module
|
||||
*
|
||||
* @param {Object} appconfig Application config
|
||||
* @return {Object} MongoDB wrapper instance
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
/**
|
||||
* Initialize DB
|
||||
*
|
||||
* @param {Object} appconfig The application config
|
||||
* @return {Object} DB instance
|
||||
*/
|
||||
init(appconfig) {
|
||||
|
||||
let self = this;
|
||||
|
||||
let dbModelsPath = path.resolve(ROOTPATH, 'models');
|
||||
|
||||
modb.Promise = require('bluebird');
|
||||
|
||||
// Event handlers
|
||||
|
||||
modb.connection.on('error', (err) => {
|
||||
winston.error('[' + PROCNAME + '] Failed to connect to MongoDB instance.');
|
||||
});
|
||||
modb.connection.once('open', function() {
|
||||
winston.log('[' + PROCNAME + '] Connected to MongoDB instance.');
|
||||
});
|
||||
|
||||
// Store connection handle
|
||||
|
||||
self.connection = modb.connection;
|
||||
self.ObjectId = modb.Types.ObjectId;
|
||||
|
||||
// Load DB Models
|
||||
|
||||
fs
|
||||
.readdirSync(dbModelsPath)
|
||||
.filter(function(file) {
|
||||
return (file.indexOf(".") !== 0);
|
||||
})
|
||||
.forEach(function(file) {
|
||||
let modelName = _.upperFirst(_.camelCase(_.split(file,'.')[0]));
|
||||
self[modelName] = require(path.join(dbModelsPath, file));
|
||||
});
|
||||
|
||||
// Connect
|
||||
|
||||
self.onReady = modb.connect(appconfig.db);
|
||||
|
||||
return self;
|
||||
|
||||
}
|
||||
|
||||
};
|
@@ -1,57 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
const _ = require('lodash');
|
||||
|
||||
/**
|
||||
* Rights
|
||||
*/
|
||||
module.exports = {
|
||||
|
||||
|
||||
check(req, role) {
|
||||
|
||||
let rt = [];
|
||||
let p = _.chain(req.originalUrl).toLower().trim().value();
|
||||
|
||||
// Load User Rights
|
||||
|
||||
if(_.isArray(req.user.rights)) {
|
||||
rt = req.user.rights;
|
||||
}
|
||||
|
||||
// Is admin?
|
||||
|
||||
if(_.find(rt, { role: 'admin' })) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check specific role on path
|
||||
|
||||
let filteredRights = _.filter(rt, (r) => {
|
||||
if(r.role === role || (r.role === 'write' && role === 'read')) {
|
||||
if((!r.exact && _.startsWith(p, r.path)) || (r.exact && p === r.path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
// Check for deny scenario
|
||||
|
||||
let isValid = false;
|
||||
|
||||
if(filteredRights.length > 1) {
|
||||
isValid = !_.chain(filteredRights).sortBy((r) => {
|
||||
return r.path.length + ((r.deny) ? 0.5 : 0);
|
||||
}).last().get('deny').value();
|
||||
} else if(filteredRights.length == 1 && filteredRights[0].deny === false) {
|
||||
isValid = true;
|
||||
}
|
||||
|
||||
// Deny by default
|
||||
|
||||
return isValid;
|
||||
|
||||
}
|
||||
|
||||
};
|
@@ -1,18 +0,0 @@
|
||||
"use strict";
|
||||
|
||||
var winston = require('winston');
|
||||
|
||||
module.exports = (isDebug) => {
|
||||
|
||||
winston.remove(winston.transports.Console);
|
||||
winston.add(winston.transports.Console, {
|
||||
level: (isDebug) ? 'debug' : 'info',
|
||||
prettyPrint: true,
|
||||
colorize: true,
|
||||
silent: false,
|
||||
timestamp: true
|
||||
});
|
||||
|
||||
return winston;
|
||||
|
||||
};
|
Reference in New Issue
Block a user