From 60cabd1936eb0d7921ea998920417987d0a2eca9 Mon Sep 17 00:00:00 2001 From: Kayne Ruse Date: Mon, 25 Jan 2021 12:53:46 +1100 Subject: [PATCH] Email validation working --- .envdev | 1 + README.md | 4 ++- server/accounts/index.js | 1 + server/accounts/signup.js | 17 +++++----- server/accounts/validation.js | 39 +++++++++++++++++++++++ server/database/index.js | 2 +- server/database/models/accounts.js | 2 +- server/database/models/pending-signups.js | 2 +- 8 files changed, 55 insertions(+), 13 deletions(-) create mode 100644 server/accounts/validation.js diff --git a/.envdev b/.envdev index 13a60f3..47dfd87 100644 --- a/.envdev +++ b/.envdev @@ -6,6 +6,7 @@ MAIL_SMTP=smtp.example.com MAIL_USERNAME=foobar@example.com MAIL_PASSWORD=foobar +DB_HOSTNAME=127.0.0.1 DB_DATABASE=template DB_USERNAME=template DB_PASSWORD=pikachu diff --git a/README.md b/README.md index 92d4774..57f65a9 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ This should get the template working in development mode. - Account system - ~~sign up~~ - - verify email + - ~~validate email~~ - login (with cookies) - logout - account deletion and management @@ -26,6 +26,8 @@ This should get the template working in development mode. - News blog system - access an external news feed - build the microservice to provide the news feed +- Chat system +- Achievements? # Email settings diff --git a/server/accounts/index.js b/server/accounts/index.js index 369fd9e..80309a8 100644 --- a/server/accounts/index.js +++ b/server/accounts/index.js @@ -3,5 +3,6 @@ const router = express.Router(); //basic account management router.post('/signup', require('./signup')); +router.get('/validation', require('./validation')); module.exports = router; diff --git a/server/accounts/signup.js b/server/accounts/signup.js index 954b5e8..f370676 100644 --- a/server/accounts/signup.js +++ b/server/accounts/signup.js @@ -9,7 +9,6 @@ const { bannedEmails, accounts, pendingSignups } = require('../database/models') //utilities const validateEmail = require('../../common/utilities/validate-email.js'); const validateUsername = require('../../common/utilities/validate-username.js'); -const sequelize = require('../database'); //api/accounts/signup const route = async (req, res) => { @@ -24,16 +23,16 @@ const route = async (req, res) => { const hash = await bcrypt.hash(req.fields.password, salt); //generate the validation field - const verify = Math.floor(Math.random() * 2000000000); + const token = Math.floor(Math.random() * 2000000000); //register signup - const signupErr = await registerPendingSignup(req.fields, hash, verify); + const signupErr = await registerPendingSignup(req.fields, hash, token); if (signupErr) { return res.status(500).send(signupErr); } //send the validation email - const emailErr = await sendValidationEmail(req.fields.email, verify); + const emailErr = await sendValidationEmail(req.fields.email, req.fields.username, token); if (emailErr) { return res.status(500).send(emailErr); } @@ -97,20 +96,20 @@ const validateDetails = async (fields) => { return null; }; -const registerPendingSignup = async (fields, hash, verify) => { +const registerPendingSignup = async (fields, hash, token) => { const record = await pendingSignups.upsert({ email: fields.email, username: fields.username, hash: hash, - verify: verify + token: token }); return null; }; -const sendValidationEmail = async (email, verify) => { - const addr = `${process.env.WEB_PROTOCOL}://${process.env.WEB_ADDRESS}/api/verify?verify=${verify}`; - const msg = `Hello! Please visit the following address to verify your account: ${addr}`; +const sendValidationEmail = async (email, username, token) => { + const addr = `${process.env.WEB_PROTOCOL}://${process.env.WEB_ADDRESS}/api/accounts/validation?username=${username}&token=${token}`; + const msg = `Hello! Please visit the following address to validate your account: ${addr}`; //what exactly is a transport? let transporter = nodemailer.createTransport({ diff --git a/server/accounts/validation.js b/server/accounts/validation.js new file mode 100644 index 0000000..5d02eaa --- /dev/null +++ b/server/accounts/validation.js @@ -0,0 +1,39 @@ +const { pendingSignups, accounts } = require('../database/models'); + +//api/accounts/validation +const route = async (req, res) => { + //get the existing pending signup + const info = await pendingSignups.findOne({ + where: { + username: req.query.username + } + }); + + //check the given info + if (!info) { + return res.status(401).send('validation failed'); + } + + if (info.token != req.query.token) { + return res.status(401).send('tokens do not match'); + } + + //delete the pending signup + pendingSignups.destroy({ + where: { + username: req.query.username + } + }); + + //move data to the accounts table + accounts.create({ + email: info.email, + username: info.username, + hash: info.hash + }); + + //finally + res.status(200).send('Validation succeeded!'); +}; + +module.exports = route; \ No newline at end of file diff --git a/server/database/index.js b/server/database/index.js index 7b8c394..fadb96a 100644 --- a/server/database/index.js +++ b/server/database/index.js @@ -1,7 +1,7 @@ const Sequelize = require('sequelize'); const sequelize = new Sequelize(process.env.DB_DATABASE, process.env.DB_USERNAME, process.env.DB_PASSWORD, { - host: '127.0.0.1', + host: process.env.DB_HOSTADDR, dialect: 'mariadb', logging: false }); diff --git a/server/database/models/accounts.js b/server/database/models/accounts.js index 6bb6257..e3c7b5b 100644 --- a/server/database/models/accounts.js +++ b/server/database/models/accounts.js @@ -28,7 +28,7 @@ module.exports = sequelize.define('accounts', { hash: 'varchar(100)', //for passwords - expiry: { + deletion: { type: 'DATETIME', allowNull: true, defaultValue: null diff --git a/server/database/models/pending-signups.js b/server/database/models/pending-signups.js index 1da186c..fbb5aea 100644 --- a/server/database/models/pending-signups.js +++ b/server/database/models/pending-signups.js @@ -14,5 +14,5 @@ module.exports = sequelize.define('pendingSignups', { hash: 'varchar(100)', //for passwords - verify: Sequelize.INTEGER(11) + token: Sequelize.INTEGER(11) });