Skip to content

Commit

Permalink
Merge pull request #273 from AgoraDesk-LocalMonero/iteration_59
Browse files Browse the repository at this point in the history
Iteration 59
  • Loading branch information
sergdeus authored Mar 13, 2024
2 parents e08fbad + 1e7c171 commit 094e35d
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 81 deletions.
3 changes: 1 addition & 2 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
### Updates

1. Added new pairs for the price formula.
2. Improved login anti-DDoS protection.
1. Hotfix: push notifications token updates.

### About the attached app's

Expand Down
24 changes: 12 additions & 12 deletions ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 119;
CURRENT_PROJECT_VERSION = 121;
DEVELOPMENT_TEAM = G8RXR25D89;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
Expand All @@ -441,7 +441,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.22;
MARKETING_VERSION = 1.1.24;
PRODUCT_BUNDLE_IDENTIFIER = com.agoradesk.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -522,7 +522,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 119;
CURRENT_PROJECT_VERSION = 121;
DEVELOPMENT_TEAM = G8RXR25D89;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
Expand All @@ -531,7 +531,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.22;
MARKETING_VERSION = 1.1.24;
PRODUCT_BUNDLE_IDENTIFIER = com.agoradesk.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -611,7 +611,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 119;
CURRENT_PROJECT_VERSION = 121;
DEVELOPMENT_TEAM = G8RXR25D89;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
Expand All @@ -620,7 +620,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.22;
MARKETING_VERSION = 1.1.24;
PRODUCT_BUNDLE_IDENTIFIER = co.localmonero.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -703,7 +703,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 119;
CURRENT_PROJECT_VERSION = 121;
DEVELOPMENT_TEAM = G8RXR25D89;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
Expand All @@ -712,7 +712,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.22;
MARKETING_VERSION = 1.1.24;
PRODUCT_BUNDLE_IDENTIFIER = co.localmonero.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -791,7 +791,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 119;
CURRENT_PROJECT_VERSION = 121;
DEVELOPMENT_TEAM = G8RXR25D89;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
Expand All @@ -800,7 +800,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.22;
MARKETING_VERSION = 1.1.24;
PRODUCT_BUNDLE_IDENTIFIER = com.agoradesk.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down Expand Up @@ -878,7 +878,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 119;
CURRENT_PROJECT_VERSION = 121;
DEVELOPMENT_TEAM = G8RXR25D89;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
Expand All @@ -887,7 +887,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.1.22;
MARKETING_VERSION = 1.1.24;
PRODUCT_BUNDLE_IDENTIFIER = co.localmonero.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
Expand Down
50 changes: 27 additions & 23 deletions lib/core/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ class _AppState extends State<App>
);
return MediaQuery(
data: mq.copyWith(
textScaleFactor: mq.textScaleFactor > 1.4 ? 1.4 : mq.textScaleFactor,
textScaler: TextScaler.linear(mq.textScaleFactor > 1.4 ? 1.4 : mq.textScaleFactor),
),
child: KeyboardSizeProvider(
child: child!,
Expand Down Expand Up @@ -280,7 +280,7 @@ class _AppState extends State<App>
appState.proxyStatus = GetIt.I<AppParameters>().proxy;
await _afterConfigInit();
await _authService.init();
await _initLocalSettings();
await _initLocalSettings(false);
appState.initialized = true;
await Future.delayed(const Duration(milliseconds: 500));
_initStartRoute(uri: _initialUri);
Expand Down Expand Up @@ -370,7 +370,7 @@ class _AppState extends State<App>
case AuthState.loggedIn:
_pollingService.getBalances();
_initStartRoute();
_initLocalSettings();
_initLocalSettings(true);
break;
case AuthState.guest:
_initStartRoute();
Expand Down Expand Up @@ -405,7 +405,7 @@ class _AppState extends State<App>
router.removeLast();
}

void _addUniLinksRouts() {
void addUniLinksRouts() {
final PageRouteInfo<dynamic>? pageRoute = AppLinksHandler().parseUniLink(uri);
if (pageRoute != null) {
if (pageRoute.path == 'trades/trade') {
Expand All @@ -431,12 +431,12 @@ class _AppState extends State<App>

if (_authService.isAuthenticated != true && _authService.authState == AuthState.guest) {
newRoutes.add(const MainScreenRoute());
_addUniLinksRouts();
addUniLinksRouts();
} else if (_authService.isAuthenticated != true) {
newRoutes.add(
const WelcomeRoute(),
);
_addUniLinksRouts();
addUniLinksRouts();
} else if (_authService.showPinSetUp) {
newRoutes.add(const MainScreenRoute());
newRoutes.add(const PinCodeSetRoute());
Expand All @@ -446,7 +446,7 @@ class _AppState extends State<App>
if (GetIt.I<AppParameters>().appRanFromPush) {
newRoutes.add(TradeRoute(tradeId: GetIt.I<AppParameters>().tradeId!));
}
_addUniLinksRouts();
addUniLinksRouts();
if (appState.hasPinCode) {
newRoutes.add(const PinCodeCheckRoute());
}
Expand Down Expand Up @@ -496,8 +496,9 @@ class _AppState extends State<App>
void _initGlobalEvents() {
eventBus
..on<AnalyticsEvent>().listen((e) {
if (GetIt.I<AppParameters>().debugPrintIsOn)
if (GetIt.I<AppParameters>().debugPrintIsOn) {
debugPrint('[AnalyticEvent] event: ${e.event}, props: ${e.properties}');
}
if (appState.initialized) {
if (_plausible != null) {
_plausible!.event(name: e.event, referrer: e.properties.toString());
Expand Down Expand Up @@ -681,25 +682,28 @@ class _AppState extends State<App>
});
}

Future _initLocalSettings() async {
if (AppSharedPrefs().username == null || AppSharedPrefs().username!.isEmpty) {
// app runs first time, we should clean FlutterSecureStorage items
// https://stackoverflow.com/questions/57933021/flutter-how-do-i-delete-fluttersecurestorage-items-during-install-uninstall
token ??= await _secureStorage.read(SecureStorageKey.token);
if (token != null) {
final res = await _accountService.getMyself();
if (res.isRight && res.right.username != null) {
await AppSharedPrefs().setString(AppSharedPrefsKey.username, res.right.username);
appState.updateWith(notify: true);
_notificationsService.getToken();
} else {
_secureStorage.deleteAll();
}
Future _initLocalSettings(bool fromLoginState) async {
if (fromLoginState) await Future.delayed(const Duration(seconds: 2));

if (AppSharedPrefs().username?.isNotEmpty == true) {
await _notificationsService.getToken();
return;
}

// app runs first time, we should clean FlutterSecureStorage items
// https://stackoverflow.com/questions/57933021/flutter-how-do-i-delete-fluttersecurestorage-items-during-install-uninstall
token ??= await _secureStorage.read(SecureStorageKey.token);
if (token != null) {
final res = await _accountService.getMyself();
if (res.isRight && res.right.username != null) {
await AppSharedPrefs().setString(AppSharedPrefsKey.username, res.right.username);
appState.updateWith(notify: true);
_notificationsService.getToken();
} else {
_secureStorage.deleteAll();
}
} else {
_notificationsService.getToken();
_secureStorage.deleteAll();
}

appState.updateWith(
Expand Down
1 change: 1 addition & 0 deletions lib/core/app_parameters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -239,4 +239,5 @@ class AppParameters {
bool? proxy;
bool debugPrintIsOn = true;
bool polling = false;
bool get loggedIn => accessToken != null;
}
99 changes: 56 additions & 43 deletions lib/core/services/notifications/notifications_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -171,19 +171,18 @@ class NotificationsService with ForegroundMessagesMixin {

Future getToken() async {
// check that this is the time to update token
if (_tokenLoading) {
return;
}

if (!GetIt.I<AppParameters>().loggedIn) return;

if (_tokenLoading) return;

_tokenLoading = true;
bool update = true;
final DateTime? dateTokenSaved = AppSharedPrefs().fcmTokenSavedToApiDate;
if (dateTokenSaved != null) {
final days = DateTime.now().difference(dateTokenSaved).inDays;
if (days < _kPeriodCheckTokenUpdatesDays) {
update = false;
}
if (dateTokenSaved != null && DateTime.now().difference(dateTokenSaved).inDays < _kPeriodCheckTokenUpdatesDays) {
update = false;
}
if (fcm != null && appState.username.isNotEmpty && update) {
if (fcm != null && GetIt.I<AppParameters>().loggedIn && update) {
bool userPermission = true;
final settings = await fcm!.requestPermission(
alert: true,
Expand All @@ -198,7 +197,6 @@ class NotificationsService with ForegroundMessagesMixin {

if (userPermission) {
try {
await fcm!.deleteToken();
final token = await fcm!.getToken();
if (token != null) {
if (GetIt.I<AppParameters>().debugPrintIsOn) debugPrint('++++ FirebaseMessaging pushtoken created: $token');
Expand Down Expand Up @@ -228,58 +226,73 @@ class NotificationsService with ForegroundMessagesMixin {
);
return;
}
if (!_updating) {
_updating = true;
final oldToken = await secureStorage.read(SecureStorageKey.pushToken);

if (_updating) return;

_updating = true;
final oldToken = await secureStorage.read(SecureStorageKey.pushToken);
await Sentry.captureMessage(
{'pushTokenUpdateEvent:': '', 'oldTokenNotEqualnewToken:': oldToken != newToken}.toString(),
);
if (oldToken != newToken) {
await Sentry.captureMessage(
{'pushTokenUpdateEvent:': '', 'oldTokenNotEqualnewToken:': oldToken != newToken}.toString(),
{'pushTokenUpdateEvent:': '${GetIt.I<AppParameters>().loggedIn} '}.toString(),
);
if (oldToken != newToken && appState.username.isNotEmpty) {
late String deviceName;
var deviceData = <String, dynamic>{};
try {
if (Platform.isAndroid) {
deviceData = _readAndroidBuildData(await deviceInfoPlugin.androidInfo);
deviceName = deviceData['device'] ?? 'Android';
} else if (Platform.isIOS) {
deviceData = _readIosDeviceInfo(await deviceInfoPlugin.iosInfo);
deviceName = deviceData['name'] ?? 'iPhone';
}
} catch (e) {
deviceName = 'unknown';
}
final res = await _saveFcmTokenToApi(
DeviceModel(
token: newToken,
deviceName: deviceName,
type: 'FCM',
),
);
await Sentry.captureMessage(
{'SaveTokenEventResult': res}.toString(),
);
if (res) {
await secureStorage.write(SecureStorageKey.pushToken, newToken);
await AppSharedPrefs().setDate(AppSharedPrefsKey.fcmTokenSavedToApiDate, DateTime.now());
}
if (oldToken != newToken && GetIt.I<AppParameters>().loggedIn) {
late String deviceName;
var deviceData = <String, dynamic>{};
try {
if (Platform.isAndroid) {
deviceData = _readAndroidBuildData(await deviceInfoPlugin.androidInfo);
deviceName = deviceData['device'] ?? 'Android';
} else if (Platform.isIOS) {
deviceData = _readIosDeviceInfo(await deviceInfoPlugin.iosInfo);
deviceName = deviceData['name'] ?? 'iPhone';
}
} catch (e) {
deviceName = 'unknown';
}
final res = await _saveFcmTokenToApi(
DeviceModel(
token: newToken,
deviceName: deviceName,
type: 'FCM',
),
);
await Sentry.captureMessage(
{'SaveTokenEventResult': res}.toString(),
);
if (res) {
await secureStorage.write(SecureStorageKey.pushToken, newToken);
await AppSharedPrefs().setDate(AppSharedPrefsKey.fcmTokenSavedToApiDate, DateTime.now());
}
_updating = false;
}
_updating = false;
}

///
/// Add new FCM push token to API
///
Future<bool> _saveFcmTokenToApi(DeviceModel device) async {
try {
if (GetIt.I<AppParameters>().debugPrintIsOn) debugPrint('++++[_saveFcmTokenToApi] Save token to API $device');
final resp = await api.client.post(
'/push/registration',
data: device.toJson(),
);
if (resp.statusCode != 200) {
await Sentry.captureMessage(
{'SaveTokenEventError1': '${resp.statusCode} - ${resp.data}'}.toString(),
);
}
return resp.statusCode == 200;
} catch (e) {
ApiError apiError = ApiHelper.parseErrorToApiError(e, '[$runtimeType]');

await Sentry.captureMessage(
{'SaveTokenEventError2': e.toString()}.toString(),
);

if (apiError.message.containsKey('error_code')) {
// token already saved
if (apiError.message['error_code'] == 256) {
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: agoradesk
version: 1.1.22+119
version: 1.1.24+121
publish_to: none
description: Person-to-person platform to allow anyone to trade their local currency for cryptocurrency.
environment:
Expand Down

0 comments on commit 094e35d

Please sign in to comment.