Better 2fa verification support (#6782)
* Better 2fa verification support Signed-off-by: fufesou <shuanglongchen@yeah.net> * 2FA login verification, add request filed 'tfa_code' Signed-off-by: fufesou <shuanglongchen@yeah.net> * 2fa dialog Signed-off-by: fufesou <shuanglongchen@yeah.net> * msgbox, title Signed-off-by: fufesou <shuanglongchen@yeah.net> * Feat, oidc login, 2fa Signed-off-by: fufesou <shuanglongchen@yeah.net> --------- Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
parent
89150317e1
commit
7e3a0c4ded
@ -11,9 +11,11 @@ class HttpType {
|
||||
static const kAuthReqTypeMobile = "mobile";
|
||||
static const kAuthReqTypeSMSCode = "sms_code";
|
||||
static const kAuthReqTypeEmailCode = "email_code";
|
||||
static const kAuthReqTypeTfaCode = "tfa_code";
|
||||
|
||||
static const kAuthResTypeToken = "access_token";
|
||||
static const kAuthResTypeEmailCheck = "email_check";
|
||||
static const kAuthResTypeTfaCheck = "tfa_check";
|
||||
}
|
||||
|
||||
enum UserStatus { kDisabled, kNormal, kUnverified }
|
||||
@ -118,6 +120,7 @@ class LoginRequest {
|
||||
bool? autoLogin;
|
||||
String? type;
|
||||
String? verificationCode;
|
||||
String? tfaCode;
|
||||
|
||||
LoginRequest(
|
||||
{this.username,
|
||||
@ -126,7 +129,8 @@ class LoginRequest {
|
||||
this.uuid,
|
||||
this.autoLogin,
|
||||
this.type,
|
||||
this.verificationCode});
|
||||
this.verificationCode,
|
||||
this.tfaCode});
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
final Map<String, dynamic> data = <String, dynamic>{};
|
||||
@ -139,6 +143,7 @@ class LoginRequest {
|
||||
if (verificationCode != null) {
|
||||
data['verificationCode'] = verificationCode;
|
||||
}
|
||||
if (tfaCode != null) data['tfaCode'] = tfaCode;
|
||||
|
||||
Map<String, dynamic> deviceInfo = {};
|
||||
try {
|
||||
@ -154,13 +159,15 @@ class LoginRequest {
|
||||
class LoginResponse {
|
||||
String? access_token;
|
||||
String? type;
|
||||
String? tfa_type;
|
||||
UserPayload? user;
|
||||
|
||||
LoginResponse({this.access_token, this.type, this.user});
|
||||
LoginResponse({this.access_token, this.type, this.tfa_type, this.user});
|
||||
|
||||
LoginResponse.fromJson(Map<String, dynamic> json) {
|
||||
access_token = json['access_token'];
|
||||
type = json['type'];
|
||||
tfa_type = json['tfa_type'];
|
||||
user = json['user'] != null ? UserPayload.fromJson(json['user']) : null;
|
||||
}
|
||||
}
|
||||
|
@ -427,6 +427,54 @@ Future<bool?> loginDialog() async {
|
||||
close(false);
|
||||
}
|
||||
|
||||
handleLoginResponse(LoginResponse resp, bool storeIfAccessToken,
|
||||
void Function([dynamic])? close) async {
|
||||
switch (resp.type) {
|
||||
case HttpType.kAuthResTypeToken:
|
||||
if (resp.access_token != null) {
|
||||
if (storeIfAccessToken) {
|
||||
await bind.mainSetLocalOption(
|
||||
key: 'access_token', value: resp.access_token!);
|
||||
await bind.mainSetLocalOption(
|
||||
key: 'user_info', value: jsonEncode(resp.user ?? {}));
|
||||
}
|
||||
if (close != null) {
|
||||
close(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case HttpType.kAuthResTypeEmailCheck:
|
||||
bool? isEmailVerification;
|
||||
if (resp.tfa_type == null ||
|
||||
resp.tfa_type == HttpType.kAuthResTypeEmailCheck) {
|
||||
isEmailVerification = true;
|
||||
} else if (resp.tfa_type == HttpType.kAuthResTypeTfaCheck) {
|
||||
isEmailVerification = false;
|
||||
} else {
|
||||
passwordMsg = "Failed, bad tfa type from server";
|
||||
}
|
||||
if (isEmailVerification != null) {
|
||||
if (isMobile) {
|
||||
if (close != null) close(false);
|
||||
verificationCodeDialog(resp.user, isEmailVerification);
|
||||
} else {
|
||||
setState(() => isInProgress = false);
|
||||
final res =
|
||||
await verificationCodeDialog(resp.user, isEmailVerification);
|
||||
if (res == true) {
|
||||
if (close != null) close(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
passwordMsg = "Failed, bad response from server";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onLogin() async {
|
||||
// validate
|
||||
if (username.text.isEmpty) {
|
||||
@ -447,35 +495,7 @@ Future<bool?> loginDialog() async {
|
||||
uuid: await bind.mainGetUuid(),
|
||||
autoLogin: true,
|
||||
type: HttpType.kAuthReqTypeAccount));
|
||||
|
||||
switch (resp.type) {
|
||||
case HttpType.kAuthResTypeToken:
|
||||
if (resp.access_token != null) {
|
||||
await bind.mainSetLocalOption(
|
||||
key: 'access_token', value: resp.access_token!);
|
||||
await bind.mainSetLocalOption(
|
||||
key: 'user_info', value: jsonEncode(resp.user ?? {}));
|
||||
close(true);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case HttpType.kAuthResTypeEmailCheck:
|
||||
if (isMobile) {
|
||||
close(true);
|
||||
verificationCodeDialog(resp.user);
|
||||
} else {
|
||||
setState(() => isInProgress = false);
|
||||
final res = await verificationCodeDialog(resp.user);
|
||||
if (res == true) {
|
||||
close(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
passwordMsg = "Failed, bad response from server";
|
||||
break;
|
||||
}
|
||||
await handleLoginResponse(resp, true, close);
|
||||
} on RequestException catch (err) {
|
||||
passwordMsg = translate(err.cause);
|
||||
} catch (err) {
|
||||
@ -506,15 +526,21 @@ Future<bool?> loginDialog() async {
|
||||
.map((e) => ConfigOP(op: e['name'], icon: e['icon']))
|
||||
.toList(),
|
||||
curOP: curOP,
|
||||
cbLogin: (Map<String, dynamic> authBody) {
|
||||
cbLogin: (Map<String, dynamic> authBody) async {
|
||||
LoginResponse? resp;
|
||||
try {
|
||||
// access_token is already stored in the rust side.
|
||||
gFFI.userModel.getLoginResponseFromAuthBody(authBody);
|
||||
resp =
|
||||
gFFI.userModel.getLoginResponseFromAuthBody(authBody);
|
||||
} catch (e) {
|
||||
debugPrint(
|
||||
'Failed to parse oidc login body: "$authBody"');
|
||||
}
|
||||
close(true);
|
||||
|
||||
if (resp != null) {
|
||||
handleLoginResponse(resp, false, null);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
@ -583,7 +609,8 @@ Future<bool?> loginDialog() async {
|
||||
return res;
|
||||
}
|
||||
|
||||
Future<bool?> verificationCodeDialog(UserPayload? user) async {
|
||||
Future<bool?> verificationCodeDialog(
|
||||
UserPayload? user, bool isEmailVerification) async {
|
||||
var autoLogin = true;
|
||||
var isInProgress = false;
|
||||
String? errorText;
|
||||
@ -614,6 +641,7 @@ Future<bool?> verificationCodeDialog(UserPayload? user) async {
|
||||
try {
|
||||
final resp = await gFFI.userModel.login(LoginRequest(
|
||||
verificationCode: code.text,
|
||||
tfaCode: isEmailVerification ? null : code.text,
|
||||
username: user?.name,
|
||||
id: await bind.mainGetMyId(),
|
||||
uuid: await bind.mainGetUuid(),
|
||||
@ -648,20 +676,22 @@ Future<bool?> verificationCodeDialog(UserPayload? user) async {
|
||||
content: Column(
|
||||
children: [
|
||||
Offstage(
|
||||
offstage: user?.email == null,
|
||||
offstage: !isEmailVerification || user?.email == null,
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: "Email", prefixIcon: Icon(Icons.email)),
|
||||
readOnly: true,
|
||||
controller: TextEditingController(text: user?.email),
|
||||
)),
|
||||
const SizedBox(height: 8),
|
||||
isEmailVerification ? const SizedBox(height: 8) : const Offstage(),
|
||||
DialogTextField(
|
||||
title: '${translate("Verification code")}:',
|
||||
title:
|
||||
'${translate(isEmailVerification ? "Verification code" : "2FA code")}:',
|
||||
controller: code,
|
||||
errorText: errorText,
|
||||
focusNode: focusNode,
|
||||
helperText: translate('verification_tip'),
|
||||
helperText: translate(
|
||||
isEmailVerification ? 'verification_tip' : '2fa_tip'),
|
||||
),
|
||||
/*
|
||||
CheckboxListTile(
|
||||
|
@ -95,6 +95,8 @@ pub struct UserPayload {
|
||||
pub struct AuthBody {
|
||||
pub access_token: String,
|
||||
pub r#type: String,
|
||||
#[serde(default)]
|
||||
pub tfa_type: String,
|
||||
pub user: UserPayload,
|
||||
}
|
||||
|
||||
@ -238,15 +240,17 @@ impl OidcSession {
|
||||
while OIDC_SESSION.read().unwrap().keep_querying && begin.elapsed() < query_timeout {
|
||||
match Self::query(&api_server, &code_url.code, &id, &uuid) {
|
||||
Ok(HbbHttpResponse::<_>::Data(auth_body)) => {
|
||||
if remember_me {
|
||||
LocalConfig::set_option(
|
||||
"access_token".to_owned(),
|
||||
auth_body.access_token.clone(),
|
||||
);
|
||||
LocalConfig::set_option(
|
||||
"user_info".to_owned(),
|
||||
serde_json::json!({ "name": auth_body.user.name, "status": auth_body.user.status }).to_string(),
|
||||
);
|
||||
if auth_body.r#type == "access_token" {
|
||||
if remember_me {
|
||||
LocalConfig::set_option(
|
||||
"access_token".to_owned(),
|
||||
auth_body.access_token.clone(),
|
||||
);
|
||||
LocalConfig::set_option(
|
||||
"user_info".to_owned(),
|
||||
serde_json::json!({ "name": auth_body.user.name, "status": auth_body.user.status }).to_string(),
|
||||
);
|
||||
}
|
||||
}
|
||||
OIDC_SESSION
|
||||
.write()
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "用户提权后,不能显示多个显示器。若要控制多显示器,请安装后再试。"),
|
||||
("Swap control-command key", "交换Control键和Command键"),
|
||||
("swap-left-right-mouse", "交换鼠标左右键"),
|
||||
("2FA code", "2FA code"),
|
||||
("2fa_tip", "请输入授权 app 中的 2FA code"),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "Snímání více displejů není podporováno v uživatelském režimu se zvýšenými oprávněními. Pokud chcete ovládat více displejů, zkuste to znovu po instalaci."),
|
||||
("Swap control-command key", "Prohození klávesy control-command"),
|
||||
("swap-left-right-mouse", "Prohodit levé a pravé tlačítko myši"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "Das Erfassen mehrerer Bildschirme wird im erweiterten Benutzermodus nicht unterstützt. Bitte versuchen Sie es nach der Installation erneut, wenn Sie mehrere Bildschirme steuern möchten."),
|
||||
("Swap control-command key", "Steuerungs- und Befehlstasten tauschen"),
|
||||
("swap-left-right-mouse", "Linke und rechte Maustaste tauschen"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -210,5 +210,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("input_source_2_tip", "Input source 2"),
|
||||
("capture_display_elevated_connections_tip", "Capturing multiple displays is not supported in the elevated user mode. Please try again after installation if you want to control multiple displays."),
|
||||
("swap-left-right-mouse", "Swap left-right mouse button"),
|
||||
("2FA code", "2FA code"),
|
||||
("2fa_tip", "Please enter the your 2FA code in the authentication app."),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "La captura de múltiples pantallas en el modo de usaurio con privilegios elevados no está soportada. Por favor, inténtalo de nuevo tras la instalación si quieres controlar múltiples pantallas."),
|
||||
("Swap control-command key", "Intercambiar teclas control-comando"),
|
||||
("swap-left-right-mouse", "Intercambiar botones derecho-izquierdo del ratón"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "Mitme ekraani jäädvustamine ei ole kõrgendatud kasutajarežiimis toetatud. Kui soovid juhtida mitut ekraani, palun proovi uuesti pärast paigaldamist."),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", "Vaheta vasak ja parem hiirenupp"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "La capture de plusieurs écrans n'est pas prise en charge en mode utilisateur avec privilièges. Veuillez réessayer après l'installation si vous souhaitez contrôler plusieurs écrans."),
|
||||
("Swap control-command key", "Échanger la touche de controle-commande"),
|
||||
("swap-left-right-mouse", "Intervertir le bouton gauche et droit de la souris"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "La cattura di più display non è supportata nella modalità utente con privilegi elevati. Se vuoi controllare più display riprova dopo l'installazione."),
|
||||
("Swap control-command key", "Scambia tasto controllo-comando"),
|
||||
("swap-left-right-mouse", "Scambia pulsante sinistro-destro mouse"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "권한 상승된 사용자 모드에서는 다중 디스플레이 캡처가 지원되지 않습니다. 다중 디스플레이를 제어하려면 설치 후 재시도하세요."),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "Vairāku displeju uzņemšana netiek atbalstīta paaugstinātā lietotāja režīmā. Lūdzu, mēģiniet vēlreiz pēc instalēšanas, ja vēlaties kontrolēt vairākus displejus."),
|
||||
("Swap control-command key", "Apmainīt vadības un komandas taustiņu"),
|
||||
("swap-left-right-mouse", "Apmainīt kreiso un labo peles pogu"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "Scannen van meerdere schermen wordt niet ondersteund in de bevoorrechte gebruikersmodus. Als je meerdere schermen wilt bedienen, probeer het dan opnieuw na de installatie."),
|
||||
("Swap control-command key", "Wissel controle-commando toets"),
|
||||
("swap-left-right-mouse", "wissel-links-rechts-muis"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "Przechwytywanie wielu ekranów nie jest obsługiwane w trybie użytkownika z podwyższonym poziomem uprawnień. Jeśli chcesz sterować wieloma wyświetlaczami, spróbuj ponownie po instalacji."),
|
||||
("Swap control-command key", "Zamiana przycisków sterujących myszki"),
|
||||
("swap-left-right-mouse", "Zamień przyciski myszki (lewy - prawy)"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "Захват экрана нескольких дисплеев не поддерживается в режиме повышенных прав. Повторите попытку после установки, если хотите управлять несколькими дисплеями."),
|
||||
("Swap control-command key", "Поменять кнопки управления и команд"),
|
||||
("swap-left-right-mouse", "Поменять левую и правую кнопки мыши"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "Snímanie viacerých displejov nie je podporované v režime privilegovaného používateľa. Ak chcete ovládať viac displejov, skúste to po inštalácii znova."),
|
||||
("Swap control-command key", "Vymeniť kláves ovládania a príkazu"),
|
||||
("swap-left-right-mouse", "Prehodiť ľavé a pravé tlačidlo myši"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", "В режимі розширених прав захоплення декількох дисплеїв не підтримується. Якщо ви хочете керувати декількома дисплеями, будь ласка, спробуйте це після встановлення."),
|
||||
("Swap control-command key", "Поміняти місцями клавіші Control та Command"),
|
||||
("swap-left-right-mouse", "Поміняти місцями ліву та праву кнопки миші"),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -578,5 +578,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
|
||||
("capture_display_elevated_connections_tip", ""),
|
||||
("Swap control-command key", ""),
|
||||
("swap-left-right-mouse", ""),
|
||||
("2FA code", ""),
|
||||
("2fa_tip", ""),
|
||||
].iter().cloned().collect();
|
||||
}
|
||||
|
@ -1223,7 +1223,7 @@ function login() {
|
||||
if (data.type == 'email_check') {
|
||||
abLoading = false;
|
||||
show_progress(-1);
|
||||
on_email_check(data);
|
||||
on_2fa_check(data);
|
||||
return;
|
||||
}
|
||||
handler.set_local_option("access_token", data.access_token);
|
||||
@ -1241,12 +1241,14 @@ function login() {
|
||||
});
|
||||
}
|
||||
|
||||
function on_email_check(last_msg) {
|
||||
function on_2fa_check(last_msg) {
|
||||
var isEmailCheck = !last_msg.tfa_type || last_msg.tfa_type == 'email_check';
|
||||
|
||||
var emailHint = last_msg.user.email;
|
||||
msgbox("custom-email-verification-code", translate('Verification code'), <div .form .set-password>
|
||||
<div><span>{translate('Email')}:</span><span>{emailHint}</span></div>
|
||||
<div><span>{translate('Verification code')}:</span><input|text name="verification_code" .outline-focus /></div>
|
||||
<div style="font-size:0.9em; margin-bottom:1em;">{translate('verification_tip')}</div>
|
||||
msgbox("custom-2fa-verification-code", translate('Verification code'), <div .form .set-password>
|
||||
{ isEmailCheck && <div><span>{translate('Email')}:</span><span>{emailHint}</span></div> }
|
||||
<div><span>{translate(isEmailCheck ? 'Verification code' : '2FA code')}:</span><input|text name="verification_code" .outline-focus /></div>
|
||||
<div style="font-size:0.9em; margin-bottom:1em;">{translate(isEmailCheck ? 'verification_tip' : '2fa_tip')}</div>
|
||||
</div>, "",
|
||||
function(res=null, show_progress) {
|
||||
if (!res) return;
|
||||
@ -1258,7 +1260,8 @@ function on_email_check(last_msg) {
|
||||
}
|
||||
abLoading = true;
|
||||
var url = handler.get_api_server();
|
||||
httpRequest(url + "/api/login", #post, {username: last_msg.user.name, id: my_id, uuid: handler.get_uuid(), type: 'email_code', autoLogin: true, verificationCode: code, deviceInfo: getDeviceInfo()},
|
||||
const loginData = {username: last_msg.user.name, id: my_id, uuid: handler.get_uuid(), type: 'email_code', verificationCode: code, tfaCode: isEmailCheck ? '' : code, deviceInfo: getDeviceInfo()};
|
||||
httpRequest(url + "/api/login", #post, loginData,
|
||||
function(data) {
|
||||
if (data.error) {
|
||||
abLoading = false;
|
||||
|
Loading…
x
Reference in New Issue
Block a user