password max length prompt (#9248)
Signed-off-by: 21pages <sunboeasy@gmail.com>
This commit is contained in:
parent
04c0f66ca9
commit
29e12b84a9
@ -381,6 +381,7 @@ class DialogTextField extends StatelessWidget {
|
|||||||
final FocusNode? focusNode;
|
final FocusNode? focusNode;
|
||||||
final TextInputType? keyboardType;
|
final TextInputType? keyboardType;
|
||||||
final List<TextInputFormatter>? inputFormatters;
|
final List<TextInputFormatter>? inputFormatters;
|
||||||
|
final int? maxLength;
|
||||||
|
|
||||||
static const kUsernameTitle = 'Username';
|
static const kUsernameTitle = 'Username';
|
||||||
static const kUsernameIcon = Icon(Icons.account_circle_outlined);
|
static const kUsernameIcon = Icon(Icons.account_circle_outlined);
|
||||||
@ -398,6 +399,7 @@ class DialogTextField extends StatelessWidget {
|
|||||||
this.hintText,
|
this.hintText,
|
||||||
this.keyboardType,
|
this.keyboardType,
|
||||||
this.inputFormatters,
|
this.inputFormatters,
|
||||||
|
this.maxLength,
|
||||||
required this.title,
|
required this.title,
|
||||||
required this.controller})
|
required this.controller})
|
||||||
: super(key: key);
|
: super(key: key);
|
||||||
@ -424,6 +426,7 @@ class DialogTextField extends StatelessWidget {
|
|||||||
obscureText: obscureText,
|
obscureText: obscureText,
|
||||||
keyboardType: keyboardType,
|
keyboardType: keyboardType,
|
||||||
inputFormatters: inputFormatters,
|
inputFormatters: inputFormatters,
|
||||||
|
maxLength: maxLength,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -681,6 +684,7 @@ class PasswordWidget extends StatefulWidget {
|
|||||||
this.hintText,
|
this.hintText,
|
||||||
this.errorText,
|
this.errorText,
|
||||||
this.title,
|
this.title,
|
||||||
|
this.maxLength,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final TextEditingController controller;
|
final TextEditingController controller;
|
||||||
@ -689,6 +693,7 @@ class PasswordWidget extends StatefulWidget {
|
|||||||
final String? hintText;
|
final String? hintText;
|
||||||
final String? errorText;
|
final String? errorText;
|
||||||
final String? title;
|
final String? title;
|
||||||
|
final int? maxLength;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<PasswordWidget> createState() => _PasswordWidgetState();
|
State<PasswordWidget> createState() => _PasswordWidgetState();
|
||||||
@ -751,6 +756,7 @@ class _PasswordWidgetState extends State<PasswordWidget> {
|
|||||||
obscureText: !_passwordVisible,
|
obscureText: !_passwordVisible,
|
||||||
errorText: widget.errorText,
|
errorText: widget.errorText,
|
||||||
focusNode: _focusNode,
|
focusNode: _focusNode,
|
||||||
|
maxLength: widget.maxLength,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2245,6 +2251,7 @@ void changeUnlockPinDialog(String oldPin, Function() callback) {
|
|||||||
final confirmController = TextEditingController(text: oldPin);
|
final confirmController = TextEditingController(text: oldPin);
|
||||||
String? pinErrorText;
|
String? pinErrorText;
|
||||||
String? confirmationErrorText;
|
String? confirmationErrorText;
|
||||||
|
final maxLength = bind.mainMaxEncryptLen();
|
||||||
gFFI.dialogManager.show((setState, close, context) {
|
gFFI.dialogManager.show((setState, close, context) {
|
||||||
submit() async {
|
submit() async {
|
||||||
pinErrorText = null;
|
pinErrorText = null;
|
||||||
@ -2278,12 +2285,14 @@ void changeUnlockPinDialog(String oldPin, Function() callback) {
|
|||||||
controller: pinController,
|
controller: pinController,
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
errorText: pinErrorText,
|
errorText: pinErrorText,
|
||||||
|
maxLength: maxLength,
|
||||||
),
|
),
|
||||||
DialogTextField(
|
DialogTextField(
|
||||||
title: translate('Confirmation'),
|
title: translate('Confirmation'),
|
||||||
controller: confirmController,
|
controller: confirmController,
|
||||||
obscureText: true,
|
obscureText: true,
|
||||||
errorText: confirmationErrorText,
|
errorText: confirmationErrorText,
|
||||||
|
maxLength: maxLength,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
).marginOnly(bottom: 12),
|
).marginOnly(bottom: 12),
|
||||||
|
@ -1200,6 +1200,7 @@ class MyGroupPeerCard extends BasePeerCard {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _rdpDialog(String id) async {
|
void _rdpDialog(String id) async {
|
||||||
|
final maxLength = bind.mainMaxEncryptLen();
|
||||||
final port = await bind.mainGetPeerOption(id: id, key: 'rdp_port');
|
final port = await bind.mainGetPeerOption(id: id, key: 'rdp_port');
|
||||||
final username = await bind.mainGetPeerOption(id: id, key: 'rdp_username');
|
final username = await bind.mainGetPeerOption(id: id, key: 'rdp_username');
|
||||||
final portController = TextEditingController(text: port);
|
final portController = TextEditingController(text: port);
|
||||||
@ -1288,6 +1289,7 @@ void _rdpDialog(String id) async {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Obx(() => TextField(
|
child: Obx(() => TextField(
|
||||||
obscureText: secure.value,
|
obscureText: secure.value,
|
||||||
|
maxLength: maxLength,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: isDesktop
|
labelText: isDesktop
|
||||||
? null
|
? null
|
||||||
|
@ -857,6 +857,7 @@ void setPasswordDialog({VoidCallback? notEmptyCallback}) async {
|
|||||||
// SpecialCharacterValidationRule(),
|
// SpecialCharacterValidationRule(),
|
||||||
MinCharactersValidationRule(8),
|
MinCharactersValidationRule(8),
|
||||||
];
|
];
|
||||||
|
final maxLength = bind.mainMaxEncryptLen();
|
||||||
|
|
||||||
gFFI.dialogManager.show((setState, close, context) {
|
gFFI.dialogManager.show((setState, close, context) {
|
||||||
submit() {
|
submit() {
|
||||||
@ -915,6 +916,7 @@ void setPasswordDialog({VoidCallback? notEmptyCallback}) async {
|
|||||||
errMsg0 = '';
|
errMsg0 = '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
maxLength: maxLength,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@ -941,6 +943,7 @@ void setPasswordDialog({VoidCallback? notEmptyCallback}) async {
|
|||||||
errMsg1 = '';
|
errMsg1 = '';
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
maxLength: maxLength,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -2512,6 +2512,7 @@ void changeSocks5Proxy() async {
|
|||||||
: Icons.visibility))),
|
: Icons.visibility))),
|
||||||
controller: pwdController,
|
controller: pwdController,
|
||||||
enabled: !isOptFixed,
|
enabled: !isOptFixed,
|
||||||
|
maxLength: bind.mainMaxEncryptLen(),
|
||||||
)),
|
)),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
@ -39,7 +39,7 @@ pub const REG_INTERVAL: i64 = 15_000;
|
|||||||
pub const COMPRESS_LEVEL: i32 = 3;
|
pub const COMPRESS_LEVEL: i32 = 3;
|
||||||
const SERIAL: i32 = 3;
|
const SERIAL: i32 = 3;
|
||||||
const PASSWORD_ENC_VERSION: &str = "00";
|
const PASSWORD_ENC_VERSION: &str = "00";
|
||||||
const ENCRYPT_MAX_LEN: usize = 128;
|
pub const ENCRYPT_MAX_LEN: usize = 128; // used for password, pin, etc, not for all
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
|
@ -89,11 +89,11 @@ pub fn encrypt_str_or_original(s: &str, version: &str, max_len: usize) -> String
|
|||||||
log::error!("Duplicate encryption!");
|
log::error!("Duplicate encryption!");
|
||||||
return s.to_owned();
|
return s.to_owned();
|
||||||
}
|
}
|
||||||
if s.bytes().len() > max_len {
|
if s.chars().count() > max_len {
|
||||||
return String::default();
|
return String::default();
|
||||||
}
|
}
|
||||||
if version == "00" {
|
if version == "00" {
|
||||||
if let Ok(s) = encrypt(s.as_bytes(), max_len) {
|
if let Ok(s) = encrypt(s.as_bytes()) {
|
||||||
return version.to_owned() + &s;
|
return version.to_owned() + &s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ pub fn encrypt_vec_or_original(v: &[u8], version: &str, max_len: usize) -> Vec<u
|
|||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
if version == "00" {
|
if version == "00" {
|
||||||
if let Ok(s) = encrypt(v, max_len) {
|
if let Ok(s) = encrypt(v) {
|
||||||
let mut version = version.to_owned().into_bytes();
|
let mut version = version.to_owned().into_bytes();
|
||||||
version.append(&mut s.into_bytes());
|
version.append(&mut s.into_bytes());
|
||||||
return version;
|
return version;
|
||||||
@ -155,8 +155,8 @@ pub fn decrypt_vec_or_original(v: &[u8], current_version: &str) -> (Vec<u8>, boo
|
|||||||
(v.to_owned(), false, !v.is_empty())
|
(v.to_owned(), false, !v.is_empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn encrypt(v: &[u8], max_len: usize) -> Result<String, ()> {
|
fn encrypt(v: &[u8]) -> Result<String, ()> {
|
||||||
if !v.is_empty() && v.len() <= max_len {
|
if !v.is_empty() {
|
||||||
symmetric_crypt(v, true).map(|v| base64::encode(v, base64::Variant::Original))
|
symmetric_crypt(v, true).map(|v| base64::encode(v, base64::Variant::Original))
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
|
@ -2282,6 +2282,10 @@ pub fn main_clear_trusted_devices() {
|
|||||||
clear_trusted_devices()
|
clear_trusted_devices()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn main_max_encrypt_len() -> SyncReturn<usize> {
|
||||||
|
SyncReturn(max_encrypt_len())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn session_request_new_display_init_msgs(session_id: SessionID, display: usize) {
|
pub fn session_request_new_display_init_msgs(session_id: SessionID, display: usize) {
|
||||||
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
|
if let Some(session) = sessions::get_session_by_session_id(&session_id) {
|
||||||
session.request_init_msgs(display);
|
session.request_init_msgs(display);
|
||||||
|
27
src/ipc.rs
27
src/ipc.rs
@ -928,16 +928,23 @@ pub fn set_permanent_password(v: String) -> ResultType<()> {
|
|||||||
pub fn set_unlock_pin(v: String, translate: bool) -> ResultType<()> {
|
pub fn set_unlock_pin(v: String, translate: bool) -> ResultType<()> {
|
||||||
let v = v.trim().to_owned();
|
let v = v.trim().to_owned();
|
||||||
let min_len = 4;
|
let min_len = 4;
|
||||||
if !v.is_empty() && v.len() < min_len {
|
let max_len = crate::ui_interface::max_encrypt_len();
|
||||||
let err = if translate {
|
let len = v.chars().count();
|
||||||
crate::lang::translate(
|
if !v.is_empty() {
|
||||||
"Requires at least {".to_string() + &format!("{min_len}") + "} characters",
|
if len < min_len {
|
||||||
)
|
let err = if translate {
|
||||||
} else {
|
crate::lang::translate(
|
||||||
// Sometimes, translated can't show normally in command line
|
"Requires at least {".to_string() + &format!("{min_len}") + "} characters",
|
||||||
format!("Requires at least {} characters", min_len)
|
)
|
||||||
};
|
} else {
|
||||||
bail!(err);
|
// Sometimes, translated can't show normally in command line
|
||||||
|
format!("Requires at least {} characters", min_len)
|
||||||
|
};
|
||||||
|
bail!(err);
|
||||||
|
}
|
||||||
|
if len > max_len {
|
||||||
|
bail!("No more than {max_len} characters");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Config::set_unlock_pin(&v);
|
Config::set_unlock_pin(&v);
|
||||||
set_config("unlock-pin", v)
|
set_config("unlock-pin", v)
|
||||||
|
@ -1495,3 +1495,8 @@ pub fn clear_trusted_devices() {
|
|||||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||||
ipc::clear_trusted_devices();
|
ipc::clear_trusted_devices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "flutter")]
|
||||||
|
pub fn max_encrypt_len() -> usize {
|
||||||
|
hbb_common::config::ENCRYPT_MAX_LEN
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user