@rainersoft/utils 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +47 -1
- package/dist/index.d.ts +47 -1
- package/dist/index.js +193 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +189 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
1
3
|
var __defProp = Object.defineProperty;
|
|
2
4
|
var __export = (target, all) => {
|
|
3
5
|
for (var name in all)
|
|
@@ -807,6 +809,192 @@ function findMinMax(data, field) {
|
|
|
807
809
|
max: Math.max(...values)
|
|
808
810
|
};
|
|
809
811
|
}
|
|
812
|
+
function usePasswordStrength(password, options = {}) {
|
|
813
|
+
const {
|
|
814
|
+
minLength = 8,
|
|
815
|
+
requireUppercase = true,
|
|
816
|
+
requireLowercase = true,
|
|
817
|
+
requireNumbers = true,
|
|
818
|
+
requireSpecialChars = true,
|
|
819
|
+
customPatterns = [],
|
|
820
|
+
labels = {}
|
|
821
|
+
} = options;
|
|
822
|
+
const defaultLabels = {
|
|
823
|
+
veryWeak: "Very Weak",
|
|
824
|
+
weak: "Weak",
|
|
825
|
+
fair: "Fair",
|
|
826
|
+
good: "Good",
|
|
827
|
+
strong: "Strong",
|
|
828
|
+
enterPassword: "Enter a password",
|
|
829
|
+
useMinLength: `Use at least ${minLength} characters`,
|
|
830
|
+
addUppercase: "Add uppercase letters",
|
|
831
|
+
addLowercase: "Add lowercase letters",
|
|
832
|
+
addNumbers: "Add numbers",
|
|
833
|
+
addSpecialChars: "Add special characters (!@#$%)",
|
|
834
|
+
avoidRepeating: "Avoid repeating characters",
|
|
835
|
+
avoidCommon: "Avoid common passwords or obvious patterns"
|
|
836
|
+
};
|
|
837
|
+
const finalLabels = { ...defaultLabels, ...labels };
|
|
838
|
+
const strength = React.useMemo(() => {
|
|
839
|
+
if (!password) return 0;
|
|
840
|
+
let score = 0;
|
|
841
|
+
const length = password.length;
|
|
842
|
+
if (length >= minLength) score += 25;
|
|
843
|
+
if (length >= 12) score += 15;
|
|
844
|
+
if (length >= 16) score += 10;
|
|
845
|
+
if (/[a-z]/.test(password) && requireLowercase) score += 15;
|
|
846
|
+
if (/[A-Z]/.test(password) && requireUppercase) score += 15;
|
|
847
|
+
if (/[0-9]/.test(password) && requireNumbers) score += 15;
|
|
848
|
+
if (/[^a-zA-Z0-9]/.test(password) && requireSpecialChars) score += 20;
|
|
849
|
+
customPatterns.forEach((pattern) => {
|
|
850
|
+
if (new RegExp(pattern).test(password)) {
|
|
851
|
+
score += 5;
|
|
852
|
+
}
|
|
853
|
+
});
|
|
854
|
+
if (/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[^a-zA-Z0-9])/.test(password)) {
|
|
855
|
+
score += 10;
|
|
856
|
+
}
|
|
857
|
+
const commonPatterns = [
|
|
858
|
+
/^123456/,
|
|
859
|
+
/password/i,
|
|
860
|
+
/qwerty/i,
|
|
861
|
+
/admin/i,
|
|
862
|
+
/abc123/i,
|
|
863
|
+
/^(.)\1+$/,
|
|
864
|
+
// Caracteres repetidos
|
|
865
|
+
/^(?:[a-z]+|[A-Z]+|[0-9]+)$/
|
|
866
|
+
// Apenas um tipo de caractere
|
|
867
|
+
];
|
|
868
|
+
commonPatterns.forEach((pattern) => {
|
|
869
|
+
if (pattern.test(password)) {
|
|
870
|
+
score = Math.max(0, score - 20);
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
return Math.min(100, Math.max(0, score));
|
|
874
|
+
}, [password, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars, customPatterns]);
|
|
875
|
+
const level = React.useMemo(() => {
|
|
876
|
+
if (strength < 20) return "very-weak";
|
|
877
|
+
if (strength < 40) return "weak";
|
|
878
|
+
if (strength < 60) return "fair";
|
|
879
|
+
if (strength < 80) return "good";
|
|
880
|
+
return "strong";
|
|
881
|
+
}, [strength]);
|
|
882
|
+
const color = React.useMemo(() => {
|
|
883
|
+
switch (level) {
|
|
884
|
+
case "very-weak":
|
|
885
|
+
return "#ef4444";
|
|
886
|
+
// red-500
|
|
887
|
+
case "weak":
|
|
888
|
+
return "#f97316";
|
|
889
|
+
// orange-500
|
|
890
|
+
case "fair":
|
|
891
|
+
return "#eab308";
|
|
892
|
+
// yellow-500
|
|
893
|
+
case "good":
|
|
894
|
+
return "#22c55e";
|
|
895
|
+
// green-500
|
|
896
|
+
case "strong":
|
|
897
|
+
return "#059669";
|
|
898
|
+
// emerald-600
|
|
899
|
+
default:
|
|
900
|
+
return "#6b7280";
|
|
901
|
+
}
|
|
902
|
+
}, [level]);
|
|
903
|
+
const label = React.useMemo(() => {
|
|
904
|
+
switch (level) {
|
|
905
|
+
case "very-weak":
|
|
906
|
+
return finalLabels.veryWeak;
|
|
907
|
+
case "weak":
|
|
908
|
+
return finalLabels.weak;
|
|
909
|
+
case "fair":
|
|
910
|
+
return finalLabels.fair;
|
|
911
|
+
case "good":
|
|
912
|
+
return finalLabels.good;
|
|
913
|
+
case "strong":
|
|
914
|
+
return finalLabels.strong;
|
|
915
|
+
default:
|
|
916
|
+
return finalLabels.enterPassword;
|
|
917
|
+
}
|
|
918
|
+
}, [level, finalLabels]);
|
|
919
|
+
const validations = React.useMemo(() => {
|
|
920
|
+
return {
|
|
921
|
+
hasMinLength: password.length >= minLength,
|
|
922
|
+
hasUppercase: !requireUppercase || /[A-Z]/.test(password),
|
|
923
|
+
hasLowercase: !requireLowercase || /[a-z]/.test(password),
|
|
924
|
+
hasNumbers: !requireNumbers || /[0-9]/.test(password),
|
|
925
|
+
hasSpecialChars: !requireSpecialChars || /[^a-zA-Z0-9]/.test(password),
|
|
926
|
+
noRepeatingChars: !/^(.)\1+$/.test(password),
|
|
927
|
+
noCommonPatterns: !/123456|password|qwerty|admin|abc123/i.test(password)
|
|
928
|
+
};
|
|
929
|
+
}, [password, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);
|
|
930
|
+
const isValid = React.useMemo(() => {
|
|
931
|
+
return Object.values(validations).every(Boolean);
|
|
932
|
+
}, [validations]);
|
|
933
|
+
const suggestions = React.useMemo(() => {
|
|
934
|
+
const suggestions2 = [];
|
|
935
|
+
if (!validations.hasMinLength) {
|
|
936
|
+
suggestions2.push(finalLabels.useMinLength);
|
|
937
|
+
}
|
|
938
|
+
if (!validations.hasUppercase && requireUppercase) {
|
|
939
|
+
suggestions2.push(finalLabels.addUppercase);
|
|
940
|
+
}
|
|
941
|
+
if (!validations.hasLowercase && requireLowercase) {
|
|
942
|
+
suggestions2.push(finalLabels.addLowercase);
|
|
943
|
+
}
|
|
944
|
+
if (!validations.hasNumbers && requireNumbers) {
|
|
945
|
+
suggestions2.push(finalLabels.addNumbers);
|
|
946
|
+
}
|
|
947
|
+
if (!validations.hasSpecialChars && requireSpecialChars) {
|
|
948
|
+
suggestions2.push(finalLabels.addSpecialChars);
|
|
949
|
+
}
|
|
950
|
+
if (!validations.noRepeatingChars) {
|
|
951
|
+
suggestions2.push(finalLabels.avoidRepeating);
|
|
952
|
+
}
|
|
953
|
+
if (!validations.noCommonPatterns) {
|
|
954
|
+
suggestions2.push(finalLabels.avoidCommon);
|
|
955
|
+
}
|
|
956
|
+
return suggestions2;
|
|
957
|
+
}, [validations, finalLabels, minLength, requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);
|
|
958
|
+
const generateStrongPassword = React.useCallback((length = 16) => {
|
|
959
|
+
const uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
960
|
+
const lowercase = "abcdefghijklmnopqrstuvwxyz";
|
|
961
|
+
const numbers = "0123456789";
|
|
962
|
+
const special = "!@#$%^&*()_+-=[]{}|;:,.<>?";
|
|
963
|
+
let chars = lowercase;
|
|
964
|
+
if (requireUppercase) chars += uppercase;
|
|
965
|
+
if (requireNumbers) chars += numbers;
|
|
966
|
+
if (requireSpecialChars) chars += special;
|
|
967
|
+
let password2 = "";
|
|
968
|
+
if (requireLowercase) password2 += lowercase[Math.floor(Math.random() * lowercase.length)];
|
|
969
|
+
if (requireUppercase) password2 += uppercase[Math.floor(Math.random() * uppercase.length)];
|
|
970
|
+
if (requireNumbers) password2 += numbers[Math.floor(Math.random() * numbers.length)];
|
|
971
|
+
if (requireSpecialChars) password2 += special[Math.floor(Math.random() * special.length)];
|
|
972
|
+
for (let i = password2.length; i < length; i++) {
|
|
973
|
+
password2 += chars[Math.floor(Math.random() * chars.length)];
|
|
974
|
+
}
|
|
975
|
+
return password2.split("").sort(() => Math.random() - 0.5).join("");
|
|
976
|
+
}, [requireUppercase, requireLowercase, requireNumbers, requireSpecialChars]);
|
|
977
|
+
return {
|
|
978
|
+
// Métricas principais
|
|
979
|
+
strength,
|
|
980
|
+
level,
|
|
981
|
+
color,
|
|
982
|
+
label,
|
|
983
|
+
isValid,
|
|
984
|
+
// Validações detalhadas
|
|
985
|
+
validations,
|
|
986
|
+
// Feedback ao usuário
|
|
987
|
+
suggestions,
|
|
988
|
+
// Utilitários
|
|
989
|
+
generateStrongPassword,
|
|
990
|
+
// Estados convenientes
|
|
991
|
+
isVeryWeak: level === "very-weak",
|
|
992
|
+
isWeak: level === "weak",
|
|
993
|
+
isFair: level === "fair",
|
|
994
|
+
isGood: level === "good",
|
|
995
|
+
isStrong: level === "strong"
|
|
996
|
+
};
|
|
997
|
+
}
|
|
810
998
|
|
|
811
999
|
// src/pt-br.ts
|
|
812
1000
|
var pt_br_exports = {};
|
|
@@ -841,6 +1029,6 @@ function translateStatus2(status) {
|
|
|
841
1029
|
return translateStatus(status, "pt-BR");
|
|
842
1030
|
}
|
|
843
1031
|
|
|
844
|
-
export { CURRENCY_MAP, DEFAULT_LOCALE, calculateChange, calculateMovingAverage, capitalize, cleanText, copyToClipboard, countWords, downloadFile, extractInitials, findMinMax, formatCurrency, formatDate, formatDateTime, formatNumber2 as formatNumber, formatPercentage, formatRelativeDate, generateAvatarUrl, generateDynamicAvatarUrl, generateMockChartData, generateUniqueId, getAvatarColorFromName, getElementPosition, getStatusColor, getStatusVariant, groupDataByPeriod, isDarkMode, isElementVisible, isEmpty, isMobile, isValidAvatarUrl, isValidDate, normalizeSpaces, onDarkModeChange, onReducedMotionChange, prefersReducedMotion, pt_br_exports as ptBR, scrollToElement, scrollToPosition, scrollToTop, smoothScrollTo, textToSlug, toISOString, translateStatus, truncateText, validateEmail, validatePassword, validatePhone, validateSlug, validateText, validateUrl, validateUsername };
|
|
1032
|
+
export { CURRENCY_MAP, DEFAULT_LOCALE, calculateChange, calculateMovingAverage, capitalize, cleanText, copyToClipboard, countWords, downloadFile, extractInitials, findMinMax, formatCurrency, formatDate, formatDateTime, formatNumber2 as formatNumber, formatPercentage, formatRelativeDate, generateAvatarUrl, generateDynamicAvatarUrl, generateMockChartData, generateUniqueId, getAvatarColorFromName, getElementPosition, getStatusColor, getStatusVariant, groupDataByPeriod, isDarkMode, isElementVisible, isEmpty, isMobile, isValidAvatarUrl, isValidDate, normalizeSpaces, onDarkModeChange, onReducedMotionChange, prefersReducedMotion, pt_br_exports as ptBR, scrollToElement, scrollToPosition, scrollToTop, smoothScrollTo, textToSlug, toISOString, translateStatus, truncateText, usePasswordStrength, validateEmail, validatePassword, validatePhone, validateSlug, validateText, validateUrl, validateUsername };
|
|
845
1033
|
//# sourceMappingURL=index.mjs.map
|
|
846
1034
|
//# sourceMappingURL=index.mjs.map
|