Files
term_portal/express/controllers/users.js
T
2023-03-10 12:50:23 +01:00

163 lines
4.6 KiB
JavaScript

const { randomBytes } = require('crypto')
const { promisify } = require('util')
const passport = require('passport')
const User = require('../models/user')
const email = require('../models/email')
const { origin } = require('../config/keys')
const { rememberMeCookieSettings } = require('../config/settings')
const RandomBytesAsync = promisify(randomBytes)
const { DEFAULT_HITS_PER_PAGE } = require('../config/settings')
const user = {}
user.register = async (req, res) => {
// TODO Add validation.
const userId = await User.create({
...req.body,
language: req.session.language
})
const activationToken = (await RandomBytesAsync(32)).toString('hex')
await User.saveActivationToken(userId, activationToken)
const { email: userEmail, username } = req.body
let activationLink = new URL('/users/activate', origin)
activationLink.searchParams.set('token', activationToken)
activationLink = activationLink.href
const renderAsync = promisify(req.app.render.bind(req.app))
const emailHtml = await renderAsync(`email/user-activation_${req.language}`, {
username,
activationLink
})
await email.send({
to: userEmail,
subject: req.t('Aktivacija računa'),
html: emailHtml
})
res.send(req.t('Registracija uspešna'))
}
user.activateAccount = async (req, res) => {
// TODO Add validation. What if user is already logged in? What if account is already active? ...
const { token } = req.query
const user = await User.fetchByActivationToken(token)
await User.activateAccount(user)
const loginAsync = promisify(req.login.bind(req))
await loginAsync(user)
if (req.session.language) {
await User.updateLanguage(user.id, req.session.language)
delete req.session.language
}
res.redirect('/')
}
user.login = async (req, res, next) => {
passport.authenticate(
'local',
{
badRequestMessage: req.t(
'Nepravilno uporabniško ime, elektronski naslov ali geslo.'
)
},
async (err, user, info) => {
if (err) return next(err)
if (!user) {
const err = Error(info.message)
err.status = 403
err.displayInProd = true
return next(err)
}
const loginAsync = promisify(req.login.bind(req))
await loginAsync(user)
if (req.body.rememberMe) {
// TODO Consider what happens if the user already has a remember me token.
const rememberMeToken = await User.generateRememberMeToken()
await User.saveRememberMeToken(user, rememberMeToken)
res.cookie('remember_me', rememberMeToken, rememberMeCookieSettings)
}
if (req.session.language) {
await User.updateLanguage(user.id, req.session.language)
delete req.session.language
}
res.send(req.t('Prijava uspešna'))
}
)(req, res, next)
}
user.logout = async (req, res) => {
const rememberMeToken = req.signedCookies.remember_me
if (rememberMeToken) {
res.clearCookie('remember_me')
await User.clearRememberMeToken(rememberMeToken)
}
req.session.language = req.user.language
req.logout()
// Manually clear session.passport due to bug in current passport version.
delete req.session.passport.user
res.redirect('/')
}
user.list = async (req, res) => {
const resultsPerPage = req.user?.hitsPerPage || DEFAULT_HITS_PER_PAGE
const { pages_total: numberOfAllPages, results } = await User.fetchAll(
resultsPerPage,
1
)
res.render('pages/admin/user-list', {
title: req.t('Seznam uporabnikov'),
numberOfAllPages,
results
})
}
user.listAllWithPortalRoles = async (req, res) => {
const users = await User.fetchAllWithPortalRoles()
res.render('pages/admin/user-portals', {
title: req.t('Skrbniki portala'),
users
})
}
user.findByUsernameOrEmail = async (req, res) => {
const userNameEmail = req.query.userNameEmail
const searchedUser = await User.findByUsernameOrEmail(userNameEmail)
res.send(searchedUser)
}
user.updateRoles = async (req, res) => {
await User.updatePortalRoles(req.body.rolesPerUser)
res.redirect('back')
}
user.adminEdit = async (req, res) => {
const userId = req.params.userId
const [userData, userRoles] = await Promise.all([
User.fetchUser(userId),
User.fetchUserRoles(userId)
])
res.render('pages/admin/user-edit', {
title: req.t('Uporabnik'),
userData,
userRoles
})
}
// TODO Aljaž: Luka, please adjust update function for updating user's password and email
// TODO Handle username unique constraint failure.
user.adminUpdate = async (req, res) => {
const { userId } = req.params
await User.updateUser(userId, req.body)
res.redirect('back')
}
module.exports = user