diff --git a/config.js b/config.js index 4ba24b7..5bffbd0 100644 --- a/config.js +++ b/config.js @@ -50,7 +50,7 @@ var config = { defaultLanguage: 'en', defaultUnit: 'btc', subjectPrefix: '', - pushServerUrl: 'http://localhost:8000/send', + pushServerUrl: 'http://localhost:8000', }, fiatRateServiceOpts: { defaultProvider: 'BitPay', diff --git a/lib/expressapp.js b/lib/expressapp.js index c197374..af850fb 100644 --- a/lib/expressapp.js +++ b/lib/expressapp.js @@ -518,6 +518,23 @@ ExpressApp.prototype.start = function(opts, cb) { }); }); + router.post('/v1/pushnotifications/subscriptions/', function(req, res) { + getServerWithAuth(req, res, function(server) { + server.pushNotificationsSubscribe(req.body, function(err, response) { + if (err) return returnError(err, res, req); + res.json(response); + }); + }); + }); + + router.delete('/v1/pushnotifications/subscriptions/:token/', function(req, res) { + getServerWithAuth(req, res, function(server) { + server.pushNotificationsUnsubscribe(req.params['token'], function(err, response) { + if (err) return returnError(err, res, req); + res.json(response); + }); + }); + }); this.app.use(opts.basePath || '/bws/api', router); diff --git a/lib/pushnotificationsservice.js b/lib/pushnotificationsservice.js index 8d8b81c..641cc92 100644 --- a/lib/pushnotificationsservice.js +++ b/lib/pushnotificationsservice.js @@ -341,7 +341,7 @@ PushNotificationsService.prototype._makeRequest = function(opts, cb) { var self = this; self.request({ - url: self.pushServerUrl, + url: self.pushServerUrl + '/send', method: 'POST', json: true, body: opts diff --git a/lib/server.js b/lib/server.js index fed64fe..fbb0dc7 100644 --- a/lib/server.js +++ b/lib/server.js @@ -3,6 +3,8 @@ var _ = require('lodash'); var $ = require('preconditions').singleton(); var async = require('async'); var log = require('npmlog'); +var config = require('../config'); + log.debug = log.verbose; log.disableColor(); var EmailValidator = require('email-validator'); @@ -24,6 +26,8 @@ var MessageBroker = require('./messagebroker'); var BlockchainExplorer = require('./blockchainexplorer'); var FiatRateService = require('./fiatrateservice'); +var request = require('request'); + var Model = require('./model'); var Wallet = Model.Wallet; @@ -80,6 +84,8 @@ WalletService.initialize = function(opts, cb) { lock = opts.lock || new Lock(opts.lockOpts); blockchainExplorer = opts.blockchainExplorer; blockchainExplorerOpts = opts.blockchainExplorerOpts; + if (opts.request) + request = opts.request; function initStorage(cb) { if (opts.storage) { @@ -644,8 +650,8 @@ WalletService.prototype.joinWallet = function(opts, cb) { } if (_.find(wallet.copayers, { - xPubKey: opts.xPubKey - })) return cb(Errors.COPAYER_IN_WALLET); + xPubKey: opts.xPubKey + })) return cb(Errors.COPAYER_IN_WALLET); if (wallet.copayers.length == wallet.n) return cb(Errors.WALLET_FULL); @@ -738,8 +744,8 @@ WalletService.prototype._canCreateAddress = function(ignoreMaxGap, cb) { isChange: true }), Defaults.MAX_MAIN_ADDRESS_GAP); if (latestAddresses.length < Defaults.MAX_MAIN_ADDRESS_GAP || _.any(latestAddresses, { - hasActivity: true - })) return cb(null, true); + hasActivity: true + })) return cb(null, true); var bc = self._getBlockchainExplorer(latestAddresses[0].network); var activityFound = false; @@ -2421,6 +2427,38 @@ WalletService.prototype.getFiatRate = function(opts, cb) { }); }; +WalletService.prototype.pushNotificationsSubscribe = function(opts, cb) { + if (!Utils.checkRequired(opts, ['token'])) + return cb(new ClientError('Required argument missing')); + + var self = this; + + opts.user = self.walletId + '$' + self.copayerId + '$' + opts.token; + + request({ + url: config.pushNotificationsOpts.pushServerUrl + '/subscribe', + method: 'POST', + json: true, + body: opts + }, function(err, response) { + return cb(err, response); + }); +}; + +WalletService.prototype.pushNotificationsUnsubscribe = function(token, cb) { + var self = this; + + request({ + url: config.pushNotificationsOpts.pushServerUrl + '/unsubscribe', + method: 'POST', + json: true, + body: { + user: self.walletId + '$' + self.copayerId + '$' + token + } + }, function(err, response) { + return cb(err, response); + }); +}; module.exports = WalletService; module.exports.ClientError = ClientError; diff --git a/test/integration/helpers.js b/test/integration/helpers.js index a89cb4d..99b43b9 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -60,7 +60,8 @@ helpers.beforeEach = function(cb) { blockchainExplorer = sinon.stub(); var opts = { storage: storage, - blockchainExplorer: blockchainExplorer + blockchainExplorer: blockchainExplorer, + request: sinon.stub() }; WalletService.initialize(opts, function() { return cb(opts); @@ -101,7 +102,7 @@ helpers.getAuthServer = function(copayerId, cb) { clientVersion: helpers.CLIENT_VERSION, }, function(err, server) { verifyStub.restore(); - if (err || !server) throw new Error('Could not login as copayerId ' + copayerId); + if (err || !server) throw new Error('Could not login as copayerId ' + copayerId + ' err: ' + err); return cb(server); }); }; diff --git a/test/integration/server.js b/test/integration/server.js index fa4c7b5..ff62e38 100644 --- a/test/integration/server.js +++ b/test/integration/server.js @@ -23,7 +23,7 @@ var WalletService = require('../../lib/server'); var TestData = require('../testdata'); var helpers = require('./helpers'); -var storage, blockchainExplorer; +var storage, blockchainExplorer, request; describe('Wallet service', function() { @@ -34,6 +34,7 @@ describe('Wallet service', function() { helpers.beforeEach(function(res) { storage = res.storage; blockchainExplorer = res.blockchainExplorer; + request = res.request; done(); }); }); @@ -5451,4 +5452,57 @@ describe('Wallet service', function() { }); }); }); + + describe('Subscribe/unsubscribe', function() { + var server, wallet; + beforeEach(function(done) { + helpers.createAndJoinWallet(2, 3, function(s, w) { + server = s; + wallet = w; + done(); + }); + }); + + it('should subscribe copayer to push notifications service', function(done) { + request.yields(); + helpers.getAuthServer(wallet.copayers[0].id, function(server) { + should.exist(server); + server.pushNotificationsSubscribe({ + token: 'DEVICE_TOKEN' + }, function(err, response) { + should.not.exist(err); + var calls = request.getCalls(); + calls.length.should.equal(1); + var args = _.map(calls, function(c) { + return c.args[0]; + }); + args[0].body.user.should.contain(wallet.copayers[0].id); + args[0].body.user.should.contain(wallet.id); + args[0].body.user.should.contain('DEVICE_TOKEN'); + done(); + }); + }); + }); + + it('should unsubscribe copayer to push notifications service', function(done) { + request.yields(); + helpers.getAuthServer(wallet.copayers[0].id, function(server) { + should.exist(server); + server.pushNotificationsUnsubscribe('DEVICE_TOKEN', function(err, response) { + should.not.exist(err); + var calls = request.getCalls(); + calls.length.should.equal(1); + var args = _.map(calls, function(c) { + return c.args[0]; + }); + + args[0].body.user.should.contain(wallet.copayers[0].id); + args[0].body.user.should.contain(wallet.id); + args[0].body.user.should.contain('DEVICE_TOKEN'); + done(); + }); + }); + }); + }); + });