Send e-mail verification

This commit is contained in:
xfarrow 2024-03-07 18:08:09 +01:00
parent d491b9064c
commit 696d1b8b7b
3 changed files with 64 additions and 8 deletions

View File

@ -5,6 +5,9 @@ API_SERVER_PORT = 3000
JWT_SECRET_KEY = jwt-secret # Change this in production
LIMITER_WINDOW = 3600000 # Milliseconds in limiter window
LIMITER_MAXIMUM_PER_WINDOW = 5000 # Requests for each limiter window
SMTP_USERNAME = blink@ik.me # Fill only if NEEDS_EMAIL_VERIFICATION is true
SMTP_PASSWORD = your_password # Fill only if NEEDS_EMAIL_VERIFICATION is true
SMTP_PORT = 465 # Fill only if NEEDS_EMAIL_VERIFICATION is true
# Database settings
POSTGRES_SERVER = localhost
@ -13,4 +16,5 @@ POSTGRES_PASSWORD = postgres
POSTGRES_PORT = 5432
# Application settings
ALLOW_USER_REGISTRATION = true
ALLOW_USER_REGISTRATION = true
NEEDS_EMAIL_VERIFICATION = true # Does this server need users to verify their e-mail address?

View File

@ -18,6 +18,7 @@ const crypto = require('crypto');
const personModel = require('../models/person_model');
const activationModel = require('../models/activation_model');
const express = require('express');
const mailUtils = require('../utils/mail_utils');
/**
* POST Request
@ -44,12 +45,6 @@ async function registerPerson(req, res) {
});
}
// Generate activation link token
const activationLink = crypto.randomBytes(16).toString('hex');
// Hash provided password
const hashPasswordPromise = bcrypt.hash(req.body.password, 10);
// Check whether e-mail exists already (enforced by database constraints)
const existingUser = await personModel.getPersonByEmail(req.body.email);
if (existingUser) {
@ -57,17 +52,34 @@ async function registerPerson(req, res) {
error: 'E-mail already in use'
});
}
let activationLink = '';
let isEnabled = true;
if (process.env.NEEDS_EMAIL_VERIFICATION === 'true') {
// Generate activation link token
activationLink = crypto.randomBytes(16).toString('hex');
isEnabled = false;
}
// Hash provided password
const hashPasswordPromise = bcrypt.hash(req.body.password, 10);
const personToInsert = personModel.createPerson(
req.body.email,
await hashPasswordPromise,
req.body.display_name,
req.body.date_of_birth,
req.body.available,
false,
isEnabled,
req.body.place_of_living,
req.body.about_me,
req.body.qualification);
await personModel.registerPerson(personToInsert, activationLink);
if (process.env.NEEDS_EMAIL_VERIFICATION === 'true') {
// TODO generalize
mailUtils.sendConfirmationLink(req.body.email, 'http://localhost:3000/api/persons/me/activation?q=' + activationLink);
}
return res.status(200).json({
activationLink
});

View File

@ -0,0 +1,40 @@
const nodemailer = require('nodemailer');
// Create a transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
service: 'Infomaniak',
auth: {
user: process.env.SMTP_USERNAME,
pass: process.env.SMTP_PASSWORD
}
});
function sendConfirmationLink(destinationEmail, confirmationLink) {
let mailOptions = {
from: `"Blink" ${process.env.SMTP_USERNAME}`,
to: destinationEmail,
subject: 'Verify your Blink Account',
// text: 'This is plain HTML',
html: getConfirmationLinkHtmlPage(confirmationLink)
};
sendMail(mailOptions);
}
function sendMail(mailOptions) {
// Send mail with defined transport object
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
return console.error(error);
}
console.log('Message sent: %s', info.messageId);
});
}
function getConfirmationLinkHtmlPage(confirmationLink) {
return `<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>Activation Page</title><style>body{font-family:Arial,sans-serif;background-color:#f4f4f4;margin:0;padding:0;display:flex;justify-content:center;align-items:center;height:100vh}.container{text-align:center;padding:20px;border-radius:10px;box-shadow:0 0 20px rgba(0,0,0,.1);background-color:#fff}h1{color:#333}a{display:block;padding:10px 20px;margin-top:20px;background-color:#007bff;color:#fff;text-decoration:none;border-radius:5px;transition:background-color .3s ease}a:hover{background-color:#0056b3}</style></head><body><div class="container"><h1>Activate your Blink Account</h1><p>Please click the activation link below to activate your account</p><a href="${confirmationLink}">Activate Now</a></div></body></html>`;
}
module.exports = {
sendConfirmationLink,
sendMail
}