wikijs-fork/server/controllers/auth.js

162 lines
4.3 KiB
JavaScript
Raw Normal View History

/* global WIKI */
2017-02-09 01:52:37 +00:00
const express = require('express')
2019-07-13 19:15:35 +00:00
const ExpressBrute = require('express-brute')
2020-04-22 03:16:13 +00:00
const BruteKnex = require('../helpers/brute-knex')
2017-02-09 01:52:37 +00:00
const router = express.Router()
2018-12-24 06:03:10 +00:00
const moment = require('moment')
2018-12-24 22:38:34 +00:00
const _ = require('lodash')
2019-07-13 19:15:35 +00:00
const bruteforce = new ExpressBrute(new BruteKnex({
createTable: true,
knex: WIKI.models.knex
}), {
freeRetries: 5,
minWait: 5 * 60 * 1000, // 5 minutes
maxWait: 60 * 60 * 1000, // 1 hour
2019-07-13 19:15:35 +00:00
failCallback: (req, res, next) => {
res.status(401).send('Too many failed attempts. Try again later.')
}
})
2016-08-17 03:56:08 +00:00
/**
* Login form
*/
2019-07-13 19:15:35 +00:00
router.get('/login', async (req, res, next) => {
2018-12-24 22:38:34 +00:00
_.set(res.locals, 'pageMeta.title', 'Login')
2019-07-13 19:15:35 +00:00
if (req.query.legacy || (req.get('user-agent') && req.get('user-agent').indexOf('Trident') >= 0)) {
const { formStrategies, socialStrategies } = await WIKI.models.authentication.getStrategiesForLegacyClient()
2019-07-13 19:15:35 +00:00
res.render('legacy/login', {
err: false,
2019-07-13 19:15:35 +00:00
formStrategies,
socialStrategies
})
} else {
// -> Bypass Login
if (WIKI.config.auth.autoLogin && !req.query.all) {
const stg = await WIKI.models.authentication.query().orderBy('order').first()
const stgInfo = _.find(WIKI.data.authentication, ['key', stg.strategyKey])
if (!stgInfo.useForm) {
return res.redirect(`/login/${stg.key}`)
}
}
// -> Show Login
const bgUrl = !_.isEmpty(WIKI.config.auth.loginBgUrl) ? WIKI.config.auth.loginBgUrl : '/_assets/img/splash/1.jpg'
res.render('login', { bgUrl, hideLocal: WIKI.config.auth.hideLocal })
2019-07-13 19:15:35 +00:00
}
2017-02-09 01:52:37 +00:00
})
2019-07-13 19:15:35 +00:00
/**
* Social Strategies Login
*/
2019-04-21 06:04:00 +00:00
router.get('/login/:strategy', async (req, res, next) => {
try {
2019-04-28 01:42:04 +00:00
await WIKI.models.users.login({
2019-04-21 06:04:00 +00:00
strategy: req.params.strategy
}, { req, res })
} catch (err) {
next(err)
}
})
2019-07-13 19:15:35 +00:00
/**
* Social Strategies Callback
*/
2019-04-28 01:42:04 +00:00
router.all('/login/:strategy/callback', async (req, res, next) => {
if (req.method !== 'GET' && req.method !== 'POST') { return next() }
2019-04-21 06:04:00 +00:00
try {
const authResult = await WIKI.models.users.login({
strategy: req.params.strategy
}, { req, res })
res.cookie('jwt', authResult.jwt, { expires: moment().add(1, 'y').toDate() })
res.redirect('/')
2019-04-21 06:04:00 +00:00
} catch (err) {
next(err)
}
})
2016-08-17 03:56:08 +00:00
2019-07-13 19:15:35 +00:00
/**
* LEGACY - Login form handling
*/
router.post('/login', bruteforce.prevent, async (req, res, next) => {
_.set(res.locals, 'pageMeta.title', 'Login')
if (req.query.legacy || req.get('user-agent').indexOf('Trident') >= 0) {
try {
const authResult = await WIKI.models.users.login({
strategy: req.body.strategy,
username: req.body.user,
password: req.body.pass
}, { req, res })
req.brute.reset()
res.cookie('jwt', authResult.jwt, { expires: moment().add(1, 'y').toDate() })
res.redirect('/')
} catch (err) {
const { formStrategies, socialStrategies } = await WIKI.models.authentication.getStrategiesForLegacyClient()
res.render('legacy/login', {
err,
formStrategies,
socialStrategies
})
2019-07-13 19:15:35 +00:00
}
} else {
res.redirect('/login')
}
})
2016-08-17 03:56:08 +00:00
/**
* Logout
*/
2017-02-09 01:52:37 +00:00
router.get('/logout', function (req, res) {
req.logout()
res.clearCookie('jwt')
2017-02-09 01:52:37 +00:00
res.redirect('/')
})
2016-08-17 03:56:08 +00:00
/**
* Register form
*/
router.get('/register', async (req, res, next) => {
2018-12-24 22:38:34 +00:00
_.set(res.locals, 'pageMeta.title', 'Register')
const localStrg = await WIKI.models.authentication.getStrategy('local')
if (localStrg.selfRegistration) {
res.render('register')
} else {
next(new WIKI.Error.AuthRegistrationDisabled())
}
})
2018-12-24 06:03:10 +00:00
/**
* Verify
*/
2019-07-13 19:15:35 +00:00
router.get('/verify/:token', bruteforce.prevent, async (req, res, next) => {
try {
const usr = await WIKI.models.userKeys.validateToken({ kind: 'verify', token: req.params.token })
await WIKI.models.users.query().patch({ isVerified: true }).where('id', usr.id)
req.brute.reset()
if (WIKI.config.auth.enforce2FA) {
res.redirect('/login')
} else {
const result = await WIKI.models.users.refreshToken(usr)
res.cookie('jwt', result.token, { expires: moment().add(1, 'years').toDate() })
res.redirect('/')
}
} catch (err) {
next(err)
}
2018-12-24 06:03:10 +00:00
})
2018-12-03 02:42:43 +00:00
/**
* JWT Public Endpoints
*/
router.get('/.well-known/jwk.json', function (req, res, next) {
res.json(WIKI.config.certs.jwk)
})
router.get('/.well-known/jwk.pem', function (req, res, next) {
res.send(WIKI.config.certs.public)
})
2017-02-09 01:52:37 +00:00
module.exports = router