Browse Source

Worked on emails, added verify email email.

KrisVos130 8 years ago
parent
commit
8f13f31f6d

+ 4 - 0
backend/config/template.json

@@ -19,6 +19,10 @@
 		"discord": {
 			"client": "",
 			"secret": ""
+		},
+		"mailgun": {
+			"key": "",
+			"domain": ""
 		}
 	},
 	"cors": {

+ 4 - 0
backend/index.js

@@ -6,6 +6,7 @@ const async = require('async');
 
 const db = require('./logic/db');
 const app = require('./logic/app');
+const mail = require('./logic/mail');
 const api = require('./logic/api');
 const io = require('./logic/io');
 const stations = require('./logic/stations');
@@ -35,6 +36,9 @@ async.waterfall([
 	// setup the express server
 	(next) => app.init(next),
 
+	// setup the mail
+	(next) => mail.init(next),
+
 	// setup the socket.io server (all client / server communication is done over this)
 	(next) => io.init(next),
 

+ 1 - 1
backend/logic/actions/stations.js

@@ -399,7 +399,7 @@ module.exports = {
 
 	create: hooks.loginRequired((session, data, cb) => {
 		data._id = data._id.toLowerCase();
-		let blacklist = ["country", "edm", "musare", "hip-hop", "rap", "top-hits", "todays-hits", "old-school", "christmas", "about", "support", "staff", "help", "news", "terms", "privacy", "profile", "c", "community", "tos", "login", "register", "p", "official", "o", "trap", "faq", "team", "donate", "buy", "shop", "forums", "explore", "settings", "admin"];
+		let blacklist = ["country", "edm", "musare", "hip-hop", "rap", "top-hits", "todays-hits", "old-school", "christmas", "about", "support", "staff", "help", "news", "terms", "privacy", "profile", "c", "community", "tos", "login", "register", "p", "official", "o", "trap", "faq", "team", "donate", "buy", "shop", "forums", "explore", "settings", "admin", "auth"];
 		async.waterfall([
 
 			(next) => {

+ 12 - 3
backend/logic/actions/users.js

@@ -6,6 +6,7 @@ const request = require('request');
 const bcrypt = require('bcrypt');
 
 const db = require('../db');
+const mail = require('../mail');
 const cache = require('../cache');
 const utils = require('../utils');
 const hooks = require('./hooks');
@@ -88,6 +89,7 @@ module.exports = {
 	 */
 	register: function(session, username, email, password, recaptcha, cb) {
 		email = email.toLowerCase();
+		let verificationToken = utils.generateRandomString(64);
 		async.waterfall([
 
 			// verify the request with google recaptcha
@@ -136,7 +138,7 @@ module.exports = {
 					username,
 					email: {
 						address: email,
-						verificationToken: utils.generateRandomString(64)
+						verificationToken: verificationToken
 					},
 					services: {
 						password: {
@@ -149,7 +151,9 @@ module.exports = {
 			// respond with the new user
 			(newUser, next) => {
 				//TODO Send verification email
-				next();
+				mail.schemas.verifyEmail(email, username, verificationToken, () => {
+					next();
+				});
 			}
 
 		], (err) => {
@@ -365,11 +369,16 @@ module.exports = {
 						logger.error("UPDATE_EMAIL", `Email already in use.`);
 						return cb({ status: 'failure', message: 'That email is already in use.' });
 					}
-					db.models.user.update({_id: userId}, {$set: {"email.address": newEmail}}, (err) => {
+					let verificationToken = utils.generateRandomString(64);
+					db.models.user.update({_id: userId}, {$set: {"email.address": newEmail, "email.verified": false, "email.verificationToken": verificationToken}}, (err) => {
 						if (err) {
 							logger.error("UPDATE_EMAIL", `Couldn't update user. Mongo error. ${err.message}`);
 							return cb({ status: 'error', message: err.message });
 						}
+						console.log(12, newEmail, user.username, verificationToken);
+						mail.schemas.verifyEmail(newEmail, user.username, verificationToken, (err) => {
+							console.log(1, err);
+						});
 						logger.success("UPDATE_EMAIL", `Updated email. '${userId}' ${newEmail}'`);
 						cb({ status: 'success', message: 'Email updated successfully.' });
 					});

+ 36 - 3
backend/logic/app.js

@@ -4,6 +4,9 @@ const express = require('express');
 const bodyParser = require('body-parser');
 const cors = require('cors');
 const config = require('config');
+const async = require('async');
+const logger = require('./logger');
+const mail = require('./mail');
 const request = require('request');
 const OAuth2 = require('oauth').OAuth2;
 
@@ -98,6 +101,7 @@ const lib = {
 											if (email.primary) address = email.email.toLowerCase();
 										});
 										db.models.user.findOne({'email.address': address}, (err, user) => {
+											let verificationToken = utils.generateRandomString(64);
 											if (err) return redirectOnErr(res, err.message);
 											if (user) return redirectOnErr(res, 'An account with that email address already exists.');
 											else db.models.user.create({
@@ -105,14 +109,14 @@ const lib = {
 												username: body.login,
 												email: {
 													address,
-													verificationToken: utils.generateRandomString(64)
+													verificationToken: verificationToken
 												},
 												services: {
 													github: {id: body.id, access_token}
 												}
 											}, (err, user) => {
 												if (err) return redirectOnErr(res, err.message);
-												//TODO Send verification email
+												mail.schemas.verifyEmail(address, body.login, verificationToken);
 												let sessionId = utils.guid();
 												cache.hset('sessions', sessionId, cache.schemas.session(sessionId, user._id), err => {
 													if (err) return redirectOnErr(res, err.message);
@@ -132,9 +136,38 @@ const lib = {
 			});
 		});
 
-		cb();
+		app.get('/auth/verify_email', (req, res) => {
+			let code = req.query.code;
 
+			async.waterfall([
+				(next) => {
+					if (!code) return next('Invalid code.');
+					next();
+				},
+
+				(next) => {
+					db.models.user.findOne({"email.verificationToken": code}, next);
+				},
+
+				(user, next) => {
+					if (!user) return next('User not found.');
+					if (user.email.verified) return next('This email is already verified.');
+					db.models.user.update({"email.verificationToken": code}, {$set: {"email.verified": true}, $unset: {"email.verificationToken": ''}}, next);
+				}
+			], (err) => {
+				if (err) {
+					let error = 'An error occurred.';
+					if (typeof err === "string") error = err;
+					else if (err.message) error = err.message;
+					logger.error("VERIFY_EMAIL", `Verifying email failed. "${error}"`);
+					return res.json({ status: 'failure', message: error});
+				}
+				logger.success("VERIFY_EMAIL", `Successfully verified email.`);
+				res.redirect(config.get("domain"));
+			});
+		});
 
+		cb();
 	}
 };
 

+ 24 - 0
backend/logic/mail/index.js

@@ -0,0 +1,24 @@
+'use strict';
+
+const config = require('config');
+const mailgun = require('mailgun-js')({apiKey: config.get("apis.mailgun.key"), domain: config.get("apis.mailgun.domain")});
+
+let lib = {
+
+	schemas: {},
+
+	init: (cb) => {
+		lib.schemas = {
+			verifyEmail: require('./schemas/verifyEmail')
+		};
+
+		cb();
+	},
+
+	sendMail: (data, cb) => {
+		if (!cb) cb = ()=>{};
+		mailgun.messages().send(data, cb);
+	}
+};
+
+module.exports = lib;

+ 27 - 0
backend/logic/mail/schemas/verifyEmail.js

@@ -0,0 +1,27 @@
+const config = require('config');
+const mail = require('../index');
+
+/**
+ * Sends a verify email email
+ *
+ * @param {String} to - the email address of the recipient
+ * @param {String} username - the username of the recipient
+ * @param {String} code - the email reset code of the recipient
+ * @param {Function} cb - gets called when an error occurred or when the operation was successful
+ */
+module.exports = function(to, username, code, cb) {
+	let data = {
+		from: 'Musare <noreply@musare.com>',
+		to: to,
+		subject: 'Please verify your email',
+		html:
+			`
+				Hello there ${username},
+				<br>
+				<br>
+				To verify your email, please visit <a href="${config.get('serverDomain')}/auth/verify_email?code=${code}">${config.get('serverDomain')}/auth/verify_email?code=${code}</a>.
+			`
+	};
+
+	mail.sendMail(data, cb);
+};

+ 1 - 0
backend/package.json

@@ -20,6 +20,7 @@
     "cors": "^2.8.1",
     "express": "^4.14.0",
     "express-session": "^1.14.0",
+    "mailgun-js": "^0.8.0",
     "moment": "^2.15.2",
     "mongoose": "^4.6.0",
     "oauth": "^0.9.14",

BIN
frontend/build/assets/wordmark.png