feat: guest + user permissions
This commit is contained in:
@@ -3,6 +3,8 @@ const passportJWT = require('passport-jwt')
|
||||
const fs = require('fs-extra')
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const jwt = require('jsonwebtoken')
|
||||
const moment = require('moment')
|
||||
|
||||
const securityHelper = require('../helpers/security')
|
||||
|
||||
@@ -10,11 +12,16 @@ const securityHelper = require('../helpers/security')
|
||||
|
||||
module.exports = {
|
||||
strategies: {},
|
||||
guest: {
|
||||
cacheExpiration: moment.utc().subtract(1, 'd')
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the authentication module
|
||||
*/
|
||||
init() {
|
||||
this.passport = passport
|
||||
|
||||
// Serialization user methods
|
||||
|
||||
passport.serializeUser(function (user, done) {
|
||||
done(null, user.id)
|
||||
})
|
||||
@@ -34,6 +41,10 @@ module.exports = {
|
||||
|
||||
return this
|
||||
},
|
||||
|
||||
/**
|
||||
* Load authentication strategies
|
||||
*/
|
||||
async activateStrategies() {
|
||||
try {
|
||||
// Unload any active strategies
|
||||
@@ -46,7 +57,7 @@ module.exports = {
|
||||
passport.use('jwt', new passportJWT.Strategy({
|
||||
jwtFromRequest: securityHelper.extractJWT,
|
||||
secretOrKey: WIKI.config.certs.public,
|
||||
audience: 'urn:wiki.js', // TODO: use value from admin
|
||||
audience: WIKI.config.auth.audience,
|
||||
issuer: 'urn:wiki.js'
|
||||
}, (jwtPayload, cb) => {
|
||||
cb(null, jwtPayload)
|
||||
@@ -60,7 +71,7 @@ module.exports = {
|
||||
|
||||
const strategy = require(`../modules/authentication/${stg.key}/authentication.js`)
|
||||
|
||||
stg.config.callbackURL = `${WIKI.config.host}/login/${stg.key}/callback` // TODO: config.host
|
||||
stg.config.callbackURL = `${WIKI.config.host}/login/${stg.key}/callback`
|
||||
strategy.init(passport, stg.config)
|
||||
|
||||
fs.readFile(path.join(WIKI.ROOTPATH, `assets/svg/auth-icon-${strategy.key}.svg`), 'utf8').then(iconData => {
|
||||
@@ -79,5 +90,74 @@ module.exports = {
|
||||
WIKI.logger.error(`Authentication Strategy: [ FAILED ]`)
|
||||
WIKI.logger.error(err)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Authenticate current request
|
||||
*
|
||||
* @param {Express Request} req
|
||||
* @param {Express Response} res
|
||||
* @param {Express Next Callback} next
|
||||
*/
|
||||
authenticate(req, res, next) {
|
||||
WIKI.auth.passport.authenticate('jwt', {session: false}, async (err, user, info) => {
|
||||
if (err) { return next() }
|
||||
|
||||
// Expired but still valid within N days, just renew
|
||||
if (info instanceof Error && info.name === 'TokenExpiredError' && moment().subtract(14, 'days').isBefore(info.expiredAt)) {
|
||||
const jwtPayload = jwt.decode(securityHelper.extractJWT(req))
|
||||
try {
|
||||
const newToken = await WIKI.models.users.refreshToken(jwtPayload.id)
|
||||
user = newToken.user
|
||||
|
||||
// Try headers, otherwise cookies for response
|
||||
if (req.get('content-type') === 'application/json') {
|
||||
res.set('new-jwt', newToken.token)
|
||||
} else {
|
||||
res.cookie('jwt', newToken.token, { expires: moment().add(365, 'days').toDate() })
|
||||
}
|
||||
} catch (err) {
|
||||
return next()
|
||||
}
|
||||
}
|
||||
|
||||
// JWT is NOT valid, set as guest
|
||||
if (!user) {
|
||||
if (WIKI.auth.guest.cacheExpiration ) {
|
||||
WIKI.auth.guest = await WIKI.models.users.getGuestUser()
|
||||
WIKI.auth.guest.cacheExpiration = moment.utc().add(1, 'm')
|
||||
}
|
||||
req.user = WIKI.auth.guest
|
||||
return next()
|
||||
}
|
||||
|
||||
// JWT is valid
|
||||
req.logIn(user, { session: false }, (err) => {
|
||||
if (err) { return next(err) }
|
||||
next()
|
||||
})
|
||||
})(req, res, next)
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if user has access to resource
|
||||
*
|
||||
* @param {User} user
|
||||
* @param {Array<String>} permissions
|
||||
* @param {String|Boolean} path
|
||||
*/
|
||||
checkAccess(user, permissions = [], path = false) {
|
||||
// System Admin
|
||||
if (_.includes(user.permissions, 'manage:system')) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check Global Permissions
|
||||
if (_.intersection(user.permissions, permissions).length < 1) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check Page Rules
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@@ -52,8 +52,6 @@ module.exports = {
|
||||
appconfig.port = process.env.PORT || 80
|
||||
}
|
||||
|
||||
appconfig.public = (appconfig.public === true || _.toLower(appconfig.public) === 'true')
|
||||
|
||||
WIKI.config = appconfig
|
||||
WIKI.data = appdata
|
||||
WIKI.version = require(path.join(WIKI.ROOTPATH, 'package.json')).version
|
||||
|
Reference in New Issue
Block a user