Skip to content

Commit

Permalink
Fix freepasa phone number validation, lock screen fixes and logout bu…
Browse files Browse the repository at this point in the history
…tton
  • Loading branch information
bbedward committed Oct 22, 2019
1 parent d36153d commit 406f6f7
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 57 deletions.
209 changes: 157 additions & 52 deletions lib/ui/lockscreen/lock_screen.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import 'package:auto_size_text/auto_size_text.dart';
import 'package:blaise_wallet_flutter/appstate_container.dart';
import 'package:blaise_wallet_flutter/localization.dart';
import 'package:blaise_wallet_flutter/model/authentication_method.dart';
import 'package:blaise_wallet_flutter/service_locator.dart';
import 'package:blaise_wallet_flutter/ui/util/app_icons.dart';
import 'package:blaise_wallet_flutter/ui/util/routes.dart';
import 'package:blaise_wallet_flutter/ui/util/text_styles.dart';
import 'package:blaise_wallet_flutter/ui/widgets/overlay_dialog.dart';
import 'package:blaise_wallet_flutter/util/ui_util.dart';
import 'package:blaise_wallet_flutter/ui/widgets/buttons.dart';
import 'package:blaise_wallet_flutter/ui/widgets/pin_screen.dart';
Expand All @@ -28,16 +31,6 @@ class _LockScreenPageState extends State<LockScreenPage> {
.pushNamedAndRemoveUntil('/overview', (Route<dynamic> route) => false);
}

Widget _buildPinScreen(BuildContext context, String expectedPin) {
return PinScreen(
type: PinOverlayType.ENTER_PIN,
expectedPin: expectedPin,
description: AppLocalization.of(context).enterPINToUnlockParagraph,
onSuccess: (pin) {
_goHome();
});
}

String _formatCountDisplay(int count) {
if (count <= 60) {
// Seconds only
Expand Down Expand Up @@ -129,51 +122,56 @@ class _LockScreenPageState extends State<LockScreenPage> {
setState(() {
_lockedOut = false;
});
sl.get<SharedPrefsUtil>().getAuthMethod().then((authMethod) {
AuthUtil().hasBiometrics().then((hasBiometrics) {
if (authMethod.method == AuthMethod.BIOMETRICS && hasBiometrics) {
AuthenticationMethod authMethod = await sl.get<SharedPrefsUtil>().getAuthMethod();
bool hasBiometrics = await AuthUtil().hasBiometrics();
if (authMethod.method == AuthMethod.BIOMETRICS && hasBiometrics) {
setState(() {
_showUnlockButton = true;
});
bool authenticated = await AuthUtil().authenticateWithBiometrics(AppLocalization.of(context).authenticateToUnlockParagraph);
if (authenticated) {
_goHome();
} else {
setState(() {
_showUnlockButton = true;
});
}
} else {
// PIN authentication
String expectedPin = await sl.get<Vault>().getPin();
if (transitions) {
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) {
return PinScreen(
type: PinOverlayType.ENTER_PIN,
expectedPin: expectedPin,
description: AppLocalization.of(context).enterPINToUnlockParagraph,
onSuccess: (pin) {
_goHome();
});
}),
);
} else {
Navigator.of(context).push(
NoPushTransitionRoute(builder: (BuildContext context) {
return PinScreen(
type: PinOverlayType.ENTER_PIN,
expectedPin: expectedPin,
description: AppLocalization.of(context).enterPINToUnlockParagraph,
onSuccess: (pin) {
_goHome();
});
}),
);
}
Future.delayed(Duration(milliseconds: 200), () {
if (mounted) {
setState(() {
_showUnlockButton = true;
});
AuthUtil()
.authenticateWithBiometrics(
AppLocalization.of(context).authenticateToUnlockParagraph)
.then((authenticated) {
if (authenticated) {
_goHome();
} else {
setState(() {
_showUnlockButton = true;
});
}
});
} else {
// PIN Authentication
sl.get<Vault>().getPin().then((expectedPin) {
if (transitions) {
Navigator.of(context).push(
MaterialPageRoute(builder: (BuildContext context) {
return _buildPinScreen(context, expectedPin);
}),
);
} else {
Navigator.of(context).push(
NoPushTransitionRoute(builder: (BuildContext context) {
return _buildPinScreen(context, expectedPin);
}),
);
}
Future.delayed(Duration(milliseconds: 200), () {
if (mounted) {
setState(() {
_showUnlockButton = true;
});
}
});
});
}
});
});
}
}

@override
Expand All @@ -182,6 +180,52 @@ class _LockScreenPageState extends State<LockScreenPage> {
_authenticate();
}

void logoutPressed() {
showAppDialog(
context: context,
builder: (_) => DialogOverlay(
title: toUppercase(
AppLocalization.of(context).warningHeader, context),
warningStyle: true,
confirmButtonText: toUppercase(
AppLocalization.of(context).deletePrivateKeyAndLogoutButton,
context),
body: TextSpan(
children: formatLocalizedColorsDanger(context,
AppLocalization.of(context).logoutFirstDisclaimerParagraph),
),
onConfirm: () {
Navigator.of(context).pop();
showAppDialog(
context: context,
builder: (_) => DialogOverlay(
title: toUppercase(
AppLocalization.of(context).areYouSureHeader,
context),
warningStyle: true,
confirmButtonText: toUppercase(
AppLocalization.of(context).yesImSureButton,
context),
body: TextSpan(
children: formatLocalizedColorsDanger(
context,
AppLocalization.of(context)
.logoutSecondDisclaimerParagraph),
),
onConfirm: () {
// Handle logging out
walletState.reset();
sl.get<Vault>().deleteAll().then((_) {
sl.get<SharedPrefsUtil>().deleteAll().then((_) {
Navigator.of(context).pushNamedAndRemoveUntil(
'/', (Route<dynamic> route) => false);
});
});
}));
},
));
}

@override
Widget build(BuildContext context) {
// The main scaffold that holds everything
Expand Down Expand Up @@ -247,6 +291,67 @@ class _LockScreenPageState extends State<LockScreenPage> {
),
],
),
// Logout button
Container(
margin: EdgeInsetsDirectional.only(start: 5, top: 30),
alignment: Alignment.topLeft,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
FlatButton(
splashColor: StateContainer.of(context)
.curTheme
.backgroundPrimary30,
highlightColor: StateContainer.of(context)
.curTheme
.backgroundPrimary15,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8)),
onPressed: () {
logoutPressed();
},
padding: EdgeInsetsDirectional.fromSTEB(12, 8, 12, 8),
// A row for logout icon and text
child: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
// log out icon
Container(
margin: EdgeInsetsDirectional.only(end: 8),
child: Icon(AppIcons.logout,
size: 20,
color: StateContainer.of(context)
.curTheme
.backgroundPrimary),
),
// Support text
Container(
constraints: BoxConstraints(
maxWidth:
(MediaQuery.of(context).size.width -
100) *
0.4),
child: AutoSizeText(
AppLocalization.of(context).logoutHeader,
style: TextStyle(
fontWeight: FontWeight.w700,
fontSize: 14,
fontFamily: "Metropolis",
color: StateContainer.of(context).curTheme.backgroundPrimary
),
textAlign: TextAlign.center,
maxLines: 1,
minFontSize: 8,
stepGranularity: 0.1,
),
),
],
),
),
],
),
),
],
),
],
Expand Down Expand Up @@ -274,9 +379,9 @@ class _LockScreenPageState extends State<LockScreenPage> {
text: _lockedOut
? _countDownTxt
: AppLocalization.of(context).unlockButton,
onPressed: () {
onPressed: () async {
if (!_lockedOut) {
_authenticate(transitions: true);
await _authenticate(transitions: true);
}
},
disabled: _lockedOut,
Expand Down
2 changes: 1 addition & 1 deletion lib/ui/overview/get_free_account_sheet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ class _GetFreeAccountSheetState extends State<GetFreeAccountSheet> {
// Submit request, return request ID if successful
Future<String> onSubmitted() async {
// Validate phone number
if (_phoneNumberController.text.replaceAll(RegExp(r"[^0-9]"), "").length != 10) {
if (_phoneNumberController.text.replaceAll(RegExp(r"[^0-9]"), "").length < 5) {
if (mounted) {
setState(() {
_showPhoneError = true;
Expand Down
6 changes: 3 additions & 3 deletions lib/ui/util/formatters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ class PascalNameFormatter extends TextInputFormatter {
}

/// For phone numbers
/// Ensures no more than 10 digits
/// Ensures no more than 20 digits
/// Ensures hyphens only occur after a number
class PhoneNumberFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
// Check digit count, 10 is max
if (newValue.text.replaceAll(RegExp(r"[^0-9]"), "").length > 10) {
// Check digit count, 20 is max
if (newValue.text.replaceAll(RegExp(r"[^0-9]"), "").length > 20) {
return oldValue;
}
// Ensure only 1 hyphen after a number
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ description: A new Flutter project.
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.3+13
version: 1.0.4+14

environment:
sdk: ">=2.1.0 <3.0.0"
Expand Down

0 comments on commit 406f6f7

Please sign in to comment.