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

@@ -22,7 +22,7 @@ module.exports = function(app, controllersDir = __dirname + '/../controllers') {
for (let url of urls) {
app.get(url.url, ((url) => function(req, res, next) {
app[url.method.toLowerCase()](url.url, ((url) => function(req, res, next) {
let path = obj[url.view](req, res, function(template) {

View File

@@ -1,10 +1,11 @@
let urls = {};
class Url {
constructor(url, view, name) {
constructor(url, view, name, method="GET") {
this.url = url;
this.view = view;
this.name = name;
this.method = method;
}
}
@@ -19,8 +20,8 @@ module.exports = function(req, res, next) {
module.exports.getUrl = getUrl;
module.exports.url = function(url, viewName, urlName) {
let ret = new Url(url, viewName, urlName);
module.exports.url = function(url, viewName, urlName, method) {
let ret = new Url(url, viewName, urlName, method);
urls[urlName] = ret;
return ret;
}

14
utils/mail.js Normal file
View File

@@ -0,0 +1,14 @@
const config = require('settings/config');
const mail = require('emailjs');
module.exports = function(params, callback) {
let server = mail.server.connect({
user: config.MAIL.USERNAME,
password: config.MAIL.PASSWORD,
host: config.MAIL.HOSTNAME,
port: config.MAIL.PORT,
tls: config.MAIL.TLS
});
server.send(params, callback);
};

View File

@@ -5,6 +5,40 @@ const bc = require('bcryptjs');
let models = [];
function postgresToCamel(postgres) {
let ret = '';
for (let i = 0; i < postgres.length; i++) {
let c = postgres.charAt(i);
if (c === '_') {
i++;
ret += postgres.charAt(i).toUpperCase();
} else {
ret += c;
}
}
return ret;
}
function camelToPostgres(camelCase) {
let ret = '';
for (let i = 0; i < camelCase.length; i++) {
let c = camelCase.charAt(i);
if (c === c.toUpperCase()) {
ret += '_' + c.toLowerCase()
} else {
ret += c;
}
}
return ret;
}
function attributeToGetBy(attributeName) {
return 'getBy' +
attributeName.charAt(0).toUpperCase() + attributeName.substr(1);
}
module.exports.BaseModel = class {
constructor(name) {
models.push(this);
@@ -19,13 +53,17 @@ module.exports.BaseModel = class {
reinitialize(callback = () => {}) {
log.debug('Reinitializing ' + this.name);
db.query('DROP TABLE IF EXISTS ' + this.name + ' CASCADE')
let query =
"DROP TABLE IF EXISTS " +
camelToPostgres(this.name) + " CASCADE;";
db.query(query)
.then(res => this.createTable(callback))
.catch(err => log.dberror(err));
}
createTable(callback) {
let query = 'CREATE TABLE ' + this.name + '(\n';
let query = 'CREATE TABLE ' + camelToPostgres(this.name) + '(\n';
query += this.fields
.map(f => '\t' + f.getCreationString())
.join(',\n');
@@ -35,7 +73,7 @@ module.exports.BaseModel = class {
db.query(query)
.then(res => {
log.debug("Table " + this.name + " created")
log.debug("Table " + camelToPostgres(this.name) + " created")
callback();
})
.catch(err => log.dberror(err));
@@ -43,8 +81,30 @@ module.exports.BaseModel = class {
}
module.exports.BaseField = class {
constructor(name) {
constructor(name, properties = {}) {
this.name = name;
this.unique = properties.unique || false;
this.notNull = properties.notNull || false;
this.default = properties.default;
}
getCreationString() {
return [
camelToPostgres(this.name),
this.getPostgresType(),
this.getFormattedPropeties(),
].join(' ');
}
getFormattedPropeties() {
let properties = [];
if (this.unique) {
properties.push('UNIQUE');
}
if (this.notNull) {
properties.push('NOT NULL');
}
return properties.join(' ');
}
createMutators() {
@@ -73,43 +133,43 @@ module.exports.BaseField = class {
}
module.exports.SmallIntegerField = class extends module.exports.BaseField {
constructor(name) {
super(name);
constructor(name, properties = {}) {
super(name, properties);
}
getCreationString() {
return this.name + " SMALLINT";
getPostgresType() {
return "SMALLINT";
}
}
module.exports.SerialField = class extends module.exports.BaseField {
constructor(name) {
super(name);
constructor(name, properties = {}) {
super(name, properties);
this.unique = true;
}
getCreationString() {
return this.name + " SERIAL";
getPostgresType() {
return "SERIAL";
}
}
module.exports.TextField = class extends module.exports.BaseField {
constructor(name) {
super(name);
constructor(name, properties = {}) {
super(name, properties);
}
getCreationString() {
return this.name + " TEXT";
getPostgresType() {
return "TEXT";
}
}
module.exports.PasswordField = class extends module.exports.BaseField {
constructor(name) {
super(name);
constructor(name, properties = {}) {
super(name, properties);
}
getCreationString() {
return this.name + ' TEXT';
getPostgresType() {
return 'TEXT';
}
@@ -121,7 +181,6 @@ module.exports.PasswordField = class extends module.exports.BaseField {
changed: true,
};
}
}
}
@@ -130,36 +189,57 @@ module.exports.PasswordField.testSync = function(password, hash) {
}
module.exports.BoolField = class extends module.exports.BaseField {
constructor(name, properties) {
super(name, properties);
}
getPostgresType() {
return 'BOOLEAN';
}
}
module.exports.createClass = function(model) {
let ret = function(param) {
this._persisted = false;
for (let field of model.fields) {
this['_' + field.name] = {
value: undefined,
changed: false,
value: field.default,
changed: true,
}
Object.defineProperty(this, field.name, field.createMutators());
}
};
ret.getById = function(id, callback) {
db
.query('SELECT * FROM ' + model.name + ' WHERE id=$1;', [id])
.then(res => {
// Create the instance
let instance = new ret();
instance._persisted = true;
instance._setFromDbResult(res);
callback(undefined, instance);
})
.catch(err => callback(err));
for (let field of model.fields) {
if (!field.unique && field.name !== 'activationKey')
continue;
ret[attributeToGetBy(field.name)] = function(value, callback) {
let query =
'SELECT * FROM ' + camelToPostgres(model.name) +
' WHERE ' + camelToPostgres(field.name) +
'=$1;';
db
.query(query, [value])
.then(res => {
// Create the instance
let instance = new ret();
instance._persisted = true;
instance._setFromDbResult(res);
callback(undefined, instance);
})
.catch(err => callback(err));
}
}
ret.prototype._setFromDbResult = function(res) {
for (let field of model.fields) {
this['_' + field.name] = {
value: res.rows[0][field.name],
value: res.rows[0][camelToPostgres(field.name)],
changed: false,
};
}
@@ -182,10 +262,10 @@ module.exports.createClass = function(model) {
if (!this._persisted) {
// INSERT INTO
let queryBegin = 'INSERT INTO ' + model.name + '('
let queryBegin = 'INSERT INTO ' + camelToPostgres(model.name) + '('
let queryEnd = ' VALUES (';
queryBegin += fieldsToSave
.map(f => f.field.name)
.map(f => camelToPostgres(f.field.name))
.join(',');
queryEnd += fieldsToSave
@@ -208,16 +288,16 @@ module.exports.createClass = function(model) {
} else {
// UPDATE FROM
let query = 'UPDATE FROM ' + model.name + ' SET ';
let query = 'UPDATE ' + camelToPostgres(model.name) + ' SET ';
query += fieldsToSave.map(f => {
return f.field.name + '=' + f.value;
query += fieldsToSave.map((f, i) => {
return camelToPostgres(f.field.name) + '=$' + (i+1);
}).join(',');
query += ') RETURNING *;'
query += ' WHERE id=$' + (fieldsToSave.length + 1) + ' RETURNING *;'
db
.query(query, fieldsToSave.map(f => f.value))
.query(query, [...fieldsToSave.map(f => f.value), this.id])
.then(res => {
this._setFromDbResult(res);
this._persisted = true;