Minor bug fixes. New bitauth method for getting token

This commit is contained in:
Gustavo Maximiliano Cortez 2016-10-13 17:49:48 -03:00
parent 8ee033436f
commit c916babe25
No known key found for this signature in database
GPG Key ID: 15EDAD8D9F2EB1AF
6 changed files with 105 additions and 69 deletions

View File

@ -3,7 +3,7 @@
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) {
var self = this; var self = this;
$scope.dateRange = 'last30Days'; $scope.dateRange = { value: 'last30Days'};
$scope.network = bitpayCardService.getEnvironment(); $scope.network = bitpayCardService.getEnvironment();
var getFromCache = function(cb) { var getFromCache = function(cb) {
@ -42,7 +42,7 @@ angular.module('copayApp.controllers').controller('bitpayCardController', functi
}; };
this.update = function() { this.update = function() {
var dateRange = setDateRange($scope.dateRange); var dateRange = setDateRange($scope.dateRange.value);
$scope.loadingHistory = true; $scope.loadingHistory = true;
bitpayCardService.getHistory($scope.cardId, dateRange, function(err, history) { bitpayCardService.getHistory($scope.cardId, dateRange, function(err, history) {
@ -53,39 +53,49 @@ angular.module('copayApp.controllers').controller('bitpayCardController', functi
return; return;
} }
self.bitpayCardTransactionHistory = history.txs; var txs = lodash.clone(history.txs);
for (var i = 0; i < txs.length; i++) {
txs[i] = _getMerchantInfo(txs[i]);
txs[i].icon = _getIconName(txs[i]);
txs[i].desc = _processDescription(txs[i]);
}
self.bitpayCardTransactionHistory = txs;
self.bitpayCardCurrentBalance = history.currentCardBalance; self.bitpayCardCurrentBalance = history.currentCardBalance;
var cacheHistory = { if ($scope.dateRange.value == 'last30Days') {
balance: self.bitpayCardCurrentBalance, $log.debug('BitPay Card: store cache history');
transactions: self.bitpayCardTransactionHistory var cacheHistory = {
}; balance: history.currentCardBalance,
bitpayCardService.setBitpayDebitCardsHistory($scope.cardId, cacheHistory, {}, function(err) { transactions: history.txs
if (err) $log.error(err); };
$scope.historyCached = true; bitpayCardService.setBitpayDebitCardsHistory($scope.cardId, cacheHistory, {}, function(err) {
}); if (err) $log.error(err);
$scope.historyCached = true;
});
}
$timeout(function() { $timeout(function() {
$scope.$apply(); $scope.$apply();
}); });
}); });
}; };
this.getMerchantInfo = function(tx) { var _getMerchantInfo = function(tx) {
var bpTranCodes = bitpayCardService.bpTranCodes; var bpTranCodes = bitpayCardService.bpTranCodes;
lodash.keys(bpTranCodes).forEach(function(code) { lodash.keys(bpTranCodes).forEach(function(code) {
if (tx.type.indexOf(code) === 0) { if (tx.type.indexOf(code) === 0) {
lodash.assign(tx, bpTranCodes[code]); lodash.assign(tx, bpTranCodes[code]);
} }
}); });
return tx;
}; };
this.getIconName = function(tx) { var _getIconName = function(tx) {
var icon = tx.mcc || tx.category || null; var icon = tx.mcc || tx.category || null;
if (!icon) return 'default'; if (!icon) return 'default';
return bitpayCardService.iconMap[icon]; return bitpayCardService.iconMap[icon];
}; };
this.processDescription = function(tx) { var _processDescription = function(tx) {
if (lodash.isArray(tx.description)) { if (lodash.isArray(tx.description)) {
return tx.description[0]; return tx.description[0];
} }

View File

@ -374,11 +374,22 @@ angular.module('copayApp.controllers').controller('confirmController', function(
}; };
$scope.onSuccessConfirm = function() { $scope.onSuccessConfirm = function() {
var previousView = $ionicHistory.viewHistory().backView && $ionicHistory.viewHistory().backView.stateName;
var fromBitPayCard = previousView.match(/tabs.bitpayCard/) ? true : false;
$ionicHistory.nextViewOptions({ $ionicHistory.nextViewOptions({
disableAnimate: true disableAnimate: true
}); });
$ionicHistory.removeBackView();
$scope.sendStatus = ''; $scope.sendStatus = '';
$state.go('tabs.send');
if (fromBitPayCard) {
$timeout(function() {
$state.transitionTo('tabs.bitpayCard', {id: $stateParams.cardId});
}, 100);
} else {
$state.go('tabs.send');
}
}; };
function publishAndSign(wallet, txp, onSendStatusChange) { function publishAndSign(wallet, txp, onSendStatusChange) {

View File

@ -203,11 +203,19 @@ angular.module('copayApp.controllers').controller('tabHomeController',
var bitpayCardCache = function() { var bitpayCardCache = function() {
bitpayCardService.getBitpayDebitCards(function(err, data) { bitpayCardService.getBitpayDebitCards(function(err, data) {
if (err || lodash.isEmpty(data)) return; if (err) return;
if (lodash.isEmpty(data)) {
$scope.bitpayCards = null;
return;
}
$scope.bitpayCards = data.cards; $scope.bitpayCards = data.cards;
}); });
bitpayCardService.getBitpayDebitCardsHistory(null, function(err, data) { bitpayCardService.getBitpayDebitCardsHistory(null, function(err, data) {
if (err || lodash.isEmpty(data)) return; if (err) return;
if (lodash.isEmpty(data)) {
$scope.cardsHistory = null;
return;
}
$scope.cardsHistory = data; $scope.cardsHistory = data;
}); });
}; };

View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
angular.module('copayApp.services').factory('bitpayCardService', function($http, $log, lodash, storageService, bitauthService, platformInfo) { angular.module('copayApp.services').factory('bitpayCardService', function($http, $log, lodash, storageService, bitauthService, platformInfo, moment) {
var root = {}; var root = {};
var BITPAY_CARD_NETWORK = 'livenet'; var BITPAY_CARD_NETWORK = 'livenet';
var BITPAY_CARD_API_URL = BITPAY_CARD_NETWORK == 'livenet' ? 'https://bitpay.com' : 'https://test.bitpay.com'; var BITPAY_CARD_API_URL = BITPAY_CARD_NETWORK == 'livenet' ? 'https://bitpay.com' : 'https://test.bitpay.com';
@ -47,7 +47,6 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
}; };
}; };
var _post = function(endpoint, json, credentials) { var _post = function(endpoint, json, credentials) {
var dataToSign = BITPAY_CARD_API_URL + endpoint + JSON.stringify(json); var dataToSign = BITPAY_CARD_API_URL + endpoint + JSON.stringify(json);
var signedData = bitauthService.sign(dataToSign, credentials.priv); var signedData = bitauthService.sign(dataToSign, credentials.priv);
@ -64,26 +63,32 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
}; };
}; };
var _afterBitAuthSuccess = function(obj, credentials, cb) { var _postAuth = function(endpoint, json, credentials) {
var json = { json['params'].signature = bitauthService.sign(JSON.stringify(json.params), credentials.priv);
method: 'getTokens' json['params'].pubkey = credentials.pub;
json['params'] = JSON.stringify(json.params);
return {
method: 'POST',
url: BITPAY_CARD_API_URL + endpoint,
headers: {
'content-type': 'application/json'
},
data: json
}; };
// Get tokens };
$http(_post('/api/v2/', json, credentials)).then(function(data) {
$log.info('BitPay Get Tokens: SUCCESS'); var _afterBitAuthSuccess = function(token, obj, credentials, cb) {
var token = lodash.find(data.data.data, 'visaUser'); var json = {
if (lodash.isEmpty(token)) return cb(_setError('No token for visaUser')); method: 'getDebitCards'
token = token.visaUser; };
json['method'] = 'getDebitCards'; // Get Debit Cards
// Get Debit Cards $http(_post('/api/v2/' + token, json, credentials)).then(function(data) {
$http(_post('/api/v2/' + token, json, credentials)).then(function(data) { if (data && data.data.error) return cb(data.data.error);
$log.info('BitPay Get Debit Cards: SUCCESS'); $log.info('BitPay Get Debit Cards: SUCCESS');
return cb(data.data.error, {token: token, cards: data.data.data, email: obj.email}); 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));
});
}, function(data) { }, function(data) {
return cb(_setError('BitPay Card Error: Get Token', data)); return cb(_setError('BitPay Card Error: Get Debit Cards', data));
}); });
}; };
@ -96,16 +101,22 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
matched = true; matched = true;
} }
} }
if (!matched && ['paid', 'confirmed', 'complete'].indexOf(invoices[i].status) > -1) { var isInvoiceLessThanOneDayOld = moment() < moment(new Date(invoices[i].invoiceTime)).add(1, 'day');
if (!matched && isInvoiceLessThanOneDayOld) {
var isInvoiceUnderpaid = invoices[i].exceptionStatus === 'paidPartial';
history.unshift({ if(['paid', 'confirmed', 'complete'].indexOf(invoices[i].status) >= 0
timestamp: invoices[i].invoiceTime, || (invoices[i].status === 'invalid' || isInvoiceUnderpaid)) {
description: invoices[i].itemDesc,
amount: invoices[i].price, history.unshift({
type: '00611 = Client Funded Deposit', timestamp: new Date(invoices[i].invoiceTime),
pending: true, description: invoices[i].itemDesc,
status: invoices[i].status amount: invoices[i].price,
}); type: '00611 = Client Funded Deposit',
pending: true,
status: invoices[i].status
});
}
} }
} }
return history; return history;
@ -139,11 +150,12 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
}; };
_getCredentials(function(err, credentials) { _getCredentials(function(err, credentials) {
if (err) return cb(err); if (err) return cb(err);
$http(_post('/api/v2/', json, credentials)).then(function(data) { $http(_postAuth('/api/v2/', json, credentials)).then(function(data) {
$log.info('BitPay Card BitAuth: SUCCESS'); if (data && data.data.error) return cb(data.data.error);
_afterBitAuthSuccess(obj, credentials, cb); $log.info('BitPay Card BitAuth Create Token: SUCCESS');
_afterBitAuthSuccess(data.data.data, obj, credentials, cb);
}, function(data) { }, function(data) {
return cb(_setError('BitPay Card Error: BitAuth', data)); return cb(_setError('BitPay Card Error Create Token: BitAuth', data));
}); });
}); });
}; };
@ -164,7 +176,7 @@ angular.module('copayApp.services').factory('bitpayCardService', function($http,
// Get invoices // Get invoices
$http(_post('/api/v2/' + card.token, json, credentials)).then(function(data) { $http(_post('/api/v2/' + card.token, json, credentials)).then(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');
json = { json = {
method: 'getTransactionHistory', method: 'getTransactionHistory',

View File

@ -21,7 +21,7 @@
<div ng-if="bitpayCard.bitpayCardCurrentBalance" ng-click="bitpayCard.update()"> <div ng-if="bitpayCard.bitpayCardCurrentBalance" ng-click="bitpayCard.update()">
<div class="size-36 m20b">${{bitpayCard.bitpayCardCurrentBalance}}</div> <div class="size-36 m20b">${{bitpayCard.bitpayCardCurrentBalance}}</div>
<a class="button button-positive button-small" ui-sref="tabs.bitpayCard.amount({'cardId': cardId, 'toName': 'BitPay Card'})"> <a class="button button-positive button-small" ui-sref="tabs.bitpayCard.amount({'cardId': cardId, 'toName': 'BitPay Card'})">
<i class="icon ion-ios-plus-empty"></i> {{'Add Funds'|translate}} {{'Add Funds'|translate}}
</a> </a>
</div> </div>
<div ng-if="!bitpayCard.bitpayCardCurrentBalance" class="m10t"> <div ng-if="!bitpayCard.bitpayCardCurrentBalance" class="m10t">
@ -45,20 +45,19 @@
<h4>Your BitPay Card is ready. Add funds to your card to start using your card at stores and ATMs worldwide.</h4> <h4>Your BitPay Card is ready. Add funds to your card to start using your card at stores and ATMs worldwide.</h4>
</div> </div>
<div class="list" ng-if="bitpayCard.bitpayCardTransactionHistory[0] && !error" ng-init="cardTxs = bitpayCard.bitpayCardTransactionHistory"> <div class="list" ng-if="bitpayCard.bitpayCardTransactionHistory[0] && !error">
<div class="item item-divider"> <div class="item item-divider">
<select class="select-style" ng-model="dateRange" ng-change="bitpayCard.update(dateRange)"> <select class="select-style" ng-model="dateRange.value" ng-change="bitpayCard.update()">
<option value="last30Days">Recent Activity</option> <option value="last30Days">Recent Activity</option>
<option value="lastMonth">Last Month</option> <option value="lastMonth">Last Month</option>
<option value="all">All Activity</option> <option value="all">All Activity</option>
</select> </select>
</div> </div>
<div <div
ng-repeat="tx in cardTxs | orderBy: ['pending','-timestamp']" ng-repeat="tx in bitpayCard.bitpayCardTransactionHistory | orderBy: ['pending','-timestamp']"
class="item row" class="item row">
ng-init="bitpayCard.getMerchantInfo(tx)"> <div class="col col-10">
<div class="col col-10" ng-init="icon = bitpayCard.getIconName(tx)"> <img class="m5t" ng-src="img/mcc-icons/{{tx.icon}}.svg" width="22">
<img class="m5t" ng-src="img/mcc-icons/{{icon}}.svg" width="22">
</div> </div>
<div class="col"> <div class="col">
@ -69,10 +68,8 @@
{{tx.merchant.city}}, {{tx.merchant.state}} {{tx.merchant.city}}, {{tx.merchant.state}}
</div> </div>
</div> </div>
<div <div class="col size-12">
ng-init="desc = bitpayCard.processDescription(tx)" {{tx.desc}}
class="col size-12">
{{desc}}
</div> </div>
<div class="col"> <div class="col">
<img ng-show="!tx.pending" ng-src="img/check.svg" width="14"> <img ng-show="!tx.pending" ng-src="img/check.svg" width="14">
@ -85,7 +82,8 @@
'text-gray': tx.amount.indexOf('-') == -1 && tx.pending}"> 'text-gray': tx.amount.indexOf('-') == -1 && tx.pending}">
{{tx.amount | currency:'$':2 }} {{tx.amount | currency:'$':2 }}
</div> </div>
<time>{{tx.timestamp | amTimeAgo}}</time> <time ng-if="!tx.pending">{{tx.timestamp | amCalendar}}</time>
<span ng-if="tx.pending" class="tu" translate>Pending</span>
</div> </div>
</div> </div>
</div> </div>

View File

@ -25,11 +25,8 @@
<span class="payment-proposal-to" copy-to-clipboard="toAddress"> <span class="payment-proposal-to" copy-to-clipboard="toAddress">
<img ng-if="!cardId" src="img/icon-bitcoin-small.svg"> <img ng-if="!cardId" src="img/icon-bitcoin-small.svg">
<img ng-if="cardId" src="img/icon-card.svg" width="34"> <img ng-if="cardId" src="img/icon-card.svg" width="34">
<i ng-if="cardId" class="icon big-icon-svg"> <span ng-if="toName">{{toName}}</span>
<div class="bg icon-bitpay-card"></div> <contact ng-if="!toName" class="ellipsis" address="{{toAddress}}">{{toAddress}}</contact>
</i>
<span ng-show="toName">{{toName}}</span>
<contact class="ellipsis" address="{{toAddress}}">{{toAddress}}</contact>
<div ng-show="_paypro" ng-click="openPPModal(_paypro)"> <div ng-show="_paypro" ng-click="openPPModal(_paypro)">
<i ng-show="_paypro.verified && _paypro.caTrusted" class="ion-locked" style="color:green"></i> <i ng-show="_paypro.verified && _paypro.caTrusted" class="ion-locked" style="color:green"></i>
<i ng-show="!_paypro.caTrusted" class="ion-unlocked" style="color:red"></i> <i ng-show="!_paypro.caTrusted" class="ion-unlocked" style="color:red"></i>