Added sqlite db and email queue.
This commit is contained in:
parent
5a5c70cfb1
commit
03271573be
|
@ -2,7 +2,11 @@
|
||||||
"server": {
|
"server": {
|
||||||
"baseUrl": "http://localhost:8080",
|
"baseUrl": "http://localhost:8080",
|
||||||
"port": 8080,
|
"port": 8080,
|
||||||
"peersPath": "/tmp/peers"
|
"peersPath": "/tmp/peers",
|
||||||
|
|
||||||
|
"email": {
|
||||||
|
"from": "no-reply@musterstadt.freifunk.net"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"client": {
|
"client": {
|
||||||
"community": {
|
"community": {
|
||||||
|
@ -14,9 +18,6 @@
|
||||||
"graphUrl": "http://graph.hamburg.freifunk.net/graph.html",
|
"graphUrl": "http://graph.hamburg.freifunk.net/graph.html",
|
||||||
"mapUrl": "http://graph.hamburg.freifunk.net/geomap.html"
|
"mapUrl": "http://graph.hamburg.freifunk.net/geomap.html"
|
||||||
},
|
},
|
||||||
"monitoring": {
|
|
||||||
"enabled": true
|
|
||||||
},
|
|
||||||
"coordsSelector": {
|
"coordsSelector": {
|
||||||
"lat": 53.565278,
|
"lat": 53.565278,
|
||||||
"lng": 10.001389,
|
"lng": 10.001389,
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"async": "~1.5.2",
|
||||||
"body-parser": "~1.15.1",
|
"body-parser": "~1.15.1",
|
||||||
"compression": "~1.6.2",
|
"compression": "~1.6.2",
|
||||||
"deep-extend": "~0.4.1",
|
"deep-extend": "~0.4.1",
|
||||||
|
@ -40,6 +41,7 @@
|
||||||
"lodash": "~4.12.0",
|
"lodash": "~4.12.0",
|
||||||
"ng-di": "~0.2.1",
|
"ng-di": "~0.2.1",
|
||||||
"serve-static": "~1.10.2",
|
"serve-static": "~1.10.2",
|
||||||
|
"sqlite3": "~3.1.4",
|
||||||
"time-grunt": "~1.3.0"
|
"time-grunt": "~1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
|
|
|
@ -5,7 +5,11 @@ angular.module('ffffng').factory('config', function (fs, deepExtend) {
|
||||||
server: {
|
server: {
|
||||||
baseUrl: 'http://localhost:8080',
|
baseUrl: 'http://localhost:8080',
|
||||||
port: 8080,
|
port: 8080,
|
||||||
peersPath: '/tmp/peers'
|
peersPath: '/tmp/peers',
|
||||||
|
|
||||||
|
email: {
|
||||||
|
from: 'no-reply@musterstadt.freifunk.net'
|
||||||
|
}
|
||||||
},
|
},
|
||||||
client: {
|
client: {
|
||||||
community: {
|
community: {
|
||||||
|
|
79
server/db/database.js
Normal file
79
server/db/database.js
Normal 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();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
11
server/db/patches/001_add-email-queue-table.sql
Normal file
11
server/db/patches/001_add-email-queue-table.sql
Normal 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
|
||||||
|
);
|
|
@ -19,15 +19,18 @@ require('./utils/strings');
|
||||||
require('./resources/nodeResource');
|
require('./resources/nodeResource');
|
||||||
require('./resources/monitoringResource');
|
require('./resources/monitoringResource');
|
||||||
|
|
||||||
|
require('./services/mailService');
|
||||||
require('./services/nodeService');
|
require('./services/nodeService');
|
||||||
require('./services/monitoringService');
|
require('./services/monitoringService');
|
||||||
|
|
||||||
require('../shared/validation/constraints');
|
require('../shared/validation/constraints');
|
||||||
require('./validation/validator');
|
require('./validation/validator');
|
||||||
|
|
||||||
|
require('./db/database').init(function () {
|
||||||
angular.injector(['ffffng']).invoke(function (config, app, Router) {
|
angular.injector(['ffffng']).invoke(function (config, app, Router) {
|
||||||
Router.init();
|
Router.init();
|
||||||
|
|
||||||
app.listen(config.server.port, '::');
|
app.listen(config.server.port, '::');
|
||||||
module.exports = app;
|
module.exports = app;
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
20
server/services/mailService.js
Normal file
20
server/services/mailService.js
Normal 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);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
|
@ -1,7 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('ffffng')
|
angular.module('ffffng')
|
||||||
.service('NodeService', function (config, _, crypto, fs, glob, Strings, ErrorTypes) {
|
.service('NodeService', function (config, _, crypto, fs, glob, MailService, Strings, ErrorTypes) {
|
||||||
var linePrefixes = {
|
var linePrefixes = {
|
||||||
hostname: '# Knotenname: ',
|
hostname: '# Knotenname: ',
|
||||||
nickname: '# Ansprechpartner: ',
|
nickname: '# Ansprechpartner: ',
|
||||||
|
@ -196,6 +196,31 @@ angular.module('ffffng')
|
||||||
return parseNodeFile(file, callback);
|
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 {
|
return {
|
||||||
createNode: function (node, callback) {
|
createNode: function (node, callback) {
|
||||||
var token = generateToken();
|
var token = generateToken();
|
||||||
|
@ -213,7 +238,13 @@ angular.module('ffffng')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.monitoring && !node.monitoringConfirmed) {
|
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);
|
return callback(null, token, node);
|
||||||
|
@ -260,7 +291,13 @@ angular.module('ffffng')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.monitoring && !node.monitoringConfirmed) {
|
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);
|
return callback(null, token, node);
|
||||||
|
|
Loading…
Reference in a new issue