Fix most glaring bugs and vulnerabilities
This commit is contained in:
@@ -3,6 +3,7 @@ const { promisify } = require('util')
|
||||
const passport = require('passport')
|
||||
const User = require('../models/user')
|
||||
const email = require('../models/email')
|
||||
const { logout: logoutUser } = require('../middleware/user')
|
||||
const { origin } = require('../config/keys')
|
||||
const { rememberMeCookieSettings } = require('../config/settings')
|
||||
const RandomBytesAsync = promisify(randomBytes)
|
||||
@@ -12,10 +13,14 @@ const user = {}
|
||||
|
||||
user.register = async (req, res) => {
|
||||
// TODO Add validation.
|
||||
const userId = await User.create({
|
||||
...req.body,
|
||||
language: req.session.language
|
||||
})
|
||||
|
||||
const userId = await User.create(
|
||||
{
|
||||
...req.body,
|
||||
language: req.session.language
|
||||
},
|
||||
req.t
|
||||
)
|
||||
const activationToken = (await RandomBytesAsync(32)).toString('hex')
|
||||
await User.saveActivationToken(userId, activationToken)
|
||||
const { email: userEmail, username } = req.body
|
||||
@@ -38,8 +43,9 @@ user.register = async (req, res) => {
|
||||
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)
|
||||
if (!token) return res.redirect(303, '/')
|
||||
|
||||
const user = await User.activateAccountWithToken(token, req.t)
|
||||
const loginAsync = promisify(req.login.bind(req))
|
||||
await loginAsync(user)
|
||||
|
||||
@@ -48,7 +54,11 @@ user.activateAccount = async (req, res) => {
|
||||
delete req.session.language
|
||||
}
|
||||
|
||||
res.redirect('/')
|
||||
req.flash(
|
||||
'info',
|
||||
req.t('Uspešno ste aktivirali svoj uporabniški račun in se prijavili.')
|
||||
)
|
||||
res.redirect(303, '/')
|
||||
}
|
||||
|
||||
user.login = async (req, res, next) => {
|
||||
@@ -89,20 +99,86 @@ user.login = async (req, res, next) => {
|
||||
)(req, res, next)
|
||||
}
|
||||
|
||||
user.logout = async (req, res) => {
|
||||
const rememberMeToken = req.signedCookies.remember_me
|
||||
user.logout = [logoutUser, (req, res) => res.redirect(303, '/')]
|
||||
|
||||
if (rememberMeToken) {
|
||||
res.clearCookie('remember_me')
|
||||
await User.clearRememberMeToken(rememberMeToken)
|
||||
user.generateResetPasswordToken = async (req, res) => {
|
||||
const { usernameOrEmail } = req.body
|
||||
const user = await User.fetchByUsernameOrEmail(usernameOrEmail)
|
||||
|
||||
if (!user) {
|
||||
return res
|
||||
.status(400)
|
||||
.send(req.t('Nepravilno uporabniško ime ali elektronski naslov.'))
|
||||
}
|
||||
|
||||
req.session.language = req.user.language
|
||||
if (user.status !== 'active') {
|
||||
return res
|
||||
.status(400)
|
||||
.send(
|
||||
req.t(
|
||||
'Uporabniški račun še ni aktiviran. Kliknite aktivacijsko povezavo, katero smo vam poslali po elektronski pošti.'
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
req.logout()
|
||||
// Manually clear session.passport due to bug in current passport version.
|
||||
delete req.session.passport.user
|
||||
res.redirect('/')
|
||||
const resetPasswordToken = (await RandomBytesAsync(32)).toString('hex')
|
||||
await User.saveResetPasswordToken(user.id, resetPasswordToken)
|
||||
const { email: userEmail, username } = user
|
||||
let resetPasswordLink = new URL('/ponastavitev-gesla', origin)
|
||||
resetPasswordLink.searchParams.set('token', resetPasswordToken)
|
||||
resetPasswordLink = resetPasswordLink.href
|
||||
const renderAsync = promisify(req.app.render.bind(req.app))
|
||||
// TODO i18n - prepare proper slovenian an english email templates
|
||||
const emailHtml = await renderAsync(
|
||||
`email/user-reset-password-token_${req.language}`,
|
||||
{
|
||||
username,
|
||||
resetPasswordLink
|
||||
}
|
||||
)
|
||||
await email.send({
|
||||
to: userEmail,
|
||||
subject: req.t('Ponastavitev gesla'),
|
||||
html: emailHtml
|
||||
})
|
||||
res.send()
|
||||
}
|
||||
|
||||
user.changePassword = async (req, res) => {
|
||||
const { token, password, passwordRepeat } = req.body
|
||||
|
||||
if (password !== passwordRepeat) {
|
||||
return res.status(400).send(req.t('Gesli se ne ujemata'))
|
||||
}
|
||||
// TODO Add additional password validation (min length, ...)
|
||||
|
||||
const user = await User.resetPasswordWithToken(token, password, req.t)
|
||||
|
||||
const renderAsync = promisify(req.app.render.bind(req.app))
|
||||
// TODO i18n - prepare proper slovenian an english email templates
|
||||
const emailHtml = await renderAsync(
|
||||
`email/user-reset-password-success_${req.language}`,
|
||||
{
|
||||
username: user.username
|
||||
}
|
||||
)
|
||||
await email.send({
|
||||
to: user.email,
|
||||
subject: req.t('Uspešna ponastavitev gesla'),
|
||||
html: emailHtml
|
||||
})
|
||||
|
||||
req.flash('info', req.t('Vaše geslo je bilo uspešno ponastavljeno.'))
|
||||
|
||||
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.send()
|
||||
}
|
||||
|
||||
user.list = async (req, res) => {
|
||||
@@ -135,7 +211,7 @@ user.findByUsernameOrEmail = async (req, res) => {
|
||||
|
||||
user.updateRoles = async (req, res) => {
|
||||
await User.updatePortalRoles(req.body.rolesPerUser)
|
||||
res.redirect('back')
|
||||
res.redirect(303, 'back')
|
||||
}
|
||||
|
||||
user.adminEdit = async (req, res) => {
|
||||
@@ -144,6 +220,9 @@ user.adminEdit = async (req, res) => {
|
||||
User.fetchUser(userId),
|
||||
User.fetchUserRoles(userId)
|
||||
])
|
||||
|
||||
if (userData.status === 'closed') return res.redirect(303, '/')
|
||||
|
||||
res.render('pages/admin/user-edit', {
|
||||
title: req.t('Uporabnik'),
|
||||
userData,
|
||||
@@ -156,7 +235,7 @@ user.adminEdit = async (req, res) => {
|
||||
user.adminUpdate = async (req, res) => {
|
||||
const { userId } = req.params
|
||||
await User.updateUser(userId, req.body)
|
||||
res.redirect('back')
|
||||
res.redirect(303, 'back')
|
||||
}
|
||||
|
||||
module.exports = user
|
||||
|
||||
Reference in New Issue
Block a user