Basic signups are working

This commit is contained in:
2019-05-08 08:19:58 +10:00
parent 8896e60e80
commit 9b20a4b567
10 changed files with 682 additions and 13 deletions
+133
View File
@@ -0,0 +1,133 @@
//environment variables
require('dotenv').config();
//libraries
let bcrypt = require('bcrypt');
let formidable = require('formidable');
let sendmail = require('sendmail')();
//utilities
let { validateEmail } = require('../common/utilities.js');
function signup(connection) {
return (req, res) => {
//formidable handles forms
let form = formidable.IncomingForm();
//parse form
form.parse(req, (err, fields) => {
if (err) throw err;
//validate email, username and password
if (!validateEmail(fields.email) || fields.username.length < 4 || fields.username.length > 100 || fields.password.length < 8 || fields.password !== fields.retype) {
res.write('<p>Invalid signup data</p>');
res.end();
return;
}
//check if email, username already exists
let query = 'SELECT (SELECT COUNT(*) FROM accounts WHERE email = ?) AS email, (SELECT COUNT(*) FROM accounts WHERE username = ?) AS username;';
connection.query(query, [fields.email, fields.username], (err, results) => {
if (err) throw err;
if (results[0].email !== 0) {
res.write('<p>Email already registered!</p>');
res.end();
return;
}
if (results[0].username !== 0) {
res.write('<p>Username already registered!</p>');
res.end();
return;
}
//generate the salt, hash
bcrypt.genSalt(11, (err, salt) => {
if (err) throw err;
bcrypt.hash(fields.password, salt, (err, hash) => {
if (err) throw err;
//generate a random number as a key
let rand = Math.floor(Math.random() * 100000);
//save the generated data to the signups table
let query = 'REPLACE INTO signups (email, username, salt, hash, verify) VALUES (?, ?, ?, ?, ?);';
connection.query(query, [fields.email, fields.username, salt, hash, rand], (err) => {
if (err) throw err;
//build the verification email
let addr = `http://${process.env.WEB_ADDRESS}/verify?email=${fields.email}&verify=${rand}`;
let msg = 'Hello! Please visit the following address to verify your account: ';
let msgHtml = `<html><body><p>${msg}<a href='${addr}'>${addr}</a></p></body></html>`;
//send the verification email
sendmail({
from: `signup@${process.env.WEB_ADDRESS}`,
to: fields.email,
subject: 'Email Verification',
text: msg + addr,
html: msgHtml
}, (err, reply) => {
//final check
if (err) {
res.write(`<p>Something went wrong (did you use a valid email?)</p>${err}`)
res.end();
return;
}
res.write('<p>Verification email sent!</p>');
res.end();
});
})
});
});
});
});
}
}
function verify(connection) {
return (req, res) => {
//get the saved data
let query = 'SELECT email, username, salt, hash, verify FROM signups WHERE email = ?;';
connection.query(query, [req.query.email], (err, results) => {
if (err) throw err;
//correct number of results
if (results.length != 1) {
res.write('<p>That account does not exist or this link has already been used.</p>');
res.end();
return;
}
//verify the link
if (req.query.verify != results[0].verify) {
res.write('<p>Verification failed!</p>');
res.end();
return;
}
//move the data from signups to accounts
let query = 'INSERT INTO accounts (email, username, salt, hash) VALUES (?, ?, ?, ?);';
connection.query(query, [results[0].email, results[0].username, results[0].salt, results[0].hash], (err) => {
if (err) throw err;
//delete from signups
let query = 'DELETE FROM signups WHERE email = ?;';
connection.query(query, [results[0].email], (err) => {
if (err) throw err;
res.write('<p>Verification succeeded!</p>');
res.end();
});
});
});
}
}
module.exports = {
signup: signup,
verify: verify
};
+46
View File
@@ -0,0 +1,46 @@
//environment variables
require('dotenv').config();
//libraries
let mysql = require('mysql');
let connection;
function handleDisconnect() {
//use the config
connection = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASS,
database: process.env.DB_NAME,
port: process.env.DB_PORT
});
//connect
connection.connect((err) => {
if (err) {
console.log('Error connecting to mysql: ', err);
setTimeout(handleDisconnect, 2000);
} else {
console.log('Connected to mysql');
}
});
//prepare for failure
connection.on('error', (err) => {
console.log('mysql error: ', err);
if (err.code === 'PROTOCOL_CONNECTION_LOST') {
handleDisconnect();
} else {
throw (err);
}
});
//finally
return connection;
}
module.exports = {
connectToDatabase: handleDisconnect
}
+10 -5
View File
@@ -1,15 +1,20 @@
//environment variables
require('dotenv').config();
//libraries
let express = require('express');
let app = express();
let http = require('http').Server(app);
let path = require('path');
//database
let { connectToDatabase } = require('./database.js');
let connection = connectToDatabase(); //uses .env
//handle accounts
app.post('/signup', (req, res) => {
console.log('message heard, data ignored')
res.write('<p>message heard, data ignored</p>');
res.end();
});
let accounts = require('./accounts.js');
app.post('/signup', accounts.signup(connection));
app.get('/verify', accounts.verify(connection));
//static directories
app.use('/styles', express.static(path.resolve(__dirname + '/../public/styles')) );