mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-26 06:08:40 +01:00
Delete CakePay Auth-token if the API returns 401 (#3538)
* delete cakepay auth token on 401 * fix cakepay auth refresh * fix Cake Pay error handling
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
class CakePayUnauthorizedException implements Exception {
|
||||
const CakePayUnauthorizedException();
|
||||
|
||||
@override
|
||||
String toString() => 'Cake Pay session is no longer valid, please log in again.';
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/cake_pay_exceptions.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/models/cake_pay_card.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/models/cake_pay_order.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/widgets/cake_pay_alert_modal.dart';
|
||||
@@ -497,19 +498,37 @@ class CakePayBuyCardPage extends BasePage {
|
||||
}
|
||||
|
||||
Future<void> purchaseCard(BuildContext context) async {
|
||||
bool isLogged = await cakePayBuyCardViewModel.isUserLogged;
|
||||
if (!isLogged) {
|
||||
cakePayBuyCardViewModel.isSimulatingFlow = false;
|
||||
Navigator.of(context).pushNamed(Routes.cakePayWelcomePage);
|
||||
} else {
|
||||
try {
|
||||
await cakePayBuyCardViewModel.createOrder();
|
||||
} catch (_) {
|
||||
try {
|
||||
final isLogged = await cakePayBuyCardViewModel.isUserLogged;
|
||||
|
||||
if (!isLogged) {
|
||||
cakePayBuyCardViewModel.isSimulatingFlow = false;
|
||||
await cakePayBuyCardViewModel.logout();
|
||||
|
||||
if (context.mounted) {
|
||||
Navigator.of(context).pushNamed(Routes.cakePayWelcomePage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await cakePayBuyCardViewModel.createOrder();
|
||||
} on CakePayUnauthorizedException {
|
||||
cakePayBuyCardViewModel.isSimulatingFlow = false;
|
||||
|
||||
if (context.mounted) {
|
||||
Navigator.of(context).pushNamed(Routes.cakePayWelcomePage);
|
||||
}
|
||||
} catch (error) {
|
||||
cakePayBuyCardViewModel.isSimulatingFlow = false;
|
||||
_sendViewModel.state = FailureState(
|
||||
_sendViewModel.translateErrorMessage(
|
||||
error,
|
||||
cakePayBuyCardViewModel.walletType,
|
||||
_sendViewModel.wallet.currency,
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
cakePayBuyCardViewModel.isPurchasing = false;
|
||||
}
|
||||
cakePayBuyCardViewModel.isPurchasing = false;
|
||||
}
|
||||
|
||||
BuildContext? dialogContext;
|
||||
|
||||
@@ -477,11 +477,18 @@ class _ShopTabState extends State<_ShopTab> {
|
||||
if (i >= vendors.length) return const _Loading();
|
||||
final vendor = vendors[i];
|
||||
return CardItem(
|
||||
logoUrl: vendor.card?.cardImageUrl,
|
||||
title: vendor.name,
|
||||
subTitle: vendor.card?.description ?? '',
|
||||
onTap: () => Navigator.pushNamed(context, Routes.cakePayBuyCardPage,
|
||||
arguments: [vendor]));
|
||||
logoUrl: vendor.card?.cardImageUrl,
|
||||
title: vendor.name,
|
||||
subTitle: vendor.card?.description ?? '',
|
||||
onTap: () async {
|
||||
await Navigator.pushNamed(
|
||||
context,
|
||||
Routes.cakePayBuyCardPage,
|
||||
arguments: [vendor],
|
||||
);
|
||||
await viewModel.checkAuth();
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:cake_wallet/cake_pay/src/cake_pay_exceptions.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/models/cake_pay_order.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/models/cake_pay_user_credentials.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/models/cake_pay_vendor.dart';
|
||||
@@ -129,6 +130,10 @@ class CakePayApi {
|
||||
body: body,
|
||||
);
|
||||
|
||||
if (response.statusCode == 401) {
|
||||
throw const CakePayUnauthorizedException();
|
||||
}
|
||||
|
||||
if (response.statusCode == 201) {
|
||||
final data = json.decode(response.body) as Map<String, dynamic>;
|
||||
return CakePayOrder.fromMap(data);
|
||||
@@ -168,6 +173,10 @@ class CakePayApi {
|
||||
headers: headers,
|
||||
);
|
||||
|
||||
if (response.statusCode == 401) {
|
||||
throw const CakePayUnauthorizedException();
|
||||
}
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
}
|
||||
@@ -203,6 +212,10 @@ class CakePayApi {
|
||||
|
||||
printV('Response: ${response.statusCode}');
|
||||
|
||||
if (response.statusCode == 401) {
|
||||
throw const CakePayUnauthorizedException();
|
||||
}
|
||||
|
||||
if (response.statusCode != 200) {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/cake_pay/src/cake_pay_exceptions.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/services/cake_pay_api.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/models/cake_pay_order.dart';
|
||||
import 'package:cake_wallet/cake_pay/src/models/cake_pay_vendor.dart';
|
||||
@@ -95,29 +96,51 @@ class CakePayService {
|
||||
required bool confirmsTermsAgreed,
|
||||
}) async {
|
||||
final userEmail = (await secureStorage.read(key: cakePayEmailStorageKey))!;
|
||||
final token = (await secureStorage.read(key: cakePayUserTokenKey))!;
|
||||
return await cakePayApi.createOrder(
|
||||
apiKey: cakePayApiKey,
|
||||
cardId: cardId,
|
||||
price: price,
|
||||
quantity: quantity,
|
||||
token: token,
|
||||
userEmail: userEmail,
|
||||
confirmsNoVpn: confirmsNoVpn,
|
||||
confirmsVoidedRefund: confirmsVoidedRefund,
|
||||
confirmsTermsAgreed: confirmsTermsAgreed,
|
||||
return _withUserToken(
|
||||
(token) => cakePayApi.createOrder(
|
||||
apiKey: cakePayApiKey,
|
||||
cardId: cardId,
|
||||
price: price,
|
||||
quantity: quantity,
|
||||
token: token,
|
||||
userEmail: userEmail,
|
||||
confirmsNoVpn: confirmsNoVpn,
|
||||
confirmsVoidedRefund: confirmsVoidedRefund,
|
||||
confirmsTermsAgreed: confirmsTermsAgreed,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<CakePayOrder> findOrderById({required String orderId}) async {
|
||||
final token = (await secureStorage.read(key: cakePayUserTokenKey))!;
|
||||
return await cakePayApi.getOrderById(orderId: orderId, token: token);
|
||||
}
|
||||
Future<CakePayOrder> findOrderById({required String orderId}) => _withUserToken(
|
||||
(token) => cakePayApi.getOrderById(
|
||||
orderId: orderId,
|
||||
token: token,
|
||||
),
|
||||
);
|
||||
|
||||
///Simulate Purchase Gift Card
|
||||
Future<String> simulatePayment({required String orderId}) async {
|
||||
final token = (await secureStorage.read(key: cakePayUserTokenKey))!;
|
||||
return await cakePayApi.simulatePayment(
|
||||
CSRFToken: CSRFToken, authorization: authorization, token: token, orderId: orderId);
|
||||
Future<String> simulatePayment({required String orderId}) => _withUserToken(
|
||||
(token) => cakePayApi.simulatePayment(
|
||||
CSRFToken: CSRFToken,
|
||||
authorization: authorization,
|
||||
token: token,
|
||||
orderId: orderId,
|
||||
),
|
||||
);
|
||||
|
||||
/// Wrapper for requests with user token
|
||||
Future<T> _withUserToken<T>(Future<T> Function(String token) request) async {
|
||||
try {
|
||||
final token = await secureStorage.read(key: cakePayUserTokenKey) ?? '';
|
||||
|
||||
if (token.isEmpty) {
|
||||
throw const CakePayUnauthorizedException();
|
||||
}
|
||||
|
||||
return await request(token);
|
||||
} on CakePayUnauthorizedException {
|
||||
await logout();
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user