custom_password.dart 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // https://github.com/rodrigobastosv/fancy_password_field
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_hbb/common.dart';
  4. import 'package:get/get.dart';
  5. import 'package:password_strength/password_strength.dart';
  6. abstract class ValidationRule {
  7. String get name;
  8. bool validate(String value);
  9. }
  10. class UppercaseValidationRule extends ValidationRule {
  11. @override
  12. String get name => translate('uppercase');
  13. @override
  14. bool validate(String value) {
  15. return value.runes.any((int rune) {
  16. var character = String.fromCharCode(rune);
  17. return character.toUpperCase() == character &&
  18. character.toLowerCase() != character;
  19. });
  20. }
  21. }
  22. class LowercaseValidationRule extends ValidationRule {
  23. @override
  24. String get name => translate('lowercase');
  25. @override
  26. bool validate(String value) {
  27. return value.runes.any((int rune) {
  28. var character = String.fromCharCode(rune);
  29. return character.toLowerCase() == character &&
  30. character.toUpperCase() != character;
  31. });
  32. }
  33. }
  34. class DigitValidationRule extends ValidationRule {
  35. @override
  36. String get name => translate('digit');
  37. @override
  38. bool validate(String value) {
  39. return value.contains(RegExp(r'[0-9]'));
  40. }
  41. }
  42. class SpecialCharacterValidationRule extends ValidationRule {
  43. @override
  44. String get name => translate('special character');
  45. @override
  46. bool validate(String value) {
  47. return value.contains(RegExp(r'[!@#$%^&*(),.?":{}|<>]'));
  48. }
  49. }
  50. class MinCharactersValidationRule extends ValidationRule {
  51. final int _numberOfCharacters;
  52. MinCharactersValidationRule(this._numberOfCharacters);
  53. @override
  54. String get name => translate('length>=$_numberOfCharacters');
  55. @override
  56. bool validate(String value) {
  57. return value.length >= _numberOfCharacters;
  58. }
  59. }
  60. class PasswordStrengthIndicator extends StatelessWidget {
  61. final RxString password;
  62. final double weakMedium = 0.33;
  63. final double mediumStrong = 0.67;
  64. const PasswordStrengthIndicator({Key? key, required this.password})
  65. : super(key: key);
  66. @override
  67. Widget build(BuildContext context) {
  68. return Obx(() {
  69. var strength = estimatePasswordStrength(password.value);
  70. return Row(
  71. children: [
  72. Expanded(
  73. child: _indicator(
  74. password.isEmpty ? Colors.grey : _getColor(strength))),
  75. Expanded(
  76. child: _indicator(password.isEmpty || strength < weakMedium
  77. ? Colors.grey
  78. : _getColor(strength))),
  79. Expanded(
  80. child: _indicator(password.isEmpty || strength < mediumStrong
  81. ? Colors.grey
  82. : _getColor(strength))),
  83. Text(password.isEmpty ? '' : translate(_getLabel(strength)))
  84. .marginOnly(left: password.isEmpty ? 0 : 8),
  85. ],
  86. );
  87. });
  88. }
  89. Widget _indicator(Color color) {
  90. return Container(
  91. height: 8,
  92. color: color,
  93. );
  94. }
  95. String _getLabel(double strength) {
  96. if (strength < weakMedium) {
  97. return 'Weak';
  98. } else if (strength < mediumStrong) {
  99. return 'Medium';
  100. } else {
  101. return 'Strong';
  102. }
  103. }
  104. Color _getColor(double strength) {
  105. if (strength < weakMedium) {
  106. return Colors.yellow;
  107. } else if (strength < mediumStrong) {
  108. return Colors.blue;
  109. } else {
  110. return Colors.green;
  111. }
  112. }
  113. }