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 | ||||
| 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 | ||||
| @@ -14,3 +17,4 @@ POSTGRES_PORT = 5432 | ||||
|  | ||||
| # Application settings | ||||
| 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 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 | ||||
|     }); | ||||
|   | ||||
							
								
								
									
										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