mirror of
				https://github.com/xfarrow/blink
				synced 2025-06-27 09:03:02 +02:00 
			
		
		
		
	Send e-mail verification
This commit is contained in:
		| @@ -5,6 +5,9 @@ API_SERVER_PORT = 3000 | |||||||
| JWT_SECRET_KEY = jwt-secret # Change this in production | JWT_SECRET_KEY = jwt-secret # Change this in production | ||||||
| LIMITER_WINDOW = 3600000 # Milliseconds in limiter window | LIMITER_WINDOW = 3600000 # Milliseconds in limiter window | ||||||
| LIMITER_MAXIMUM_PER_WINDOW = 5000 # Requests for each 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 | # Database settings | ||||||
| POSTGRES_SERVER = localhost | POSTGRES_SERVER = localhost | ||||||
| @@ -13,4 +16,5 @@ POSTGRES_PASSWORD = postgres | |||||||
| POSTGRES_PORT = 5432 | POSTGRES_PORT = 5432 | ||||||
|  |  | ||||||
| # Application settings | # 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? | ||||||
| @@ -18,6 +18,7 @@ const crypto = require('crypto'); | |||||||
| const personModel = require('../models/person_model'); | const personModel = require('../models/person_model'); | ||||||
| const activationModel = require('../models/activation_model'); | const activationModel = require('../models/activation_model'); | ||||||
| const express = require('express'); | const express = require('express'); | ||||||
|  | const mailUtils = require('../utils/mail_utils'); | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * POST Request |  * 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) |     // Check whether e-mail exists already (enforced by database constraints) | ||||||
|     const existingUser = await personModel.getPersonByEmail(req.body.email); |     const existingUser = await personModel.getPersonByEmail(req.body.email); | ||||||
|     if (existingUser) { |     if (existingUser) { | ||||||
| @@ -57,17 +52,34 @@ async function registerPerson(req, res) { | |||||||
|         error: 'E-mail already in use' |         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( |     const personToInsert = personModel.createPerson( | ||||||
|       req.body.email, |       req.body.email, | ||||||
|       await hashPasswordPromise, |       await hashPasswordPromise, | ||||||
|       req.body.display_name, |       req.body.display_name, | ||||||
|       req.body.date_of_birth, |       req.body.date_of_birth, | ||||||
|       req.body.available, |       req.body.available, | ||||||
|       false, |       isEnabled, | ||||||
|       req.body.place_of_living, |       req.body.place_of_living, | ||||||
|       req.body.about_me, |       req.body.about_me, | ||||||
|       req.body.qualification); |       req.body.qualification); | ||||||
|     await personModel.registerPerson(personToInsert, activationLink); |     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({ |     return res.status(200).json({ | ||||||
|       activationLink |       activationLink | ||||||
|     }); |     }); | ||||||
|   | |||||||
							
								
								
									
										40
									
								
								backend/apis/nodejs/src/utils/mail_utils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								backend/apis/nodejs/src/utils/mail_utils.js
									
									
									
									
									
										Normal 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 | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user