| 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
 |