123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- /* global WIKI */
- const express = require('express')
- const ExpressBrute = require('express-brute')
- const BruteKnex = require('../helpers/brute-knex')
- const router = express.Router()
- const moment = require('moment')
- const _ = require('lodash')
- 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
- failCallback: (req, res, next) => {
- res.status(401).send('Too many failed attempts. Try again later.')
- }
- })
- /**
- * Login form
- */
- router.get('/login', async (req, res, next) => {
- _.set(res.locals, 'pageMeta.title', 'Login')
- if (req.query.legacy || (req.get('user-agent') && req.get('user-agent').indexOf('Trident') >= 0)) {
- const { formStrategies, socialStrategies } = await WIKI.models.authentication.getStrategiesForLegacyClient()
- res.render('legacy/login', {
- err: false,
- 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 })
- }
- })
- /**
- * Social Strategies Login
- */
- router.get('/login/:strategy', async (req, res, next) => {
- try {
- await WIKI.models.users.login({
- strategy: req.params.strategy
- }, { req, res })
- } catch (err) {
- next(err)
- }
- })
- /**
- * Social Strategies Callback
- */
- router.all('/login/:strategy/callback', async (req, res, next) => {
- if (req.method !== 'GET' && req.method !== 'POST') { return next() }
- 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() })
- const loginRedirect = req.cookies['loginRedirect']
- if (loginRedirect === '/' && authResult.redirect) {
- res.clearCookie('loginRedirect')
- res.redirect(authResult.redirect)
- } else if (loginRedirect) {
- res.clearCookie('loginRedirect')
- res.redirect(loginRedirect)
- } else if (authResult.redirect) {
- res.redirect(authResult.redirect)
- } else {
- res.redirect('/')
- }
- } catch (err) {
- next(err)
- }
- })
- /**
- * 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
- })
- }
- } else {
- res.redirect('/login')
- }
- })
- /**
- * Logout
- */
- router.get('/logout', async (req, res) => {
- const redirURL = await WIKI.models.users.logout({ req, res })
- req.logout()
- res.clearCookie('jwt')
- res.redirect(redirURL)
- })
- /**
- * Register form
- */
- router.get('/register', async (req, res, next) => {
- _.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())
- }
- })
- /**
- * Verify
- */
- 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)
- }
- })
- /**
- * Reset Password
- */
- router.get('/login-reset/:token', bruteforce.prevent, async (req, res, next) => {
- try {
- const usr = await WIKI.models.userKeys.validateToken({ kind: 'resetPwd', token: req.params.token })
- if (!usr) {
- throw new Error('Invalid Token')
- }
- req.brute.reset()
- const changePwdContinuationToken = await WIKI.models.userKeys.generateToken({
- userId: usr.id,
- kind: 'changePwd'
- })
- 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, changePwdContinuationToken })
- } catch (err) {
- next(err)
- }
- })
- /**
- * 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)
- })
- module.exports = router
|