2FA reset via SMS

This commit is contained in:
Hillel Coren 2022-11-07 18:01:28 +02:00
parent aa486ab314
commit 00b979c731
3 changed files with 155 additions and 63 deletions

View File

@ -77,6 +77,7 @@ class _LoginState extends State<LoginView> {
bool _createAccount = false; bool _createAccount = false;
bool _recoverPassword = false; bool _recoverPassword = false;
bool _disable2FA = false;
bool _termsChecked = false; bool _termsChecked = false;
bool _privacyChecked = false; bool _privacyChecked = false;
@ -235,6 +236,7 @@ class _LoginState extends State<LoginView> {
_loginError = ''; _loginError = '';
if (_recoverPassword) { if (_recoverPassword) {
_recoverPassword = false; _recoverPassword = false;
_disable2FA = false;
_buttonController.reset(); _buttonController.reset();
showDialog<MessageDialog>( showDialog<MessageDialog>(
context: context, context: context,
@ -269,6 +271,14 @@ class _LoginState extends State<LoginView> {
url: url, url: url,
secret: _isSelfHosted ? _secretController.text : '', secret: _isSelfHosted ? _secretController.text : '',
); );
} else if (_disable2FA) {
viewModel.onDisable2FAPressed(
context,
completer,
email: _emailController.text,
url: url,
secret: _isSelfHosted ? _secretController.text : '',
);
} else { } else {
viewModel.onLoginPressed( viewModel.onLoginPressed(
context, context,
@ -599,24 +609,29 @@ class _LoginState extends State<LoginView> {
), ),
SizedBox(width: 10), SizedBox(width: 10),
Text( Text(
_recoverPassword _disable2FA
? localization.recoverPassword ? localization.disable2fa
: _createAccount : _recoverPassword
? (_loginType == LOGIN_TYPE_EMAIL ? localization.recoverPassword
? localization.emailSignUp : _createAccount
: _loginType == ? (_loginType ==
LOGIN_TYPE_MICROSOFT LOGIN_TYPE_EMAIL
? localization ? localization.emailSignUp
.microsoftSignUp : _loginType ==
: localization.googleSignUp) LOGIN_TYPE_MICROSOFT
: (_loginType == LOGIN_TYPE_EMAIL ? localization
? localization.emailSignIn .microsoftSignUp
: _loginType == : localization
LOGIN_TYPE_MICROSOFT .googleSignUp)
? localization : (_loginType ==
.microsoftSignIn LOGIN_TYPE_EMAIL
: localization ? localization.emailSignIn
.googleSignIn), : _loginType ==
LOGIN_TYPE_MICROSOFT
? localization
.microsoftSignIn
: localization
.googleSignIn),
style: TextStyle( style: TextStyle(
fontSize: 18, color: Colors.white), fontSize: 18, color: Colors.white),
) )
@ -662,11 +677,34 @@ class _LoginState extends State<LoginView> {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
if (!_createAccount) if (_recoverPassword) ...[
if (!_disable2FA)
InkWell(
onTap: () {
setState(() {
_disable2FA = true;
});
},
child: Padding(
padding: const EdgeInsets.all(14),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.lock, size: 16),
SizedBox(width: 8),
Text(localization.disable2fa),
]),
),
),
InkWell( InkWell(
onTap: () { onTap: () {
setState(() { setState(() {
_recoverPassword = !_recoverPassword; if (_disable2FA) {
_disable2FA = false;
} else {
_recoverPassword = false;
}
}); });
}, },
child: Padding( child: Padding(
@ -675,67 +713,88 @@ class _LoginState extends State<LoginView> {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
if (!_recoverPassword) Icon(Icons.cancel, size: 16),
Icon(MdiIcons.lock, size: 16),
SizedBox(width: 8), SizedBox(width: 8),
Text(_recoverPassword Text(localization.cancel),
? localization.cancel
: localization.recoverPassword),
]), ]),
), ),
), ),
if (!_recoverPassword && !_isSelfHosted) ] else ...[
InkWell( if (!_createAccount)
onTap: () { InkWell(
launchUrl(Uri.parse(kStatusCheckUrl)); onTap: () {
}, setState(() {
child: Padding( _recoverPassword = true;
padding: const EdgeInsets.all(14), });
child: Row( },
mainAxisSize: MainAxisSize.max, child: Padding(
mainAxisAlignment: MainAxisAlignment.center, padding: const EdgeInsets.all(14),
children: [ child: Row(
Icon(Icons.security, size: 16), mainAxisSize: MainAxisSize.max,
SizedBox(width: 8), mainAxisAlignment: MainAxisAlignment.center,
Text(localization.checkStatus) children: <Widget>[
], if (!_recoverPassword)
Icon(MdiIcons.lock, size: 16),
SizedBox(width: 8),
Text(_recoverPassword
? localization.cancel
: localization.recoverPassword),
]),
), ),
), ),
), if (!_recoverPassword && !_isSelfHosted)
if (!_recoverPassword)
if (kIsWeb)
InkWell( InkWell(
onTap: () => onTap: () {
launchUrl(Uri.parse(getNativeAppUrl(platform))), launchUrl(Uri.parse(kStatusCheckUrl));
},
child: Padding( child: Padding(
padding: const EdgeInsets.all(14), padding: const EdgeInsets.all(14),
child: Row( child: Row(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Icon(getNativeAppIcon(platform), size: 16), Icon(Icons.security, size: 16),
SizedBox(width: 8), SizedBox(width: 8),
Text('$platform ${localization.app}') Text(localization.checkStatus)
], ],
), ),
), ),
) ),
else if (!_recoverPassword)
InkWell( if (kIsWeb)
onTap: () => launchUrl(Uri.parse(kDocsUrl)), InkWell(
child: Padding( onTap: () =>
padding: const EdgeInsets.all(14), launchUrl(Uri.parse(getNativeAppUrl(platform))),
child: Row( child: Padding(
mainAxisSize: MainAxisSize.max, padding: const EdgeInsets.all(14),
mainAxisAlignment: MainAxisAlignment.center, child: Row(
children: [ mainAxisSize: MainAxisSize.max,
Icon(Icons.book, size: 16), mainAxisAlignment: MainAxisAlignment.center,
SizedBox(width: 8), children: [
Text(localization.documentation) Icon(getNativeAppIcon(platform), size: 16),
], SizedBox(width: 8),
Text('$platform ${localization.app}')
],
),
), ),
), )
) else
InkWell(
onTap: () => launchUrl(Uri.parse(kDocsUrl)),
child: Padding(
padding: const EdgeInsets.all(14),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.book, size: 16),
SizedBox(width: 8),
Text(localization.documentation)
],
),
),
)
]
], ],
), ),
], ],

View File

@ -57,6 +57,7 @@ class LoginVM {
@required this.authState, @required this.authState,
@required this.onLoginPressed, @required this.onLoginPressed,
@required this.onRecoverPressed, @required this.onRecoverPressed,
@required this.onDisable2FAPressed,
@required this.onSignUpPressed, @required this.onSignUpPressed,
@required this.onGoogleLoginPressed, @required this.onGoogleLoginPressed,
@required this.onGoogleSignUpPressed, @required this.onGoogleSignUpPressed,
@ -89,6 +90,14 @@ class LoginVM {
@required String secret, @required String secret,
}) onRecoverPressed; }) onRecoverPressed;
final Function(
BuildContext,
Completer<Null> completer, {
@required String email,
@required String url,
@required String secret,
}) onDisable2FAPressed;
final Function( final Function(
BuildContext, BuildContext,
Completer<Null> completer, { Completer<Null> completer, {
@ -376,6 +385,24 @@ class LoginVM {
secret: secret.trim(), secret: secret.trim(),
)); ));
}, },
onDisable2FAPressed: (
BuildContext context,
Completer<Null> completer, {
@required String email,
@required String url,
@required String secret,
}) async {
if (store.state.isLoading) {
return;
}
store.dispatch(RecoverPasswordRequest(
completer: completer,
email: email.trim(),
url: _formatApiUrl(url),
secret: secret.trim(),
));
},
onLoginPressed: ( onLoginPressed: (
BuildContext context, BuildContext context,
Completer<Null> completer, { Completer<Null> completer, {

View File

@ -16,6 +16,7 @@ mixin LocalizationsProvider on LocaleCodeAware {
static final Map<String, Map<String, String>> _localizedValues = { static final Map<String, Map<String, String>> _localizedValues = {
'en': { 'en': {
// STARTER: lang key - do not remove comment // STARTER: lang key - do not remove comment
'disable_2fa': 'Disable 2FA',
'change_number': 'Change Number', 'change_number': 'Change Number',
'resend_code': 'Resend Code', 'resend_code': 'Resend Code',
'base_type': 'Base Type', 'base_type': 'Base Type',
@ -87487,6 +87488,11 @@ mixin LocalizationsProvider on LocaleCodeAware {
_localizedValues[localeCode]['change_number'] ?? _localizedValues[localeCode]['change_number'] ??
_localizedValues['en']['change_number']; _localizedValues['en']['change_number'];
String get disable2fa =>
_localizedValues[localeCode]['disable_2fa'] ??
_localizedValues['en']['disable_2fa'];
// STARTER: lang field - do not remove comment // STARTER: lang field - do not remove comment
String lookup(String key) { String lookup(String key) {