WIP - re-factor debit card to create a reusable bitpayService.
This commit is contained in:
parent
9b3a3aab9d
commit
4a6499d528
6 changed files with 464 additions and 169 deletions
|
|
@ -1,13 +1,13 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('copayApp.controllers').controller('bitpayCardController', function($scope, $timeout, $log, $state, lodash, bitpayCardService, moment, popupService, gettextCatalog, $ionicHistory) {
|
angular.module('copayApp.controllers').controller('bitpayCardController', function($scope, $timeout, $log, $state, lodash, bitpayCardService, moment, popupService, gettextCatalog, $ionicHistory, bitpayService) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var runningBalance;
|
var runningBalance;
|
||||||
$scope.dateRange = {
|
$scope.dateRange = {
|
||||||
value: 'last30Days'
|
value: 'last30Days'
|
||||||
};
|
};
|
||||||
$scope.network = bitpayCardService.getEnvironment();
|
$scope.network = bitpayService.getEnvironment();
|
||||||
|
|
||||||
var updateHistoryFromCache = function(cb) {
|
var updateHistoryFromCache = function(cb) {
|
||||||
bitpayCardService.getBitpayDebitCardsHistory($scope.cardId, function(err, data) {
|
bitpayCardService.getBitpayDebitCardsHistory($scope.cardId, function(err, data) {
|
||||||
|
|
|
||||||
|
|
@ -1,64 +1,48 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
angular.module('copayApp.controllers').controller('bitpayCardIntroController', function($scope, $log, $state, $ionicHistory, storageService, externalLinkService, bitpayCardService, gettextCatalog, popupService, appIdentityService) {
|
angular.module('copayApp.controllers').controller('bitpayCardIntroController', function($scope, $log, $state, $ionicHistory, storageService, externalLinkService, bitpayCardService, gettextCatalog, popupService, appIdentityService, bitpayService) {
|
||||||
|
|
||||||
var checkOtp = function(obj, cb) {
|
|
||||||
if (obj.otp) {
|
|
||||||
var msg = gettextCatalog.getString('Enter Two Factor for BitPay Card');
|
|
||||||
popupService.showPrompt(null, msg, null, function(res) {
|
|
||||||
cb(res);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
cb();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$scope.$on("$ionicView.beforeEnter", function(event, data) {
|
$scope.$on("$ionicView.beforeEnter", function(event, data) {
|
||||||
|
|
||||||
if (data.stateParams && data.stateParams.secret) {
|
if (data.stateParams && data.stateParams.secret) {
|
||||||
var obj = {
|
var pairData = {
|
||||||
secret: data.stateParams.secret,
|
secret: data.stateParams.secret,
|
||||||
email: data.stateParams.email,
|
email: data.stateParams.email,
|
||||||
otp: data.stateParams.otp
|
otp: data.stateParams.otp
|
||||||
};
|
};
|
||||||
checkOtp(obj, function(otp) {
|
var pairingReason = gettextCatalog.getString('add your BitPay Visa<sup>®</sup> card(s)');
|
||||||
obj.otp = otp;
|
bitpayService.pair(pairData, pairingReason, function(err, paired, apiContext) {
|
||||||
bitpayCardService.bitAuthPair(obj, function(err, data) {
|
if (err) {
|
||||||
if (err) {
|
popupService.showAlert(gettextCatalog.getString('Error'), err);
|
||||||
popupService.showAlert(gettextCatalog.getString('Error'), err);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
if (paired) {
|
||||||
var title = gettextCatalog.getString('Add BitPay Card Account?');
|
bitpayCardService.fetchBitpayDebitCards(apiContext, function(err, data) {
|
||||||
var msg = gettextCatalog.getString('Would you like to add this account ({{email}}) to your wallet?', {
|
if (err) {
|
||||||
email: obj.email
|
popupService.showAlert(gettextCatalog.getString('Error'), err);
|
||||||
});
|
return;
|
||||||
var ok = gettextCatalog.getString('Add Account');
|
|
||||||
var cancel = gettextCatalog.getString('Go back');
|
|
||||||
popupService.showConfirm(title, msg, ok, cancel, function(res) {
|
|
||||||
if (res) {
|
|
||||||
// Set flag for nextStep
|
|
||||||
storageService.setNextStep('BitpayCard', 'true', function(err) {});
|
|
||||||
// Save data
|
|
||||||
bitpayCardService.setBitpayDebitCards(data, function(err) {
|
|
||||||
if (err) return;
|
|
||||||
$ionicHistory.nextViewOptions({
|
|
||||||
disableAnimate: true
|
|
||||||
});
|
|
||||||
$state.go('tabs.home').then(function() {
|
|
||||||
if (data.cards[0]) {
|
|
||||||
$state.transitionTo('tabs.bitpayCard', {
|
|
||||||
id: data.cards[0].id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
// Set flag for nextStep
|
||||||
|
storageService.setNextStep('BitpayCard', 'true', function(err) {});
|
||||||
|
// Save data
|
||||||
|
bitpayCardService.setBitpayDebitCards(data, function(err) {
|
||||||
|
if (err) return;
|
||||||
|
$ionicHistory.nextViewOptions({
|
||||||
|
disableAnimate: true
|
||||||
|
});
|
||||||
|
$state.go('tabs.home').then(function() {
|
||||||
|
if (data.cards[0]) {
|
||||||
|
$state.transitionTo('tabs.bitpayCard', {
|
||||||
|
id: data.cards[0].id
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
appIdentityService.getIdentity(bitpayCardService.getEnvironment(), function(err, appIdentity) {
|
appIdentityService.getIdentity(bitpayService.getEnvironment(), function(err, appIdentity) {
|
||||||
if (err) popupService.showAlert(null, err);
|
if (err) popupService.showAlert(null, err);
|
||||||
else $log.info('App identity: Ok.');
|
else $log.info('App identity: OK');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
angular.module('copayApp.services').factory('bitpayCardService', function($http, $log, lodash, storageService, bitauthService, platformInfo, moment, appIdentityService) {
|
angular.module('copayApp.services').factory('bitpayCardService', function($log, $rootScope, lodash, storageService, bitauthService, platformInfo, moment, appIdentityService, bitpayService) {
|
||||||
var root = {};
|
var root = {};
|
||||||
var BITPAY_CARD_NETWORK = 'livenet';
|
|
||||||
var BITPAY_CARD_API_URL = BITPAY_CARD_NETWORK == 'livenet' ? 'https://bitpay.com' : 'https://test.bitpay.com';
|
|
||||||
|
|
||||||
var _setError = function(msg, e) {
|
var _setError = function(msg, e) {
|
||||||
$log.error(msg);
|
$log.error(msg);
|
||||||
|
|
@ -11,64 +9,6 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
return error;
|
return error;
|
||||||
};
|
};
|
||||||
|
|
||||||
var _get = function(endpoint) {
|
|
||||||
return {
|
|
||||||
method: 'GET',
|
|
||||||
url: BITPAY_CARD_API_URL + endpoint,
|
|
||||||
headers: {
|
|
||||||
'content-type': 'application/json'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var _post = function(endpoint, json, appIdentity) {
|
|
||||||
var dataToSign = BITPAY_CARD_API_URL + endpoint + JSON.stringify(json);
|
|
||||||
var signedData = bitauthService.sign(dataToSign, appIdentity.priv);
|
|
||||||
|
|
||||||
return {
|
|
||||||
method: 'POST',
|
|
||||||
url: BITPAY_CARD_API_URL + endpoint,
|
|
||||||
headers: {
|
|
||||||
'content-type': 'application/json',
|
|
||||||
'x-identity': appIdentity.pub,
|
|
||||||
'x-signature': signedData
|
|
||||||
},
|
|
||||||
data: json
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
var _postAuth = function(endpoint, json, appIdentity) {
|
|
||||||
json['params'].signature = bitauthService.sign(JSON.stringify(json.params), appIdentity.priv);
|
|
||||||
json['params'].pubkey = appIdentity.pub;
|
|
||||||
json['params'] = JSON.stringify(json.params);
|
|
||||||
|
|
||||||
var ret = {
|
|
||||||
method: 'POST',
|
|
||||||
url: BITPAY_CARD_API_URL + endpoint,
|
|
||||||
headers: {
|
|
||||||
'content-type': 'application/json'
|
|
||||||
},
|
|
||||||
data: json
|
|
||||||
};
|
|
||||||
|
|
||||||
$log.debug('post auth:' + JSON.stringify(ret));
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
var _afterBitAuthSuccess = function(token, obj, appIdentity, cb) {
|
|
||||||
var json = {
|
|
||||||
method: 'getDebitCards'
|
|
||||||
};
|
|
||||||
// Get Debit Cards
|
|
||||||
$http(_post('/api/v2/' + token, json, appIdentity)).then(function(data) {
|
|
||||||
if (data && data.data.error) return cb(data.data.error);
|
|
||||||
$log.info('BitPay Get Debit Cards: SUCCESS');
|
|
||||||
return cb(data.data.error, {token: token, cards: data.data.data, email: obj.email});
|
|
||||||
}, function(data) {
|
|
||||||
return cb(_setError('BitPay Card Error: Get Debit Cards', data));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
var _processTransactions = function(invoices, history) {
|
var _processTransactions = function(invoices, history) {
|
||||||
invoices = invoices || [];
|
invoices = invoices || [];
|
||||||
for (var i = 0; i < invoices.length; i++) {
|
for (var i = 0; i < invoices.length; i++) {
|
||||||
|
|
@ -99,35 +39,17 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
return history;
|
return history;
|
||||||
};
|
};
|
||||||
|
|
||||||
root.getEnvironment = function() {
|
root.fetchBitpayDebitCards = function(apiContext, cb) {
|
||||||
return BITPAY_CARD_NETWORK;
|
|
||||||
};
|
|
||||||
|
|
||||||
root.bitAuthPair = function(obj, cb) {
|
|
||||||
var deviceName = 'Unknown device';
|
|
||||||
if (platformInfo.isNW) {
|
|
||||||
deviceName = require('os').platform();
|
|
||||||
} else if (platformInfo.isCordova) {
|
|
||||||
deviceName = device.model;
|
|
||||||
}
|
|
||||||
var json = {
|
var json = {
|
||||||
method: 'createToken',
|
method: 'getDebitCards'
|
||||||
params: {
|
|
||||||
secret: obj.secret,
|
|
||||||
version: 2,
|
|
||||||
deviceName: deviceName,
|
|
||||||
code: obj.otp
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
appIdentityService.getIdentity(root.getEnvironment(), function(err, appIdentity) {
|
// Get Debit Cards
|
||||||
if (err) return cb(err);
|
bitpayService.post('/api/v2/' + apiContext.token, json, function(data) {
|
||||||
$http(_postAuth('/api/v2/', json, appIdentity)).then(function(data) {
|
if (data && data.data.error) return cb(data.data.error);
|
||||||
if (data && data.data.error) return cb(data.data.error);
|
$log.info('BitPay Get Debit Cards: SUCCESS');
|
||||||
$log.info('BitPay Card BitAuth Create Token: SUCCESS');
|
return cb(data.data.error, {token: apiContext.token, cards: data.data.data, email: apiContext.pairData.email});
|
||||||
_afterBitAuthSuccess(data.data.data, obj, appIdentity, cb);
|
}, function(data) {
|
||||||
}, function(data) {
|
return cb(_setError('BitPay Card Error: Get Debit Cards', data));
|
||||||
return cb(_setError('BitPay Card Error Create Token: BitAuth', data));
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -138,14 +60,14 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
method: 'getInvoiceHistory',
|
method: 'getInvoiceHistory',
|
||||||
params: JSON.stringify(params)
|
params: JSON.stringify(params)
|
||||||
};
|
};
|
||||||
appIdentityService.getIdentity(root.getEnvironment(), function(err, appIdentity) {
|
appIdentityService.getIdentity(bitpayService.getEnvironment(), function(err, appIdentity) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
root.getBitpayDebitCards(function(err, data) {
|
root.getBitpayDebitCards(function(err, data) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
var card = lodash.find(data, {id : cardId});
|
var card = lodash.find(data, {id : cardId});
|
||||||
if (!card) return cb(_setError('Card not found'));
|
if (!card) return cb(_setError('Card not found'));
|
||||||
// Get invoices
|
// Get invoices
|
||||||
$http(_post('/api/v2/' + card.token, json, appIdentity)).then(function(data) {
|
bitpayService.post('/api/v2/' + card.token, json, function(data) {
|
||||||
$log.info('BitPay Get Invoices: SUCCESS');
|
$log.info('BitPay Get Invoices: SUCCESS');
|
||||||
invoices = data.data.data || [];
|
invoices = data.data.data || [];
|
||||||
if (lodash.isEmpty(invoices)) $log.info('No invoices');
|
if (lodash.isEmpty(invoices)) $log.info('No invoices');
|
||||||
|
|
@ -154,7 +76,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
params: JSON.stringify(params)
|
params: JSON.stringify(params)
|
||||||
};
|
};
|
||||||
// Get transactions list
|
// Get transactions list
|
||||||
$http(_post('/api/v2/' + card.token, json, appIdentity)).then(function(data) {
|
bitpayService.post('/api/v2/' + card.token, json, function(data) {
|
||||||
$log.info('BitPay Get Transactions: SUCCESS');
|
$log.info('BitPay Get Transactions: SUCCESS');
|
||||||
transactions = data.data.data || {};
|
transactions = data.data.data || {};
|
||||||
transactions['txs'] = _processTransactions(invoices, transactions.transactionList);
|
transactions['txs'] = _processTransactions(invoices, transactions.transactionList);
|
||||||
|
|
@ -163,7 +85,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
return cb(_setError('BitPay Card Error: Get Transactions', data));
|
return cb(_setError('BitPay Card Error: Get Transactions', data));
|
||||||
});
|
});
|
||||||
}, function(data) {
|
}, function(data) {
|
||||||
return cb(_setError('BitPay Card Error: Get Invoices', data));
|
return cb(_setError('BitPay Card Error: Get Invoices', data));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -175,13 +97,13 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
method: 'generateTopUpInvoice',
|
method: 'generateTopUpInvoice',
|
||||||
params: JSON.stringify(params)
|
params: JSON.stringify(params)
|
||||||
};
|
};
|
||||||
appIdentityService.getIdentity(root.getEnvironment(), function(err, appIdentity) {
|
appIdentityService.getIdentity(bitpayService.getEnvironment(), function(err, appIdentity) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
root.getBitpayDebitCards(function(err, data) {
|
root.getBitpayDebitCards(function(err, data) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
var card = lodash.find(data, {id : cardId});
|
var card = lodash.find(data, {id : cardId});
|
||||||
if (!card) return cb(_setError('Card not found'));
|
if (!card) return cb(_setError('Card not found'));
|
||||||
$http(_post('/api/v2/' + card.token, json, appIdentity)).then(function(data) {
|
bitpayService.post('/api/v2/' + card.token, json, function(data) {
|
||||||
$log.info('BitPay TopUp: SUCCESS');
|
$log.info('BitPay TopUp: SUCCESS');
|
||||||
if(data.data.error) {
|
if(data.data.error) {
|
||||||
return cb(data.data.error);
|
return cb(data.data.error);
|
||||||
|
|
@ -196,7 +118,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
};
|
};
|
||||||
|
|
||||||
root.getInvoice = function(id, cb) {
|
root.getInvoice = function(id, cb) {
|
||||||
$http(_get('/invoices/' + id)).then(function(data) {
|
bitpayService.get('/invoices/' + id, function(data) {
|
||||||
$log.info('BitPay Get Invoice: SUCCESS');
|
$log.info('BitPay Get Invoice: SUCCESS');
|
||||||
return cb(data.data.error, data.data.data);
|
return cb(data.data.error, data.data.data);
|
||||||
}, function(data) {
|
}, function(data) {
|
||||||
|
|
@ -205,7 +127,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
};
|
};
|
||||||
|
|
||||||
root.getBitpayDebitCards = function(cb) {
|
root.getBitpayDebitCards = function(cb) {
|
||||||
storageService.getBitpayDebitCards(BITPAY_CARD_NETWORK, function(err, data) {
|
storageService.getBitpayDebitCards(bitpayService.getEnvironment(), function(err, data) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (lodash.isString(data)) {
|
if (lodash.isString(data)) {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
|
|
@ -217,14 +139,14 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
|
|
||||||
root.setBitpayDebitCards = function(data, cb) {
|
root.setBitpayDebitCards = function(data, cb) {
|
||||||
data = JSON.stringify(data);
|
data = JSON.stringify(data);
|
||||||
storageService.setBitpayDebitCards(BITPAY_CARD_NETWORK, data, function(err) {
|
storageService.setBitpayDebitCards(bitpayService.getEnvironment(), data, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
return cb();
|
return cb();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
root.getBitpayDebitCardsHistory = function(cardId, cb) {
|
root.getBitpayDebitCardsHistory = function(cardId, cb) {
|
||||||
storageService.getBitpayDebitCardsHistory(BITPAY_CARD_NETWORK, function(err, data) {
|
storageService.getBitpayDebitCardsHistory(bitpayService.getEnvironment(), function(err, data) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
if (lodash.isString(data)) {
|
if (lodash.isString(data)) {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
|
|
@ -236,7 +158,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
};
|
};
|
||||||
|
|
||||||
root.setBitpayDebitCardsHistory = function(cardId, data, opts, cb) {
|
root.setBitpayDebitCardsHistory = function(cardId, data, opts, cb) {
|
||||||
storageService.getBitpayDebitCardsHistory(BITPAY_CARD_NETWORK, function(err, oldData) {
|
storageService.getBitpayDebitCardsHistory(bitpayService.getEnvironment(), function(err, oldData) {
|
||||||
if (lodash.isString(oldData)) {
|
if (lodash.isString(oldData)) {
|
||||||
oldData = JSON.parse(oldData);
|
oldData = JSON.parse(oldData);
|
||||||
}
|
}
|
||||||
|
|
@ -250,19 +172,19 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
}
|
}
|
||||||
inv = JSON.stringify(inv);
|
inv = JSON.stringify(inv);
|
||||||
|
|
||||||
storageService.setBitpayDebitCardsHistory(BITPAY_CARD_NETWORK, inv, function(err) {
|
storageService.setBitpayDebitCardsHistory(bitpayService.getEnvironment(), inv, function(err) {
|
||||||
return cb(err);
|
return cb(err);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
root.remove = function(card, cb) {
|
root.remove = function(card, cb) {
|
||||||
storageService.removeBitpayDebitCard(BITPAY_CARD_NETWORK, card, function(err) {
|
storageService.removeBitpayDebitCard(bitpayService.getEnvironment(), card, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
$log.error('Error removing BitPay debit card: ' + err);
|
$log.error('Error removing BitPay debit card: ' + err);
|
||||||
// Continue, try to remove/cleanup card history
|
// Continue, try to remove/cleanup card history
|
||||||
}
|
}
|
||||||
storageService.removeBitpayDebitCardHistory(BITPAY_CARD_NETWORK, card, function(err) {
|
storageService.removeBitpayDebitCardHistory(bitpayService.getEnvironment(), card, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
$log.error('Error removing BitPay debit card transaction history: ' + err);
|
$log.error('Error removing BitPay debit card transaction history: ' + err);
|
||||||
return cb(err);
|
return cb(err);
|
||||||
|
|
@ -274,7 +196,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
|
||||||
};
|
};
|
||||||
|
|
||||||
root.getRates = function(currency, cb) {
|
root.getRates = function(currency, cb) {
|
||||||
$http(_get('/rates/' + currency)).then(function(data) {
|
bitpayService.get('/rates/' + currency, function(data) {
|
||||||
$log.info('BitPay Get Rates: SUCCESS');
|
$log.info('BitPay Get Rates: SUCCESS');
|
||||||
return cb(data.data.error, data.data.data);
|
return cb(data.data.error, data.data.data);
|
||||||
}, function(data) {
|
}, function(data) {
|
||||||
|
|
|
||||||
193
src/js/services/bitpayService.js
Normal file
193
src/js/services/bitpayService.js
Normal file
|
|
@ -0,0 +1,193 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular.module('copayApp.services').factory('bitpayService', function($log, $http, platformInfo, appIdentityService, bitauthService, storageService, gettextCatalog, popupService) {
|
||||||
|
var root = {};
|
||||||
|
|
||||||
|
var NETWORK = 'livenet';
|
||||||
|
var BITPAY_API_URL = NETWORK == 'livenet' ? 'https://bitpay.com' : 'https://test.bitpay.com';
|
||||||
|
|
||||||
|
root.getEnvironment = function() {
|
||||||
|
return NETWORK;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pair this app with the bitpay server using the specified pairing data.
|
||||||
|
* An app identity will be created if one does not already exist.
|
||||||
|
* Pairing data is provided by an input URI provided by the bitpay server.
|
||||||
|
*
|
||||||
|
* pairData - data needed to complete the pairing process
|
||||||
|
* {
|
||||||
|
* secret: shared pairing secret
|
||||||
|
* email: email address associated with bitpay account
|
||||||
|
* otp: two-factor one-time use password
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* pairingReason - text string to be embedded into popup message. If `null` then the reason
|
||||||
|
* message is not shown to the UI.
|
||||||
|
* "To {{reason}} you must pair this app with your BitPay account ({{email}})."
|
||||||
|
*
|
||||||
|
* cb - callback after completion
|
||||||
|
* callback(err, paired, apiContext)
|
||||||
|
*
|
||||||
|
* err - something unexpected happened which prevented the pairing
|
||||||
|
*
|
||||||
|
* paired - boolean indicating whether the pairing was compledted by the user
|
||||||
|
*
|
||||||
|
* apiContext - the context needed for making future api calls
|
||||||
|
* {
|
||||||
|
* token: api token for use in future calls
|
||||||
|
* pairData: the input pair data
|
||||||
|
* appIdentity: the identity of this app
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
root.pair = function(pairData, pairingReason, cb) {
|
||||||
|
checkOtp(pairData, function(otp) {
|
||||||
|
pairData.otp = otp;
|
||||||
|
var deviceName = 'Unknown device';
|
||||||
|
if (platformInfo.isNW) {
|
||||||
|
deviceName = require('os').platform();
|
||||||
|
} else if (platformInfo.isCordova) {
|
||||||
|
deviceName = device.model;
|
||||||
|
}
|
||||||
|
var json = {
|
||||||
|
method: 'createToken',
|
||||||
|
params: {
|
||||||
|
secret: pairData.secret,
|
||||||
|
version: 2,
|
||||||
|
deviceName: deviceName,
|
||||||
|
code: pairData.otp
|
||||||
|
}
|
||||||
|
};
|
||||||
|
appIdentityService.getIdentity(root.getEnvironment(), function(err, appIdentity) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
$http(_postAuth('/api/v2/', json, appIdentity)).then(function(data) {
|
||||||
|
if (data && data.data.error) return cb(data.data.error);
|
||||||
|
$log.info('BitPay service BitAuth create token: SUCCESS');
|
||||||
|
var title = gettextCatalog.getString('Add BitPay Account?');
|
||||||
|
var msgDetail = 'Add this BitPay account ({{email}})?';
|
||||||
|
if (pairingReason) {
|
||||||
|
msgDetail = 'To {{reason}} you must first add your BitPay account.<br/><br/>{{email}}';
|
||||||
|
}
|
||||||
|
var msg = gettextCatalog.getString(msgDetail, {
|
||||||
|
reason: pairingReason,
|
||||||
|
email: pairData.email
|
||||||
|
});
|
||||||
|
var ok = gettextCatalog.getString('Add Account');
|
||||||
|
var cancel = gettextCatalog.getString('Go back');
|
||||||
|
popupService.showConfirm(title, msg, ok, cancel, function(res) {
|
||||||
|
if (res) {
|
||||||
|
var acctData = {
|
||||||
|
token: data.data.data,
|
||||||
|
email: pairData.email
|
||||||
|
};
|
||||||
|
setBitpayAccount(acctData, function(err) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
return cb(null, true, {
|
||||||
|
token: acctData.token,
|
||||||
|
pairData: pairData,
|
||||||
|
appIdentity: appIdentity
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$log.info('User cancelled BitPay pairing process');
|
||||||
|
return cb(null, false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, function(data) {
|
||||||
|
return cb(_setError('BitPay service BitAuth create token: ERROR ', data));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
root.get = function(endpoint, successCallback, errorCallback) {
|
||||||
|
$http(_get(endpoint)).then(function(data) {
|
||||||
|
successCallback(data);
|
||||||
|
}, function(data) {
|
||||||
|
errorCallback(data);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
root.post = function(endpoint, json, successCallback, errorCallback) {
|
||||||
|
appIdentityService.getIdentity(NETWORK, function(err, appIdentity) {
|
||||||
|
if (err) return errorCallback(err);
|
||||||
|
$http(_post(endpoint, json, appIdentity)).then(function(data) {
|
||||||
|
successCallback(data);
|
||||||
|
}, function(data) {
|
||||||
|
errorCallback(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var checkOtp = function(pairData, cb) {
|
||||||
|
if (pairData.otp) {
|
||||||
|
var msg = gettextCatalog.getString('Enter Two Factor for your BitPay account');
|
||||||
|
popupService.showPrompt(null, msg, null, function(res) {
|
||||||
|
cb(res);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var setBitpayAccount = function(accountData, cb) {
|
||||||
|
var data = JSON.stringify(accountData);
|
||||||
|
storageService.setBitpayAccount(root.getEnvironment(), data, function(err) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
return cb();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _get = function(endpoint) {
|
||||||
|
return {
|
||||||
|
method: 'GET',
|
||||||
|
url: BITPAY_API_URL + endpoint,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var _post = function(endpoint, json, appIdentity) {
|
||||||
|
var dataToSign = BITPAY_API_URL + endpoint + JSON.stringify(json);
|
||||||
|
var signedData = bitauthService.sign(dataToSign, appIdentity.priv);
|
||||||
|
|
||||||
|
return {
|
||||||
|
method: 'POST',
|
||||||
|
url: BITPAY_API_URL + endpoint,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
'x-identity': appIdentity.pub,
|
||||||
|
'x-signature': signedData
|
||||||
|
},
|
||||||
|
data: json
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
var _postAuth = function(endpoint, json, appIdentity) {
|
||||||
|
json['params'].signature = bitauthService.sign(JSON.stringify(json.params), appIdentity.priv);
|
||||||
|
json['params'].pubkey = appIdentity.pub;
|
||||||
|
json['params'] = JSON.stringify(json.params);
|
||||||
|
|
||||||
|
var ret = {
|
||||||
|
method: 'POST',
|
||||||
|
url: BITPAY_API_URL + endpoint,
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json'
|
||||||
|
},
|
||||||
|
data: json
|
||||||
|
};
|
||||||
|
|
||||||
|
$log.debug('post auth:' + JSON.stringify(ret));
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
var _setError = function(msg, e) {
|
||||||
|
$log.error(msg);
|
||||||
|
var error = (e && e.data && e.data.error) ? e.data.error : msg;
|
||||||
|
return error;
|
||||||
|
};
|
||||||
|
|
||||||
|
return root;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
@ -130,20 +130,27 @@ angular.module('copayApp.services').factory('incomingData', function($log, $stat
|
||||||
url: data
|
url: data
|
||||||
});
|
});
|
||||||
|
|
||||||
// BitPayCard Authentication
|
// BitPay Authentication
|
||||||
} else if (data && data.indexOf($window.appConfig.name + '://') === 0) {
|
} else if (data && data.indexOf($window.appConfig.name + '://') === 0) {
|
||||||
var secret = getParameterByName('secret', data);
|
var secret = getParameterByName('secret', data);
|
||||||
var email = getParameterByName('email', data);
|
var email = getParameterByName('email', data);
|
||||||
var otp = getParameterByName('otp', data);
|
var otp = getParameterByName('otp', data);
|
||||||
|
var reason = getParameterByName('r', data);
|
||||||
|
|
||||||
$state.go('tabs.home', {}, {
|
$state.go('tabs.home', {}, {
|
||||||
'reload': true,
|
'reload': true,
|
||||||
'notify': $state.current.name == 'tabs.home' ? false : true
|
'notify': $state.current.name == 'tabs.home' ? false : true
|
||||||
}).then(function() {
|
}).then(function() {
|
||||||
$state.transitionTo('tabs.bitpayCardIntro', {
|
switch (reason) {
|
||||||
secret: secret,
|
default:
|
||||||
email: email,
|
case '0': /* For BitPay card binding */
|
||||||
otp: otp
|
$state.transitionTo('tabs.bitpayCardIntro', {
|
||||||
});
|
secret: secret,
|
||||||
|
email: email,
|
||||||
|
otp: otp
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,14 @@ angular.module('copayApp.services')
|
||||||
//
|
//
|
||||||
// UPGRADING STORAGE
|
// UPGRADING STORAGE
|
||||||
//
|
//
|
||||||
|
// TODO: prior to upgrading storage a backup of all storage should be captured and made available
|
||||||
|
// for export for recovery/debugging.
|
||||||
|
//
|
||||||
|
// Upgraders are executed in numerical order per the '##_' object key prefix. Each upgrader will run.
|
||||||
|
// Each upgrader should detect storage configuraton and fail-safe; no upgrader should damage the ability
|
||||||
|
// of another to function properly (in order). Each upgrader should upgrade storage incrementally; storage
|
||||||
|
// upgrade is not complete until all upgraders have run.
|
||||||
|
//
|
||||||
// 1. Write a function to upgrade the desired storage key(s). The function should have the protocol:
|
// 1. Write a function to upgrade the desired storage key(s). The function should have the protocol:
|
||||||
//
|
//
|
||||||
// _upgrade_x(key, network, cb), where:
|
// _upgrade_x(key, network, cb), where:
|
||||||
|
|
@ -91,12 +99,15 @@ angular.module('copayApp.services')
|
||||||
// when a storage key is involved in multiple upgraders as well as predicte the order in which upgrades
|
// when a storage key is involved in multiple upgraders as well as predicte the order in which upgrades
|
||||||
// occur the `_upgrader` object key should be prefixed with '##_' (e.g., '01_') to create a unique and
|
// occur the `_upgrader` object key should be prefixed with '##_' (e.g., '01_') to create a unique and
|
||||||
// sortable name. This format is interpreted by the _upgrade() function.
|
// sortable name. This format is interpreted by the _upgrade() function.
|
||||||
//
|
//
|
||||||
// Upgraders are executed in numerical order per the '##_' object key prefix.
|
// 3. Any dependency functions called by upgraders should be copied/factored out and remain unchanged as
|
||||||
|
// long as the upgrader remains in effect. By convention the dependency function is prefixed by '##_' to
|
||||||
|
// match the upgrader key.
|
||||||
//
|
//
|
||||||
var _upgraders = {
|
var _upgraders = {
|
||||||
'00_bitpayDebitCards' : _upgrade_bitpayDebitCards, // 2016-11: Upgrade bitpayDebitCards-x to bitpayAccounts-x
|
'00_bitpayDebitCards' : _upgrade_bitpayDebitCards, // 2016-11: Upgrade bitpayDebitCards-x to bitpayAccounts-x
|
||||||
'01_bitpayCardCredentials' : _upgrade_bitpayCardCredentials // 2016-11: Upgrade bitpayCardCredentials-x to appIdentity-x
|
'01_bitpayCardCredentials' : _upgrade_bitpayCardCredentials, // 2016-11: Upgrade bitpayCardCredentials-x to appIdentity-x
|
||||||
|
'02_bitpayAccounts' : _upgrade_bitpayAccounts // 2016-12: Reorganize the object
|
||||||
};
|
};
|
||||||
|
|
||||||
function _upgrade_bitpayDebitCards(key, network, cb) {
|
function _upgrade_bitpayDebitCards(key, network, cb) {
|
||||||
|
|
@ -109,7 +120,7 @@ angular.module('copayApp.services')
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
}
|
}
|
||||||
data = data || {};
|
data = data || {};
|
||||||
root.setBitpayDebitCards(network, data, function(err) {
|
_00_setBitpayDebitCards(network, data, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
storage.remove(key, function() {
|
storage.remove(key, function() {
|
||||||
cb(null, 'replaced with \'bitpayAccounts\'');
|
cb(null, 'replaced with \'bitpayAccounts\'');
|
||||||
|
|
@ -131,7 +142,7 @@ angular.module('copayApp.services')
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
}
|
}
|
||||||
data = data || {};
|
data = data || {};
|
||||||
root.setAppIdentity(network, data, function(err) {
|
_01_setAppIdentity(network, data, function(err) {
|
||||||
if (err) return cb(err);
|
if (err) return cb(err);
|
||||||
storage.remove(key, function() {
|
storage.remove(key, function() {
|
||||||
cb(null, 'replaced with \'appIdentity\'');
|
cb(null, 'replaced with \'appIdentity\'');
|
||||||
|
|
@ -142,6 +153,105 @@ angular.module('copayApp.services')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function _upgrade_bitpayAccounts(key, network, cb) {
|
||||||
|
key += '-' + network;
|
||||||
|
storage.get(key, function(err, data) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
if (lodash.isString(data)) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
}
|
||||||
|
data = data || {};
|
||||||
|
var upgraded = '';
|
||||||
|
Object.keys(data).forEach(function(key) {
|
||||||
|
// Keys are account emails
|
||||||
|
if (!data[key]['bitpayApi-' + network].token) {
|
||||||
|
// Needs upgrade
|
||||||
|
upgraded += ' ' + key;
|
||||||
|
var acctData = {
|
||||||
|
token: data[key]['bitpayDebitCards-' + network].token,
|
||||||
|
email: key
|
||||||
|
};
|
||||||
|
_02_setBitpayAccount(network, data, function(err) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
|
||||||
|
_02_setBitpayDebitCards(network, data[key]['bitpayDebitCards-' + network], function(err) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (upgraded.length > 0) {
|
||||||
|
cb(null, 'upgraded \'bitpayAccounts\':' + upgraded);
|
||||||
|
} else {
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// UPGRADER DEPENDENCIES
|
||||||
|
// These functions remain as long as the upgrader remains in effect.
|
||||||
|
//
|
||||||
|
var _00_setBitpayDebitCards = function(network, data, cb) {
|
||||||
|
if (lodash.isString(data)) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
}
|
||||||
|
data = data || {};
|
||||||
|
if (lodash.isEmpty(data) || !data.email) return cb('No card(s) to set');
|
||||||
|
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
if (lodash.isString(bitpayAccounts)) {
|
||||||
|
bitpayAccounts = JSON.parse(bitpayAccounts);
|
||||||
|
}
|
||||||
|
bitpayAccounts = bitpayAccounts || {};
|
||||||
|
bitpayAccounts[data.email] = bitpayAccounts[data.email] || {};
|
||||||
|
bitpayAccounts[data.email]['bitpayDebitCards-' + network] = data;
|
||||||
|
storage.set('bitpayAccounts-' + network, JSON.stringify(bitpayAccounts), cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _01_setAppIdentity = function(network, data, cb) {
|
||||||
|
storage.set('appIdentity-' + network, data, cb);
|
||||||
|
};
|
||||||
|
|
||||||
|
var _02_setBitpayAccount = function(network, data, cb) {
|
||||||
|
if (lodash.isString(data)) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
}
|
||||||
|
data = data || {};
|
||||||
|
if (lodash.isEmpty(data) || !data.email) return cb('No account to set');
|
||||||
|
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
if (lodash.isString(bitpayAccounts)) {
|
||||||
|
bitpayAccounts = JSON.parse(bitpayAccounts);
|
||||||
|
}
|
||||||
|
bitpayAccounts = bitpayAccounts || {};
|
||||||
|
bitpayAccounts[data.email] = bitpayAccounts[data.email] || {};
|
||||||
|
bitpayAccounts[data.email]['bitpayApi-' + network] = bitpayAccounts[data.email]['bitpayApi-' + network] || {};
|
||||||
|
bitpayAccounts[data.email]['bitpayApi-' + network].token = data.token;
|
||||||
|
storage.set('bitpayAccounts-' + network, JSON.stringify(bitpayAccounts), cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var _02_setBitpayDebitCards = function(network, data, cb) {
|
||||||
|
if (lodash.isString(data)) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
}
|
||||||
|
data = data || {};
|
||||||
|
if (lodash.isEmpty(data) || !data.email) return cb('No card(s) to set');
|
||||||
|
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
if (lodash.isString(bitpayAccounts)) {
|
||||||
|
bitpayAccounts = JSON.parse(bitpayAccounts);
|
||||||
|
}
|
||||||
|
bitpayAccounts = bitpayAccounts || {};
|
||||||
|
bitpayAccounts[data.email] = bitpayAccounts[data.email] || {};
|
||||||
|
bitpayAccounts[data.email]['bitpayDebitCards-' + network] = data.cards;
|
||||||
|
storage.set('bitpayAccounts-' + network, JSON.stringify(bitpayAccounts), cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
@ -467,6 +577,16 @@ angular.module('copayApp.services')
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// data: {
|
||||||
|
// cards: [
|
||||||
|
// eid: card id
|
||||||
|
// id: card id
|
||||||
|
// lastFourDigits: card number
|
||||||
|
// token: card token
|
||||||
|
// ]
|
||||||
|
// email: account email
|
||||||
|
// token: account token
|
||||||
|
// }
|
||||||
root.setBitpayDebitCards = function(network, data, cb) {
|
root.setBitpayDebitCards = function(network, data, cb) {
|
||||||
if (lodash.isString(data)) {
|
if (lodash.isString(data)) {
|
||||||
data = JSON.parse(data);
|
data = JSON.parse(data);
|
||||||
|
|
@ -480,11 +600,19 @@ angular.module('copayApp.services')
|
||||||
}
|
}
|
||||||
bitpayAccounts = bitpayAccounts || {};
|
bitpayAccounts = bitpayAccounts || {};
|
||||||
bitpayAccounts[data.email] = bitpayAccounts[data.email] || {};
|
bitpayAccounts[data.email] = bitpayAccounts[data.email] || {};
|
||||||
bitpayAccounts[data.email]['bitpayDebitCards-' + network] = data;
|
bitpayAccounts[data.email]['bitpayDebitCards-' + network] = data.cards;
|
||||||
storage.set('bitpayAccounts-' + network, JSON.stringify(bitpayAccounts), cb);
|
storage.set('bitpayAccounts-' + network, JSON.stringify(bitpayAccounts), cb);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// cb(err, cards)
|
||||||
|
// cards: [
|
||||||
|
// eid: card id
|
||||||
|
// id: card id
|
||||||
|
// lastFourDigits: card number
|
||||||
|
// token: card token
|
||||||
|
// email: account email
|
||||||
|
// ]
|
||||||
root.getBitpayDebitCards = function(network, cb) {
|
root.getBitpayDebitCards = function(network, cb) {
|
||||||
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
||||||
if (lodash.isString(bitpayAccounts)) {
|
if (lodash.isString(bitpayAccounts)) {
|
||||||
|
|
@ -494,7 +622,7 @@ angular.module('copayApp.services')
|
||||||
var cards = [];
|
var cards = [];
|
||||||
Object.keys(bitpayAccounts).forEach(function(email) {
|
Object.keys(bitpayAccounts).forEach(function(email) {
|
||||||
// For the UI, add the account email to the card object.
|
// For the UI, add the account email to the card object.
|
||||||
var acctCards = bitpayAccounts[email]['bitpayDebitCards-' + network].cards;
|
var acctCards = bitpayAccounts[email]['bitpayDebitCards-' + network] || [];
|
||||||
for (var i = 0; i < acctCards.length; i++) {
|
for (var i = 0; i < acctCards.length; i++) {
|
||||||
acctCards[i].email = email;
|
acctCards[i].email = email;
|
||||||
}
|
}
|
||||||
|
|
@ -504,6 +632,12 @@ angular.module('copayApp.services')
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// card: {
|
||||||
|
// eid: card id
|
||||||
|
// id: card id
|
||||||
|
// lastFourDigits: card number
|
||||||
|
// token: card token
|
||||||
|
// }
|
||||||
root.removeBitpayDebitCard = function(network, card, cb) {
|
root.removeBitpayDebitCard = function(network, card, cb) {
|
||||||
if (lodash.isString(card)) {
|
if (lodash.isString(card)) {
|
||||||
card = JSON.parse(card);
|
card = JSON.parse(card);
|
||||||
|
|
@ -516,12 +650,14 @@ angular.module('copayApp.services')
|
||||||
bitpayAccounts = JSON.parse(bitpayAccounts);
|
bitpayAccounts = JSON.parse(bitpayAccounts);
|
||||||
}
|
}
|
||||||
bitpayAccounts = bitpayAccounts || {};
|
bitpayAccounts = bitpayAccounts || {};
|
||||||
Object.keys(bitpayAccounts).forEach(function(userId) {
|
Object.keys(bitpayAccounts).forEach(function(email) {
|
||||||
var data = bitpayAccounts[userId]['bitpayDebitCards-' + network];
|
var data = bitpayAccounts[email]['bitpayDebitCards-' + network];
|
||||||
var newCards = lodash.reject(data.cards, {
|
var newCards = lodash.reject(data, {
|
||||||
'eid': card.eid
|
'eid': card.eid
|
||||||
});
|
});
|
||||||
|
data = {};
|
||||||
data.cards = newCards;
|
data.cards = newCards;
|
||||||
|
data.email = email;
|
||||||
root.setBitpayDebitCards(network, data, function(err) {
|
root.setBitpayDebitCards(network, data, function(err) {
|
||||||
if (err) cb(err);
|
if (err) cb(err);
|
||||||
// If there are no more cards in storage then re-enable the next step entry.
|
// If there are no more cards in storage then re-enable the next step entry.
|
||||||
|
|
@ -538,6 +674,59 @@ angular.module('copayApp.services')
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// data: {
|
||||||
|
// email: account email
|
||||||
|
// token: account token
|
||||||
|
// }
|
||||||
|
root.setBitpayAccount = function(network, data, cb) {
|
||||||
|
if (lodash.isString(data)) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
}
|
||||||
|
data = data || {};
|
||||||
|
if (lodash.isEmpty(data) || !data.email) return cb('No account to set');
|
||||||
|
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
if (lodash.isString(bitpayAccounts)) {
|
||||||
|
bitpayAccounts = JSON.parse(bitpayAccounts);
|
||||||
|
}
|
||||||
|
bitpayAccounts = bitpayAccounts || {};
|
||||||
|
bitpayAccounts[data.email] = bitpayAccounts[data.email] || {};
|
||||||
|
bitpayAccounts[data.email]['bitpayApi-' + network] = bitpayAccounts[data.email]['bitpayApi-' + network] || {};
|
||||||
|
bitpayAccounts[data.email]['bitpayApi-' + network].token = data.token;
|
||||||
|
storage.set('bitpayAccounts-' + network, JSON.stringify(bitpayAccounts), cb);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// cb(err, accounts)
|
||||||
|
// accounts: {
|
||||||
|
// email_1: {
|
||||||
|
// bitpayApi-<network>: {
|
||||||
|
// token: account token
|
||||||
|
// }
|
||||||
|
// bitpayDebitCards-<network>: {
|
||||||
|
// <card-data>
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ...
|
||||||
|
// email_n: {
|
||||||
|
// bitpayApi-<network>: {
|
||||||
|
// token: account token
|
||||||
|
// }
|
||||||
|
// bitpayDebitCards-<network>: {
|
||||||
|
// <card-data>
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
root.getBitpayAccounts = function(network, cb) {
|
||||||
|
storage.get('bitpayAccounts-' + network, function(err, bitpayAccounts) {
|
||||||
|
if (err) return cb(err);
|
||||||
|
if (lodash.isString(bitpayAccounts)) {
|
||||||
|
bitpayAccounts = JSON.parse(bitpayAccounts);
|
||||||
|
}
|
||||||
|
cb(err, bitpayAccounts);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
root.setAppIdentity = function(network, data, cb) {
|
root.setAppIdentity = function(network, data, cb) {
|
||||||
storage.set('appIdentity-' + network, data, cb);
|
storage.set('appIdentity-' + network, data, cb);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue