mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-01-19 00:13:01 +08:00
Refact/verification code input check (#6924)
* Refact, login verification code, input check Signed-off-by: fufesou <shuanglongchen@yeah.net> * Refact, settings, enable 2fa, dialog input Signed-off-by: fufesou <shuanglongchen@yeah.net> * Refact. Connect, 2fa code, input check Signed-off-by: fufesou <shuanglongchen@yeah.net> * refact, 2Fa text field, input formatter, only digits Signed-off-by: fufesou <shuanglongchen@yeah.net> * refact, error message Signed-off-by: fufesou <shuanglongchen@yeah.net> --------- Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
d39129887b
commit
06b3894249
@ -1,5 +1,6 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -362,6 +363,7 @@ class DialogTextField extends StatelessWidget {
|
||||
final Widget? suffixIcon;
|
||||
final TextEditingController controller;
|
||||
final FocusNode? focusNode;
|
||||
final List<TextInputFormatter>? inputFormatters;
|
||||
|
||||
static const kUsernameTitle = 'Username';
|
||||
static const kUsernameIcon = Icon(Icons.account_circle_outlined);
|
||||
@ -377,6 +379,7 @@ class DialogTextField extends StatelessWidget {
|
||||
this.prefixIcon,
|
||||
this.suffixIcon,
|
||||
this.hintText,
|
||||
this.inputFormatters,
|
||||
required this.title,
|
||||
required this.controller})
|
||||
: super(key: key);
|
||||
@ -401,6 +404,7 @@ class DialogTextField extends StatelessWidget {
|
||||
focusNode: focusNode,
|
||||
autofocus: true,
|
||||
obscureText: obscureText,
|
||||
inputFormatters: inputFormatters,
|
||||
),
|
||||
),
|
||||
],
|
||||
@ -408,6 +412,241 @@ class DialogTextField extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ValidationField extends StatelessWidget {
|
||||
ValidationField({Key? key}) : super(key: key);
|
||||
|
||||
String? validate();
|
||||
bool get isReady;
|
||||
}
|
||||
|
||||
class Dialog2FaField extends ValidationField {
|
||||
Dialog2FaField({
|
||||
Key? key,
|
||||
required this.controller,
|
||||
this.autoFocus = true,
|
||||
this.reRequestFocus = false,
|
||||
this.title,
|
||||
this.helperText,
|
||||
this.hintText,
|
||||
this.errorText,
|
||||
this.readyCallback,
|
||||
this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final TextEditingController controller;
|
||||
final bool autoFocus;
|
||||
final bool reRequestFocus;
|
||||
final String? title;
|
||||
final String? helperText;
|
||||
final String? hintText;
|
||||
final String? errorText;
|
||||
final VoidCallback? readyCallback;
|
||||
final VoidCallback? onChanged;
|
||||
final errMsg = translate('2FA code must be 6 digits.');
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DialogVerificationCodeField(
|
||||
title: title ?? translate('2FA code'),
|
||||
controller: controller,
|
||||
errorText: errorText,
|
||||
autoFocus: autoFocus,
|
||||
reRequestFocus: reRequestFocus,
|
||||
hintText: hintText,
|
||||
readyCallback: readyCallback,
|
||||
helperText: helperText ?? translate('2fa_tip'),
|
||||
onChanged: _onChanged,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
String get text => controller.text;
|
||||
bool get isAllDigits => text.codeUnits.every((e) => e >= 48 && e <= 57);
|
||||
|
||||
@override
|
||||
bool get isReady => text.length == 6 && isAllDigits;
|
||||
|
||||
@override
|
||||
String? validate() => isReady ? null : errMsg;
|
||||
|
||||
_onChanged(StateSetter setState, SimpleWrapper<String?> errText) {
|
||||
onChanged?.call();
|
||||
|
||||
if (text.length > 6) {
|
||||
setState(() => errText.value = errMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isAllDigits) {
|
||||
setState(() => errText.value = errMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isReady) {
|
||||
readyCallback?.call();
|
||||
return;
|
||||
}
|
||||
|
||||
if (errText.value != null) {
|
||||
setState(() => errText.value = null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DialogEmailCodeField extends ValidationField {
|
||||
DialogEmailCodeField({
|
||||
Key? key,
|
||||
required this.controller,
|
||||
this.autoFocus = true,
|
||||
this.reRequestFocus = false,
|
||||
this.hintText,
|
||||
this.errorText,
|
||||
this.readyCallback,
|
||||
this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final TextEditingController controller;
|
||||
final bool autoFocus;
|
||||
final bool reRequestFocus;
|
||||
final String? hintText;
|
||||
final String? errorText;
|
||||
final VoidCallback? readyCallback;
|
||||
final VoidCallback? onChanged;
|
||||
final errMsg = translate('Email verification code must be 6 characters.');
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DialogVerificationCodeField(
|
||||
title: translate('Verification code'),
|
||||
controller: controller,
|
||||
errorText: errorText,
|
||||
autoFocus: autoFocus,
|
||||
reRequestFocus: reRequestFocus,
|
||||
hintText: hintText,
|
||||
readyCallback: readyCallback,
|
||||
helperText: translate('verification_tip'),
|
||||
onChanged: _onChanged,
|
||||
);
|
||||
}
|
||||
|
||||
String get text => controller.text;
|
||||
|
||||
@override
|
||||
bool get isReady => text.length == 6;
|
||||
|
||||
@override
|
||||
String? validate() => isReady ? null : errMsg;
|
||||
|
||||
_onChanged(StateSetter setState, SimpleWrapper<String?> errText) {
|
||||
onChanged?.call();
|
||||
|
||||
if (text.length > 6) {
|
||||
setState(() => errText.value = errMsg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isReady) {
|
||||
readyCallback?.call();
|
||||
return;
|
||||
}
|
||||
|
||||
if (errText.value != null) {
|
||||
setState(() => errText.value = null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class DialogVerificationCodeField extends StatefulWidget {
|
||||
DialogVerificationCodeField({
|
||||
Key? key,
|
||||
required this.controller,
|
||||
required this.title,
|
||||
this.autoFocus = true,
|
||||
this.reRequestFocus = false,
|
||||
this.helperText,
|
||||
this.hintText,
|
||||
this.errorText,
|
||||
this.textLength,
|
||||
this.readyCallback,
|
||||
this.onChanged,
|
||||
this.inputFormatters,
|
||||
}) : super(key: key);
|
||||
|
||||
final TextEditingController controller;
|
||||
final bool autoFocus;
|
||||
final bool reRequestFocus;
|
||||
final String title;
|
||||
final String? helperText;
|
||||
final String? hintText;
|
||||
final String? errorText;
|
||||
final int? textLength;
|
||||
final VoidCallback? readyCallback;
|
||||
final Function(StateSetter setState, SimpleWrapper<String?> errText)?
|
||||
onChanged;
|
||||
final List<TextInputFormatter>? inputFormatters;
|
||||
|
||||
@override
|
||||
State<DialogVerificationCodeField> createState() =>
|
||||
_DialogVerificationCodeField();
|
||||
}
|
||||
|
||||
class _DialogVerificationCodeField extends State<DialogVerificationCodeField> {
|
||||
final _focusNode = FocusNode();
|
||||
Timer? _timer;
|
||||
Timer? _timerReRequestFocus;
|
||||
SimpleWrapper<String?> errorText = SimpleWrapper(null);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
if (widget.autoFocus) {
|
||||
_timer =
|
||||
Timer(Duration(milliseconds: 50), () => _focusNode.requestFocus());
|
||||
|
||||
if (widget.onChanged != null) {
|
||||
widget.controller.addListener(() {
|
||||
widget.onChanged!(setState, errorText);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// software secure keyboard will take the focus since flutter 3.13
|
||||
// request focus again when android account password obtain focus
|
||||
if (Platform.isAndroid && widget.reRequestFocus) {
|
||||
_focusNode.addListener(() {
|
||||
if (_focusNode.hasFocus) {
|
||||
_timerReRequestFocus?.cancel();
|
||||
_timerReRequestFocus = Timer(
|
||||
Duration(milliseconds: 100), () => _focusNode.requestFocus());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_timer?.cancel();
|
||||
_timerReRequestFocus?.cancel();
|
||||
_focusNode.unfocus();
|
||||
_focusNode.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DialogTextField(
|
||||
title: widget.title,
|
||||
controller: widget.controller,
|
||||
errorText: widget.errorText ?? errorText.value,
|
||||
focusNode: _focusNode,
|
||||
helperText: widget.helperText,
|
||||
inputFormatters: widget.inputFormatters,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class PasswordWidget extends StatefulWidget {
|
||||
PasswordWidget({
|
||||
Key? key,
|
||||
@ -1512,9 +1751,31 @@ void change2fa({Function()? callback}) async {
|
||||
var new2fa = (await bind.mainGenerate2Fa());
|
||||
final secretRegex = RegExp(r'secret=([^&]+)');
|
||||
final secret = secretRegex.firstMatch(new2fa)?.group(1);
|
||||
var msg = ''.obs;
|
||||
final RxString code = "".obs;
|
||||
String? errorText;
|
||||
final controller = TextEditingController();
|
||||
gFFI.dialogManager.show((setState, close, context) {
|
||||
onVerify() async {
|
||||
if (await bind.mainVerify2Fa(code: controller.text.trim())) {
|
||||
callback?.call();
|
||||
close();
|
||||
} else {
|
||||
errorText = translate('wrong-2fa-code');
|
||||
}
|
||||
}
|
||||
|
||||
final codeField = Dialog2FaField(
|
||||
controller: controller,
|
||||
errorText: errorText,
|
||||
onChanged: () => setState(() => errorText = null),
|
||||
title: translate('Verification code'),
|
||||
readyCallback: () {
|
||||
onVerify();
|
||||
setState(() {});
|
||||
},
|
||||
);
|
||||
|
||||
getOnSubmit() => codeField.isReady ? onVerify : null;
|
||||
|
||||
return CustomAlertDialog(
|
||||
title: Text(translate("enable-2fa-title")),
|
||||
content: Column(
|
||||
@ -1535,36 +1796,12 @@ void change2fa({Function()? callback}) async {
|
||||
)).marginOnly(bottom: 6),
|
||||
SelectableText(secret ?? '', style: TextStyle(fontSize: 12))
|
||||
.marginOnly(bottom: 12),
|
||||
Row(children: [
|
||||
Expanded(
|
||||
child: Obx(() => TextField(
|
||||
decoration: InputDecoration(
|
||||
errorText:
|
||||
msg.value.isEmpty ? null : translate(msg.value),
|
||||
hintText: translate("Verification code")),
|
||||
onChanged: (value) {
|
||||
code.value = value;
|
||||
msg.value = '';
|
||||
},
|
||||
autofocus: true)))
|
||||
]),
|
||||
Row(children: [Expanded(child: codeField)]),
|
||||
],
|
||||
),
|
||||
actions: [
|
||||
dialogButton("Cancel", onPressed: close, isOutline: true),
|
||||
Obx(() => dialogButton(
|
||||
"OK",
|
||||
onPressed: code.value.trim().length == 6
|
||||
? () async {
|
||||
if (await bind.mainVerify2Fa(code: code.value.trim())) {
|
||||
callback?.call();
|
||||
close();
|
||||
} else {
|
||||
msg.value = translate('wrong-2fa-code');
|
||||
}
|
||||
}
|
||||
: null,
|
||||
)),
|
||||
dialogButton("OK", onPressed: getOnSubmit()),
|
||||
],
|
||||
onCancel: close,
|
||||
);
|
||||
@ -1573,7 +1810,9 @@ void change2fa({Function()? callback}) async {
|
||||
|
||||
void enter2FaDialog(
|
||||
SessionID sessionId, OverlayDialogManager dialogManager) async {
|
||||
final RxString code = "".obs;
|
||||
final controller = TextEditingController();
|
||||
final RxBool submitReady = false.obs;
|
||||
|
||||
dialogManager.dismissAll();
|
||||
dialogManager.show((setState, close, context) {
|
||||
cancel() {
|
||||
@ -1582,34 +1821,23 @@ void enter2FaDialog(
|
||||
}
|
||||
|
||||
submit() {
|
||||
if (code.value.trim().length != 6) {
|
||||
return;
|
||||
}
|
||||
gFFI.send2FA(sessionId, code.value.trim());
|
||||
gFFI.send2FA(sessionId, controller.text.trim());
|
||||
close();
|
||||
dialogManager.showLoading(translate('Logging in...'),
|
||||
onCancel: closeConnection);
|
||||
}
|
||||
|
||||
late Dialog2FaField codeField;
|
||||
|
||||
codeField = Dialog2FaField(
|
||||
controller: controller,
|
||||
title: translate('Verification code'),
|
||||
onChanged: () => submitReady.value = codeField.isReady,
|
||||
);
|
||||
|
||||
return CustomAlertDialog(
|
||||
title: Text(translate("enter-2fa-title")),
|
||||
content: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(children: [
|
||||
Expanded(
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: translate("Verification code")),
|
||||
onChanged: (value) {
|
||||
code.value = value;
|
||||
},
|
||||
autofocus: true))
|
||||
]),
|
||||
],
|
||||
),
|
||||
onSubmit: submit,
|
||||
onCancel: cancel,
|
||||
title: Text(translate('enter-2fa-title')),
|
||||
content: codeField,
|
||||
actions: [
|
||||
dialogButton(
|
||||
'Cancel',
|
||||
@ -1618,7 +1846,7 @@ void enter2FaDialog(
|
||||
),
|
||||
Obx(() => dialogButton(
|
||||
'OK',
|
||||
onPressed: code.value.trim().length == 6 ? submit : null,
|
||||
onPressed: submitReady.isTrue ? submit : null,
|
||||
)),
|
||||
]);
|
||||
});
|
||||
|
@ -615,23 +615,11 @@ Future<bool?> verificationCodeDialog(
|
||||
var autoLogin = true;
|
||||
var isInProgress = false;
|
||||
String? errorText;
|
||||
String preCode = '';
|
||||
|
||||
final code = TextEditingController();
|
||||
final focusNode = FocusNode()..requestFocus();
|
||||
Timer(Duration(milliseconds: 100), () => focusNode..requestFocus());
|
||||
|
||||
final res = await gFFI.dialogManager.show<bool>((setState, close, context) {
|
||||
bool validate() {
|
||||
return code.text.length >= 6;
|
||||
}
|
||||
|
||||
void onVerify() async {
|
||||
if (!validate()) {
|
||||
setState(
|
||||
() => errorText = translate('Too short, at least 6 characters.'));
|
||||
return;
|
||||
}
|
||||
setState(() => isInProgress = true);
|
||||
|
||||
try {
|
||||
@ -666,18 +654,21 @@ Future<bool?> verificationCodeDialog(
|
||||
setState(() => isInProgress = false);
|
||||
}
|
||||
|
||||
code.addListener(() {
|
||||
if (errorText != null) {
|
||||
setState(() => errorText = null);
|
||||
}
|
||||
if (preCode.length != 6 && code.text.length == 6) {
|
||||
onVerify();
|
||||
}
|
||||
if (!isEmailVerification && preCode.length != 10 && code.text.length == 10) {
|
||||
onVerify();
|
||||
}
|
||||
preCode = code.text;
|
||||
});
|
||||
final codeField = isEmailVerification
|
||||
? DialogEmailCodeField(
|
||||
controller: code,
|
||||
errorText: errorText,
|
||||
readyCallback: onVerify,
|
||||
onChanged: () => errorText = null,
|
||||
)
|
||||
: Dialog2FaField(
|
||||
controller: code,
|
||||
errorText: errorText,
|
||||
readyCallback: onVerify,
|
||||
onChanged: () => errorText = null,
|
||||
);
|
||||
|
||||
getOnSubmit() => codeField.isReady ? onVerify : null;
|
||||
|
||||
return CustomAlertDialog(
|
||||
title: Text(translate("Verification code")),
|
||||
@ -693,15 +684,7 @@ Future<bool?> verificationCodeDialog(
|
||||
controller: TextEditingController(text: user?.email),
|
||||
)),
|
||||
isEmailVerification ? const SizedBox(height: 8) : const Offstage(),
|
||||
DialogTextField(
|
||||
title:
|
||||
'${translate(isEmailVerification ? "Verification code" : "2FA code")}:',
|
||||
controller: code,
|
||||
errorText: errorText,
|
||||
focusNode: focusNode,
|
||||
helperText: translate(
|
||||
isEmailVerification ? 'verification_tip' : '2fa_tip'),
|
||||
),
|
||||
codeField,
|
||||
/*
|
||||
CheckboxListTile(
|
||||
contentPadding: const EdgeInsets.all(0),
|
||||
@ -722,10 +705,10 @@ Future<bool?> verificationCodeDialog(
|
||||
],
|
||||
),
|
||||
onCancel: close,
|
||||
onSubmit: onVerify,
|
||||
onSubmit: getOnSubmit(),
|
||||
actions: [
|
||||
dialogButton("Cancel", onPressed: close, isOutline: true),
|
||||
dialogButton("Verify", onPressed: onVerify),
|
||||
dialogButton("Verify", onPressed: getOnSubmit()),
|
||||
]);
|
||||
});
|
||||
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", "Email 验证码必须是 6 个字符。"),
|
||||
("2FA code must be 6 digits.", "2FA 码必须是6位数字。"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", "Bitte richten Sie jetzt Ihren Authentifikator ein. Sie können eine Authentifizierungs-App wie Authy, Microsoft oder Google Authenticator auf Ihrem Telefon oder Desktop verwenden.\n\nScannen Sie den QR-Code mit Ihrer App und geben Sie den Code ein, den Ihre App anzeigt, um die Zwei-Faktor-Authentifizierung zu aktivieren."),
|
||||
("wrong-2fa-code", "Der Code kann nicht verifiziert werden. Prüfen Sie, ob der Code und die lokalen Zeiteinstellungen korrekt sind."),
|
||||
("enter-2fa-title", "Zwei-Faktor-Authentifizierung"),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -585,5 +585,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("enable-2fa-desc", ""),
|
||||
("wrong-2fa-code", ""),
|
||||
("enter-2fa-title", ""),
|
||||
("Email verification code must be 6 characters.", ""),
|
||||
("2FA code must be 6 digits.", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user