'How to inform single page application that email was verified?
I have vue js application running on localhost:3000 and express js restful api running on localhost:4000. Whenever new user registers, the request is sent to /api/v1/signup endpoint and after successfull registration verification email is sent with url including localhost:4000/api/v1/verify-email/:token
After user click link in the email how to inform vue js application that email validated? use socket or ...?
Register controller
async store(req, res) {
let errors = {}
let valid = false
await signupSchema.validate({
first_name: req.body.first_name?.trim(),
last_name: req.body.last_name?.trim(),
email: req.body.email?.trim(),
password: req.body.password?.trim(),
password_confirmation: req.body.password_confirmation?.trim(),
}, { abortEarly: false })
.then(() => valid = true)
.catch((err) => {
err.inner.map((inn) => errors[inn.path] = inn.errors)
})
if (!valid) return res.status(400).json({ errors: errors, message: 'Validation errors' })
const data = {
first_name: req.body.first_name.trim(),
last_name: req.body.last_name?.trim(),
email: req.body.email.trim(),
password: bcrypt.hashSync(req.body.password, 12)
}
let id = null
// create user
await knex('users').insert(data)
.then((res) => id = res[0])
.catch((err) => {
logger.log(err)
return res.status(500).json({ error: err.message })
})
// create verification token
const verificationToken = jwt.sign({ id: id }, process.env.ACCESS_TOKEN_SECRET, { expiresIn: 3600 })
await (new VerificationEmail(verificationToken, { id })).queue(data.email)
const user = await knex('users')
.select([ 'id', 'email', 'first_name', 'last_name', 'verified_at', 'deleted_at', 'created_at', 'updated_at' ])
.where('id', id)
.first()
.then((res) => res)
// sign jwt tokens
const accessToken = jwt.sign(user, process.env.ACCESS_TOKEN_SECRET, { expiresIn: 60 })
const refreshToken = jwt.sign(user, process.env.REFRESH_TOKEN_SECRET, { expiresIn: '1h' })
return res.json({ id: id, message: 'Successfully registered', accessToken, refreshToken })
}
VerifyEmailController
class VerifyEmailController {
/**
*
* @param {*} req
* @param {*} res
*/
async store(req, res) {
const user = await knex('users').where('id', req.params.id).first().then(res)
if (!user) res.status(404).json({ message: 'User not found' })
// validate token
jwt.verify(req.params.token, process.env.ACCESS_TOKEN_SECRET, async (err, data) => {
if (err) return res.status(401).json({ message: 'Invalid token' })
if (data.id !== user.id) res.status(401).json({ message: 'Invalid token' })
await knex('users').where('id', req.params.id)
.update({ verified_at: new Date() })
return res.json({ message: 'Your account verified. Thanks' })
})
}
}
VerificationEmail
class VerificationEmail {
token;
user;
constructor(token, user) {
this.token = token
this.user = user
}
layout(content) {
const str = fs.readFileSync(path.join(__dirname, '../../views/vendor/mail/default.ejs'), 'utf-8')
return ejs.render(str, { content })
}
build() {
const url = `${process.env.APP_URL}/api/v1/verify-email/${this.user.id}/${this.token}`
const str = fs.readFileSync(path.join(__dirname, '../../views/email/verification.ejs'), 'utf-8')
const content = ejs.render(str, { url })
return this.layout(content)
}
async queue(to) {
const html = this.build()
return emailQueue.add({ to, subject: 'Verify email address', html })
}
}
Signup page
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|


