diff --git a/bin/ssu b/bin/ssu index 81707303..fcdbcd9d 100755 --- a/bin/ssu +++ b/bin/ssu @@ -28,6 +28,10 @@ function bail (error) { console.log('This will activate or deactivate a cryptocurrency.') console.log('\nssu config ') console.log('Configure a plugin setting.') + console.log('\nssu notify [email] [sms]') + console.log('Set notification plugin types.') + console.log('\nssu set ') + console.log('Set current plugin for plugin type.') process.exit(1) } @@ -41,6 +45,12 @@ switch (cmd) { case 'config': configure() break + case 'notify': + notify() + break + case 'set': + setPlugin() + break default: bail('No such command: ' + cmd) break @@ -269,3 +279,48 @@ function configure () { }) }) } + +function notify () { + var plugins = argv.slice(1) + var db = connect() + return loadConfig(db) + .then(function (config) { + config.exchanges.plugins.current.notify = JSON.stringify(plugins) + return updateConfig(db, config) + }) + .then(function () { + console.log('success') + pgp.end() + }) + .catch(function (err) { + console.log(err.stack) + pgp.end() + }) +} + +function setPlugin () { + var pluginType = argv[1] + var plugin = argv[2] + + var db = connect() + return loadConfig(db) + .then(function (config) { + if (!plugin) { + var _plugin = config.exchanges.plugins.current[pluginType] + _plugin + ? console.log('Current plugin for %s: %s', pluginType, _plugin) + : console.log('No plugin set for %s', pluginType) + process.exit(0) + } + config.exchanges.plugins.current[pluginType] = plugin + return updateConfig(db, config) + }) + .then(function () { + console.log('success') + pgp.end() + }) + .catch(function (err) { + console.log(err.stack) + pgp.end() + }) +} diff --git a/dev/send-message.js b/dev/send-message.js new file mode 100644 index 00000000..bd627369 --- /dev/null +++ b/dev/send-message.js @@ -0,0 +1,31 @@ +require('es6-promise').polyfill() + +var config = require('../lib/config') +var plugins = require('../lib/plugins') + +var rand = Math.floor(Math.random() * 1e6) + +var rec = { + email: { + toEmail: 'joshmh@gmail.com', + subject: 'Test email ' + rand, + body: 'This is a test email from lamassu-server' + }, + sms: { + toNumber: process.argv[2], + body: '[Lamassu] This is a test sms ' + rand + } +} + +var db = config.connection +config.loadConfig(db) +.then(function (config) { + plugins.configure(config) + plugins.sendMessage(rec) + .then(function () { + console.log('Success.') + }) + .catch(function (err) { + console.log(err.stack) + }) +}) diff --git a/lib/config.js b/lib/config.js index a5ad2002..0b3be2c5 100644 --- a/lib/config.js +++ b/lib/config.js @@ -1,4 +1,3 @@ -require('es6-promise').polyfill() var fs = require('fs') var pgp = require('pg-promise')() diff --git a/lib/email.js b/lib/email.js deleted file mode 100644 index a4b683e9..00000000 --- a/lib/email.js +++ /dev/null @@ -1,48 +0,0 @@ -var SMTPConnection = require('smtp-connection') -var Config = require('./config') - -/* - -Nice job signing up! Let's finish getting you set up. -Simply change the settings in your email software to these: -SMTP Server: mail.smtp2go.com -SMTP Port: 2525 (recommended) -Username: josh@lamassu.is -Password: view / edit -*/ - -var options = { - port: 2525, - host: 'mail.smtp2go.com', - requireTLS: true -} - -function send (from, to, subject, body, cb) { - Config.loadConfig() - .then(function (config) { - var _config = config.exchanges.plugins.settings.email - var user = _config.user - var pass = _config.pass - - var connection = new SMTPConnection(options) - connection.connect(function () { - connection.login({user: user, pass: pass}, function (err) { - if (err) return console.error(err) - var envelope = { - from: from, - to: to - } - var message = 'Subject: ' + subject + '\n\n' + body - connection.send(envelope, message, function (err, info) { - connection.quit() - cb(err, info) - }) - }) - }) - }) -} - -send('josh@lamassu.is', 'joshmh@gmail.com', 'Another test', 'Screen is stale.\n\nTest4', function (err, info) { - console.log(err) - console.log(info) -}) diff --git a/lib/plugins.js b/lib/plugins.js index 1f478026..77949856 100644 --- a/lib/plugins.js +++ b/lib/plugins.js @@ -29,6 +29,8 @@ var traderPlugins = {} var walletPlugins = {} var idVerifierPlugin = null var infoPlugin = null +var emailPlugin = null +var smsPlugin = null var currentlyUsedPlugins = {} @@ -61,7 +63,8 @@ function loadPlugin (name, config) { trader: ['purchase', 'sell'], wallet: ['balance', 'sendBitcoins', 'newAddress'], idVerifier: ['verifyUser', 'verifyTransaction'], - info: ['checkAddress'] + info: ['checkAddress'], + email: ['sendMessage'] } var plugin = null @@ -106,7 +109,7 @@ function loadPlugin (name, config) { '\' fails to implement *recommended* \'config\' method')) plugin.config = function () {} } else if (config !== null) { - plugin.config(config) // only when plugin supports it, and config is passed + plugin.config(config, logger) // only when plugin supports it, and config is passed } return plugin @@ -144,7 +147,9 @@ function loadOrConfigPlugin (pluginHandle, pluginType, cryptoCode, currency, return pluginHandle } +exports.loadOrConfigPlugin = loadOrConfigPlugin +// Note: this whole function gets called every time there's a config update exports.configure = function configure (config) { if (config.exchanges.settings.lowBalanceMargin < 1) { throw new Error('\'settings.lowBalanceMargin\' has to be >= 1') @@ -204,7 +209,18 @@ exports.configure = function configure (config) { infoPlugin, 'info' ) + + emailPlugin = loadOrConfigPlugin( + emailPlugin, + 'email' + ) + + smsPlugin = loadOrConfigPlugin( + smsPlugin, + 'sms' + ) } + exports.getConfig = function getConfig () { return cachedConfig } @@ -613,3 +629,18 @@ exports.verifyTx = function verifyTx (data, cb) { exports.getcryptoCodes = function getcryptoCodes () { return cryptoCodes } + +exports.sendMessage = function sendMessage (rec, cb) { + console.log('DEBUG5') + cb = cb || function () {} + console.log(cachedConfig.exchanges.plugins.current.notify) + var pluginTypes = JSON.parse(cachedConfig.exchanges.plugins.current.notify) + console.log('DEBUG7') + console.log(pluginTypes) + var pluginPromises = pluginTypes.map(function (pluginType) { + if (pluginType === 'email') return emailPlugin.sendMessage(rec, cb) + if (pluginType === 'sms') return smsPlugin.sendMessage(rec, cb) + throw new Error('No such plugin type: ' + pluginType) + }) + return Promise.all(pluginPromises) +} diff --git a/lib/sms.js b/lib/sms.js deleted file mode 100644 index 18f5d229..00000000 --- a/lib/sms.js +++ /dev/null @@ -1,22 +0,0 @@ -var Client = require('twilio') -var Config = require('./config') - -var toNumber = process.argv[2] - -Config.loadConfig() -.then(function (config) { - var _config = config.exchanges.plugins.settings.sms - var accountSid = _config.accountSid - var authToken = _config.authToken - var fromNumber = _config.fromNumber - - var client = Client(accountSid, authToken) - client.messages.create({ - body: '[Lamassu] ALERT Stale screen: acceptingFirstBill', - to: toNumber, - from: fromNumber - }, function (err, message) { - console.log(err) - console.log(message) - }) -}) diff --git a/todo.txt b/todo.txt index c3351e1e..e56ee262 100644 --- a/todo.txt +++ b/todo.txt @@ -1,53 +1,4 @@ -- getDeviceRate should return bignumber -- test with l-m - -backwards compatibility: - -- new l-m must be backwards compatible with old l-s - -- clean up db stuff satoshis/cryptoAtoms -- clean up other stuff - -- add 'ETH' to config in ssu crypto: config.exchanges.settings.coins - -[2016-04-06T19:58:17.827Z] ERROR: lamassu-server/39374 on MacBook-Pro: null value in column "satoshis" violates not-null constraint - error: null value in column "satoshis" violates not-null constraint - at Connection.parseE (/Users/josh/projects/lamassu-server/node_modules/pg/lib/connection.js:539:11) - at Connection.parseMessage (/Users/josh/projects/lamassu-server/node_modules/pg/lib/connection.js:366:17) - at Socket. (/Users/josh/projects/lamassu-server/node_modules/pg/lib/connection.js:105:22) - at Socket.emit (events.js:95:17) - at Socket. (_stream_readable.js:765:14) - at Socket.emit (events.js:92:17) - at emitReadable_ (_stream_readable.js:427:10) - at emitReadable (_stream_readable.js:423:5) - at readableAddChunk (_stream_readable.js:166:9) - at Socket.Readable.push (_stream_readable.js:128:10) - -alter table transactions alter satoshis TYPE bigint; -alter table transactions add crypto_code text default 'BTC'; -alter table pending_transactions add crypto_code text default 'BTC'; -alter table pending_transactions alter satoshis TYPE bigint; -alter table bills add crypto_code text default 'BTC'; -alter table bills alter satoshis TYPE bigint; - -- handle geth send failure better -- remove debug -- implement coin selection screen -- ask neal to work on config scripts - -[2016-04-17T22:10:57.917Z] ERROR: lamassu-server/32185 on MacBook-Pro.local: could not unlock signer account - Error: could not unlock signer account - at Object.module.exports.InvalidResponse (/Users/josh/projects/lamassu-geth/node_modules/web3/lib/web3/errors.js:35:16) - at /Users/josh/projects/lamassu-geth/node_modules/web3/lib/web3/requestmanager.js:86:36 - at request.onreadystatechange (/Users/josh/projects/lamassu-geth/node_modules/web3/lib/web3/httpprovider.js:114:13) - at dispatchEvent (/Users/josh/projects/lamassu-geth/node_modules/web3/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:591:25) - at setState (/Users/josh/projects/lamassu-geth/node_modules/web3/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:610:14) - at IncomingMessage. (/Users/josh/projects/lamassu-geth/node_modules/web3/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:447:13) - at emitNone (events.js:72:20) - at IncomingMessage.emit (events.js:166:7) - at endReadableNT (_stream_readable.js:913:12) - at nextTickCallbackWith2Args (node.js:442:9) -/Users/josh/projects/lamassu-server/lib/postgresql_interface.js:301 - satoshis.toString(), - ^ -better handling of this error +- configure email, sms or both for notification +- integrate email and sms into notifications +- run notifications from server +- don't keep sending notifications when state persists -- keep variable in memory