2FA reset via SMS
This commit is contained in:
parent
aa486ab314
commit
00b979c731
|
|
@ -77,6 +77,7 @@ class _LoginState extends State<LoginView> {
|
|||
bool _createAccount = false;
|
||||
|
||||
bool _recoverPassword = false;
|
||||
bool _disable2FA = false;
|
||||
bool _termsChecked = false;
|
||||
bool _privacyChecked = false;
|
||||
|
||||
|
|
@ -235,6 +236,7 @@ class _LoginState extends State<LoginView> {
|
|||
_loginError = '';
|
||||
if (_recoverPassword) {
|
||||
_recoverPassword = false;
|
||||
_disable2FA = false;
|
||||
_buttonController.reset();
|
||||
showDialog<MessageDialog>(
|
||||
context: context,
|
||||
|
|
@ -269,6 +271,14 @@ class _LoginState extends State<LoginView> {
|
|||
url: url,
|
||||
secret: _isSelfHosted ? _secretController.text : '',
|
||||
);
|
||||
} else if (_disable2FA) {
|
||||
viewModel.onDisable2FAPressed(
|
||||
context,
|
||||
completer,
|
||||
email: _emailController.text,
|
||||
url: url,
|
||||
secret: _isSelfHosted ? _secretController.text : '',
|
||||
);
|
||||
} else {
|
||||
viewModel.onLoginPressed(
|
||||
context,
|
||||
|
|
@ -599,24 +609,29 @@ class _LoginState extends State<LoginView> {
|
|||
),
|
||||
SizedBox(width: 10),
|
||||
Text(
|
||||
_recoverPassword
|
||||
? localization.recoverPassword
|
||||
: _createAccount
|
||||
? (_loginType == LOGIN_TYPE_EMAIL
|
||||
? localization.emailSignUp
|
||||
: _loginType ==
|
||||
LOGIN_TYPE_MICROSOFT
|
||||
? localization
|
||||
.microsoftSignUp
|
||||
: localization.googleSignUp)
|
||||
: (_loginType == LOGIN_TYPE_EMAIL
|
||||
? localization.emailSignIn
|
||||
: _loginType ==
|
||||
LOGIN_TYPE_MICROSOFT
|
||||
? localization
|
||||
.microsoftSignIn
|
||||
: localization
|
||||
.googleSignIn),
|
||||
_disable2FA
|
||||
? localization.disable2fa
|
||||
: _recoverPassword
|
||||
? localization.recoverPassword
|
||||
: _createAccount
|
||||
? (_loginType ==
|
||||
LOGIN_TYPE_EMAIL
|
||||
? localization.emailSignUp
|
||||
: _loginType ==
|
||||
LOGIN_TYPE_MICROSOFT
|
||||
? localization
|
||||
.microsoftSignUp
|
||||
: localization
|
||||
.googleSignUp)
|
||||
: (_loginType ==
|
||||
LOGIN_TYPE_EMAIL
|
||||
? localization.emailSignIn
|
||||
: _loginType ==
|
||||
LOGIN_TYPE_MICROSOFT
|
||||
? localization
|
||||
.microsoftSignIn
|
||||
: localization
|
||||
.googleSignIn),
|
||||
style: TextStyle(
|
||||
fontSize: 18, color: Colors.white),
|
||||
)
|
||||
|
|
@ -662,11 +677,34 @@ class _LoginState extends State<LoginView> {
|
|||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
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(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_recoverPassword = !_recoverPassword;
|
||||
if (_disable2FA) {
|
||||
_disable2FA = false;
|
||||
} else {
|
||||
_recoverPassword = false;
|
||||
}
|
||||
});
|
||||
},
|
||||
child: Padding(
|
||||
|
|
@ -675,67 +713,88 @@ class _LoginState extends State<LoginView> {
|
|||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
if (!_recoverPassword)
|
||||
Icon(MdiIcons.lock, size: 16),
|
||||
Icon(Icons.cancel, size: 16),
|
||||
SizedBox(width: 8),
|
||||
Text(_recoverPassword
|
||||
? localization.cancel
|
||||
: localization.recoverPassword),
|
||||
Text(localization.cancel),
|
||||
]),
|
||||
),
|
||||
),
|
||||
if (!_recoverPassword && !_isSelfHosted)
|
||||
InkWell(
|
||||
onTap: () {
|
||||
launchUrl(Uri.parse(kStatusCheckUrl));
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(Icons.security, size: 16),
|
||||
SizedBox(width: 8),
|
||||
Text(localization.checkStatus)
|
||||
],
|
||||
] else ...[
|
||||
if (!_createAccount)
|
||||
InkWell(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_recoverPassword = true;
|
||||
});
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
if (!_recoverPassword)
|
||||
Icon(MdiIcons.lock, size: 16),
|
||||
SizedBox(width: 8),
|
||||
Text(_recoverPassword
|
||||
? localization.cancel
|
||||
: localization.recoverPassword),
|
||||
]),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (!_recoverPassword)
|
||||
if (kIsWeb)
|
||||
if (!_recoverPassword && !_isSelfHosted)
|
||||
InkWell(
|
||||
onTap: () =>
|
||||
launchUrl(Uri.parse(getNativeAppUrl(platform))),
|
||||
onTap: () {
|
||||
launchUrl(Uri.parse(kStatusCheckUrl));
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(getNativeAppIcon(platform), size: 16),
|
||||
Icon(Icons.security, size: 16),
|
||||
SizedBox(width: 8),
|
||||
Text('$platform ${localization.app}')
|
||||
Text(localization.checkStatus)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
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)
|
||||
],
|
||||
),
|
||||
if (!_recoverPassword)
|
||||
if (kIsWeb)
|
||||
InkWell(
|
||||
onTap: () =>
|
||||
launchUrl(Uri.parse(getNativeAppUrl(platform))),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(14),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
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)
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
]
|
||||
],
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ class LoginVM {
|
|||
@required this.authState,
|
||||
@required this.onLoginPressed,
|
||||
@required this.onRecoverPressed,
|
||||
@required this.onDisable2FAPressed,
|
||||
@required this.onSignUpPressed,
|
||||
@required this.onGoogleLoginPressed,
|
||||
@required this.onGoogleSignUpPressed,
|
||||
|
|
@ -89,6 +90,14 @@ class LoginVM {
|
|||
@required String secret,
|
||||
}) onRecoverPressed;
|
||||
|
||||
final Function(
|
||||
BuildContext,
|
||||
Completer<Null> completer, {
|
||||
@required String email,
|
||||
@required String url,
|
||||
@required String secret,
|
||||
}) onDisable2FAPressed;
|
||||
|
||||
final Function(
|
||||
BuildContext,
|
||||
Completer<Null> completer, {
|
||||
|
|
@ -376,6 +385,24 @@ class LoginVM {
|
|||
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: (
|
||||
BuildContext context,
|
||||
Completer<Null> completer, {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
|||
static final Map<String, Map<String, String>> _localizedValues = {
|
||||
'en': {
|
||||
// STARTER: lang key - do not remove comment
|
||||
'disable_2fa': 'Disable 2FA',
|
||||
'change_number': 'Change Number',
|
||||
'resend_code': 'Resend Code',
|
||||
'base_type': 'Base Type',
|
||||
|
|
@ -87487,6 +87488,11 @@ mixin LocalizationsProvider on LocaleCodeAware {
|
|||
_localizedValues[localeCode]['change_number'] ??
|
||||
_localizedValues['en']['change_number'];
|
||||
|
||||
String get disable2fa =>
|
||||
_localizedValues[localeCode]['disable_2fa'] ??
|
||||
_localizedValues['en']['disable_2fa'];
|
||||
|
||||
|
||||
// STARTER: lang field - do not remove comment
|
||||
|
||||
String lookup(String key) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue