We have email verification

This commit is contained in:
Thomas Forgione
2017-09-23 16:20:56 +00:00
parent fa105f855a
commit dae9643cd0
21 changed files with 446 additions and 59 deletions

View File

@@ -1,10 +1,14 @@
const model = require('model');
var user = new model.BaseModel("auth_user");
var user = new model.BaseModel("authUser");
user.addField(new model.SerialField("id"));
user.addField(new model.TextField("email"));
user.addField(new model.PasswordField("password"));
user.addField(new model.TextField("username", {unique: true, notNull: true}));
user.addField(new model.TextField("email", {unique: true, notNull: true}));
user.addField(new model.BoolField("active", {notNull: true, default: false}));
user.addField(new model.TextField("activationKey"));
user.addField(new model.PasswordField("password", {notNull: true}));
user.addField(new model.SmallIntegerField("resources"));
user.addField(new model.SmallIntegerField("project_id"));
user.addField(new model.SmallIntegerField("projectId"));
module.exports = model.createClass(user);

View File

@@ -0,0 +1,24 @@
{% extends "pyade/base.html" %}
{% block content %}
{% if login_failed %}
<div class="alert">Username or password incorrect. Please try again.</div>
{% endif %}
<div class="row">
<div class="col"></div>
<div class="col">
<form method="POST" action="{% url "login_target" %}">
<div class="form-group">
<input type="text" class="form-control" name="username" placeholder="Username" autofocus>
</div>
<div class="form-group">
<input type="password" class="form-control" name="password" placeholder="Password">
</div>
<div class="form-group">
<input class="btn btn-primary form-control" type="submit" value="Log in">
</div>
{% csrf_token %}
</form>
</div>
<div class="col"></div>
</div>
{% endblock %}

View File

@@ -1,4 +1,17 @@
extends ../../../templates/base.pug
block content
p Login
if loginFailed
.alert
| Username or password incorrect. Please try again.
.row
.col
.col
form(method="POST", action=getUrl("loginTarget"))
.form-group
input.form-control(type="text", name="username", placeholder="Username", autofocus)
.form-group
input.form-control(type="password", name="password", placeholder="Password")
.form-group
input.btn.btn-primary.form-control(type="submit", value="Log in")
.col

View File

@@ -0,0 +1,9 @@
{% extends "pyade/base.html" %}
{% block content %}
<h1>
A mail was sent to you.
</h1>
<p>
In this mail, you'll find a link to activate your account.
</p>
{% endblock %}

View File

@@ -0,0 +1,8 @@
extends ../../../templates/base.pug
block content
h1 A mail was sent to you
p.
In this mail, you'll find a link to activate your account.
p.
Please, don't forget that my server is cheap, so depending on your mail provider, my email might get thrown in the spam :'(

View File

@@ -0,0 +1,38 @@
extends ../../../templates/base.pug
block content
if registeringFailed
.alert There was an error.
.row
.col
.col
form(method="POST", action=getUrl("signupTarget"))
.form-group
input.form-control(type='text', name='username', placeholder='Username', autofocus='')
.form-group
input#email.form-control(type='email', name='email', placeholder='E-mail address')
.form-group
input#pass1.form-control(type='password', name='password', placeholder='Password')
.form-group
input#pass2.form-control(type='password', placeholder='Retype your password')
.form-group
input.btn.btn-primary.form-control(type='submit', value='Log in')
.col
block extrajs
script.
var mail = document.getElementById('email'),
pass = document.getElementById('pass1'),
pass2 = document.getElementById('pass2');
function validatePasswords() {
if (pass1.value === pass2.value) {
pass2.setCustomValidity('');
} else {
pass2.setCustomValidity("Passwords don't match");
}
}
pass1.addEventListener('change', validatePasswords);
pass2.addEventListener('keyup', validatePasswords);

View File

@@ -0,0 +1,50 @@
style.
.body {
width: 570px;
padding: 0px;
margin-right: auto;
margin-left: auto;
border: solid;
border-width: thin;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.header {
padding: 10px;
border-bottom: solid;
border-bottom-width: thin;
}
.footer {
font-size: 75%;
padding: 10px;
border-top: solid;
border-top-width: thin;
}
h1 {
text-align: center;
}
p {
padding: 10px;
margin: 0px;
}
.username {
font-style: italic;
}
.body
.header
h1 Welcome on ADEjs!
p.
Hello #{user.username}!
p.
You recently subscribed on ADEjs with the email <a href="mailto:#{user.email}">#{user.email}</a>.
p.
To finalize your subscription, please <a href="#{activationUrl}">click here to activate your account</a>.
.footer.
If you did not subscribe on PyADE with this email address, please ignore this e-mail.

View File

@@ -0,0 +1,10 @@
Hello #{user.username}, and welcome on ADEjs!
You recently subscribed on ADEjs with the email <a href="mailto:#{user.email}">#{user.email}</a>.
To finalize your subscription, please <a href="#{activationUrl}">click here to activate your account</a>.
See you later on ADEjs!
---
If you did not subscribe on ADEjs with this email address, please ignore this e-mail.

View File

@@ -2,4 +2,10 @@ const url = require('create-url').url;
module.exports = [
url('/login', 'login', 'login'),
url('/logout', 'logout', 'logout'),
url('/login-target', 'loginTarget', 'loginTarget', 'POST'),
url('/signup', 'signup', 'signup'),
url('/signup-target', 'signupTarget', 'signupTarget', 'POST'),
url('/mail-was-sent', 'mailWasSent', 'mailWasSent'),
url('/activate/:activationKey', 'activate', 'activate'),
]

View File

@@ -1,10 +1,95 @@
const testPassword = require('model').PasswordField.testSync;
const User = require('./models.js');
const getUrl = require('create-url').getUrl;
const mail = require('mail');
const pug = require('pug');
const config = require('settings/config');
module.exports.login = function(req, res, render) {
render('login.pug');
}
module.exports.signup = function(req, res, render) {
render('signup.pug');
}
module.exports.logout = function(req, res, render) {
req.session.user = undefined;
req.session.save();
res.redirect(getUrl("index"));
}
module.exports.loginTarget = function(req, res, render) {
User.getByUsername(req.body.username, (err, user) => {
if (user === undefined || !user.active) {
res.redirect(getUrl('login'));
} else {
if (testPassword(req.body.password, user.password)) {
req.session.user = user;
req.session.save();
res.redirect(getUrl('index'));
} else {
res.redirect(getUrl('login'));
}
}
});
}
module.exports.signupTarget = function(req, res, render) {
let user = new User();
user.username = req.body.username;
user.email = req.body.email;
user.password = req.body.password;
require('crypto').randomBytes(48, function(err, buffer) {
user.activationKey = buffer.toString('hex');
user.save((err) => {
res.locals.user = user;
let baseUrl =
req.headers.referer.split('/').slice(0, 3).join('/') + '/'
res.locals.activationUrl =
baseUrl + 'activate/' + user.activationKey;
let html = pug.renderFile(
__dirname + '/templates/validation-mail.pug',
res.locals,
);
mail({
from: config.MAIL.FROM,
to: user.username + ' <' + user.email + '>',
subject: 'Welcome on ADEjs!',
text:'',
attachment: [
{data: html, alternative: true}
]
}, (err, result) => {
res.redirect(getUrl('mailWasSent'));
});
});
});
}
module.exports.mailWasSent = function(req, res, render) {
render('mailWasSent.pug');
}
module.exports.activate = function(req, res, render, next) {
User.getByActivationKey(req.params.activationKey, (err, user) => {
if (user === undefined) {
return next();
}
user.active = true;
user.activationKey = undefined;
user.save((err, user) => {
req.session.user = user;
req.session.save();
res.redirect(getUrl('index'));
});
});
}