Added sqlite db and email queue.

This commit is contained in:
baldo 2016-05-20 22:11:35 +02:00
parent 5a5c70cfb1
commit 03271573be
8 changed files with 169 additions and 12 deletions

View file

@ -2,7 +2,11 @@
"server": {
"baseUrl": "http://localhost:8080",
"port": 8080,
"peersPath": "/tmp/peers"
"peersPath": "/tmp/peers",
"email": {
"from": "no-reply@musterstadt.freifunk.net"
}
},
"client": {
"community": {
@ -14,9 +18,6 @@
"graphUrl": "http://graph.hamburg.freifunk.net/graph.html",
"mapUrl": "http://graph.hamburg.freifunk.net/geomap.html"
},
"monitoring": {
"enabled": true
},
"coordsSelector": {
"lat": 53.565278,
"lng": 10.001389,

View file

@ -4,6 +4,7 @@
"license": "MIT",
"dependencies": {},
"devDependencies": {
"async": "~1.5.2",
"body-parser": "~1.15.1",
"compression": "~1.6.2",
"deep-extend": "~0.4.1",
@ -40,6 +41,7 @@
"lodash": "~4.12.0",
"ng-di": "~0.2.1",
"serve-static": "~1.10.2",
"sqlite3": "~3.1.4",
"time-grunt": "~1.3.0"
},
"engines": {

View file

@ -5,7 +5,11 @@ angular.module('ffffng').factory('config', function (fs, deepExtend) {
server: {
baseUrl: 'http://localhost:8080',
port: 8080,
peersPath: '/tmp/peers'
peersPath: '/tmp/peers',
email: {
from: 'no-reply@musterstadt.freifunk.net'
}
},
client: {
community: {

79
server/db/database.js Normal file
View file

@ -0,0 +1,79 @@
'use strict';
var async = require('async');
var fs = require('fs');
var glob = require('glob');
var path = require('path');
function applyPatch(db, file, callback) {
fs.readFile(file, function (err, contents) {
if (err) {
return callback(err);
}
var version = path.basename(file, '.sql');
db.get('SELECT * FROM schema_version WHERE version = ?', version, function (err, row) {
if (err) {
return callback(err);
}
if (row) {
// patch is already applied. skip!
return callback(null);
}
var sql = 'BEGIN TRANSACTION;\n'
+ contents.toString() + '\n'
+ 'INSERT INTO schema_version (version) VALUES (\'' + version + '\');\n'
+ 'END TRANSACTION;';
db.exec(sql, callback);
});
});
}
function applyMigrations(db, callback) {
var sql = 'BEGIN TRANSACTION; CREATE TABLE IF NOT EXISTS schema_version (\n'
+ ' version VARCHAR(255) PRIMARY KEY ASC,\n'
+ ' applied_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL\n'
+ '); END TRANSACTION;';
db.exec(sql, function (err) {
if (err) {
return callback(err);
}
glob(__dirname + '/patches/*.sql', function (err, files) {
if (err) {
return callback(err);
}
async.each(
files,
function (file, fileCallback) {
applyPatch(db, file, fileCallback);
},
callback
);
});
});
}
module.exports = {
init: function (callback) {
var SQLite3 = require('sqlite3');
var db = new SQLite3.Database('/tmp/test.sqlite');
applyMigrations(db, function (err) {
if (err) {
throw err;
}
angular.module('ffffng').factory('Database', function () {
return db;
});
callback();
});
}
};

View file

@ -0,0 +1,11 @@
CREATE TABLE email_queue (
id INTEGER PRIMARY KEY ASC AUTOINCREMENT,
failures INTEGER NOT NULL,
sender VARCHAR(255) NOT NULL,
recipient VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL,
data TEXT NOT NULL,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL
);

View file

@ -19,15 +19,18 @@ require('./utils/strings');
require('./resources/nodeResource');
require('./resources/monitoringResource');
require('./services/mailService');
require('./services/nodeService');
require('./services/monitoringService');
require('../shared/validation/constraints');
require('./validation/validator');
angular.injector(['ffffng']).invoke(function (config, app, Router) {
require('./db/database').init(function () {
angular.injector(['ffffng']).invoke(function (config, app, Router) {
Router.init();
app.listen(config.server.port, '::');
module.exports = app;
});
});

View file

@ -0,0 +1,20 @@
'use strict';
angular.module('ffffng')
.service('MailService', function (Database, _) {
return {
enqueue: function (sender, recipient, email, data, callback) {
if (!_.isPlainObject(data)) {
return callback(new Error('Unexpected data: ' + data));
}
Database.run(
'INSERT INTO email_queue (failures, sender, recipient, email, data) VALUES (?, ?, ?, ?, ?)',
[0, sender, recipient, email, JSON.stringify(data)],
function (err, res) {
debugger;
callback(err, res);
}
);
}
};
});

View file

@ -1,7 +1,7 @@
'use strict';
angular.module('ffffng')
.service('NodeService', function (config, _, crypto, fs, glob, Strings, ErrorTypes) {
.service('NodeService', function (config, _, crypto, fs, glob, MailService, Strings, ErrorTypes) {
var linePrefixes = {
hostname: '# Knotenname: ',
nickname: '# Ansprechpartner: ',
@ -196,6 +196,31 @@ angular.module('ffffng')
return parseNodeFile(file, callback);
}
function sendMonitoringConfirmationMail(node, nodeSecrets, callback) {
var monitoringQueryString = '?mac=' + node.mac + '&token=' + nodeSecrets.monitoringToken;
var confirmUrl = config.server.baseUrl + '/#!/monitoring/confirm' + monitoringQueryString;
var disableUrl = config.server.baseUrl + '/#!/monitoring/disable' + monitoringQueryString;
MailService.enqueue(
config.server.email.from,
node.email,
'monitoring-confirmation',
{
node: node,
confirmUrl: confirmUrl,
disableUrl: disableUrl
},
function (err) {
if (err) {
console.log(err);
return callback({data: 'Internal error.', type: ErrorTypes.internalError});
}
callback(null);
}
);
}
return {
createNode: function (node, callback) {
var token = generateToken();
@ -213,7 +238,13 @@ angular.module('ffffng')
}
if (node.monitoring && !node.monitoringConfirmed) {
// TODO: Send mail...
return sendMonitoringConfirmationMail(node, nodeSecrets, function (err) {
if (err) {
return callback(err);
}
return callback(null, token, node);
});
}
return callback(null, token, node);
@ -260,7 +291,13 @@ angular.module('ffffng')
}
if (node.monitoring && !node.monitoringConfirmed) {
// TODO: Send mail...
return sendMonitoringConfirmationMail(node, nodeSecrets, function (err) {
if (err) {
return callback(err);
}
return callback(null, token, node);
});
}
return callback(null, token, node);