complex pernament password

lowercase, uppercase, digit, length>=8

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages
2023-01-16 19:47:58 +08:00
parent 2a7f8d5367
commit 9aecd28702
34 changed files with 468 additions and 65 deletions

View File

@@ -6,6 +6,7 @@ import 'package:auto_size_text/auto_size_text.dart';
import 'package:flutter/material.dart' hide MenuItem;
import 'package:flutter/services.dart';
import 'package:flutter_hbb/common.dart';
import 'package:flutter_hbb/common/widgets/custom_password.dart';
import 'package:flutter_hbb/consts.dart';
import 'package:flutter_hbb/desktop/pages/connection_page.dart';
import 'package:flutter_hbb/desktop/pages/desktop_setting_page.dart';
@@ -543,6 +544,14 @@ void setPasswordDialog() async {
final p1 = TextEditingController(text: pw);
var errMsg0 = "";
var errMsg1 = "";
final RxString rxPass = p0.text.obs;
final rules = [
DigitValidationRule(),
UppercaseValidationRule(),
LowercaseValidationRule(),
// SpecialCharacterValidationRule(),
MinCharactersValidationRule(8),
];
gFFI.dialogManager.show((setState, close) {
submit() {
@@ -551,15 +560,20 @@ void setPasswordDialog() async {
errMsg1 = "";
});
final pass = p0.text.trim();
if (pass.length < 6 && pass.isNotEmpty) {
setState(() {
errMsg0 = translate("Too short, at least 6 characters.");
});
return;
if (pass.isNotEmpty) {
for (var r in rules) {
if (!r.validate(pass)) {
setState(() {
errMsg0 = '${translate('Prompt')}: ${r.name}';
});
return;
}
}
}
if (p1.text.trim() != pass) {
setState(() {
errMsg1 = translate("The confirmation is not identical.");
errMsg1 =
'${translate('Prompt')}: ${translate("The confirmation is not identical.")}';
});
return;
}
@@ -579,23 +593,44 @@ void setPasswordDialog() async {
),
Row(
children: [
ConstrainedBox(
constraints: const BoxConstraints(minWidth: 100),
child: Text(
"${translate('Password')}:",
textAlign: TextAlign.start,
).marginOnly(bottom: 16.0)),
const SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
obscureText: true,
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.all(15),
labelText: translate('Password'),
border: const OutlineInputBorder(),
errorText: errMsg0.isNotEmpty ? errMsg0 : null),
controller: p0,
focusNode: FocusNode()..requestFocus(),
onChanged: (value) {
rxPass.value = value;
},
),
),
],
),
Row(
children: [
Expanded(child: PasswordStrengthIndicator(password: rxPass)),
],
).marginSymmetric(vertical: 8),
const SizedBox(
height: 8.0,
),
Row(
children: [
Expanded(
child: TextField(
obscureText: true,
decoration: InputDecoration(
isDense: true,
contentPadding: EdgeInsets.all(15),
border: const OutlineInputBorder(),
labelText: translate('Confirmation'),
errorText: errMsg1.isNotEmpty ? errMsg1 : null),
controller: p1,
),
),
],
@@ -603,26 +638,24 @@ void setPasswordDialog() async {
const SizedBox(
height: 8.0,
),
Row(
children: [
ConstrainedBox(
constraints: const BoxConstraints(minWidth: 100),
child: Text("${translate('Confirmation')}:")
.marginOnly(bottom: 16.0)),
const SizedBox(
width: 24.0,
),
Expanded(
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: const OutlineInputBorder(),
errorText: errMsg1.isNotEmpty ? errMsg1 : null),
controller: p1,
),
),
],
),
Obx(() => Wrap(
runSpacing: 8,
spacing: 4,
children: rules.map((e) {
var checked = e.validate(rxPass.value.trim());
return Chip(
label: Text(
e.name,
style: TextStyle(
color: checked
? const Color(0xFF0A9471)
: Color.fromARGB(255, 198, 86, 157)),
),
backgroundColor: checked
? const Color(0xFFD0F7ED)
: Color.fromARGB(255, 247, 205, 232));
}).toList(),
))
],
),
),