use-password-policy 2.0.0 → 3.0.0
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/CHANGELOG.md +37 -0
- package/LICENSE +21 -0
- package/README.md +232 -135
- package/dist/core.d.mts +255 -0
- package/dist/core.d.ts +255 -0
- package/dist/core.js +468 -0
- package/dist/core.mjs +431 -0
- package/dist/index.d.mts +292 -9
- package/dist/index.d.ts +292 -9
- package/dist/index.js +635 -190
- package/dist/index.mjs +621 -188
- package/dist/styles.css +80 -0
- package/package.json +93 -27
package/dist/core.d.mts
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A small, bundled list of the most common passwords and password "base words".
|
|
3
|
+
* Matching is case-insensitive and also catches simple variations
|
|
4
|
+
* (trailing digits/symbols, a leading number, and common leet swaps),
|
|
5
|
+
* so "Password123!", "P@ssw0rd" and "qwerty2024" are all caught.
|
|
6
|
+
*
|
|
7
|
+
* It is intentionally small (a few KB) — for full coverage, pair it with
|
|
8
|
+
* `checkPwnedPassword` / `usePwnedPassword` (Have I Been Pwned).
|
|
9
|
+
*/
|
|
10
|
+
declare const COMMON_PASSWORDS: readonly string[];
|
|
11
|
+
|
|
12
|
+
/** Built-in strength labels, weakest to strongest. */
|
|
13
|
+
type StrengthLabel = 'Very Weak' | 'Weak' | 'Medium' | 'Strong' | 'Very Strong';
|
|
14
|
+
/** Text for a rule: a plain string, or a function of the resolved options (handy for i18n). */
|
|
15
|
+
type RuleMessage = string | ((options: ResolvedPolicyOptions) => string);
|
|
16
|
+
/**
|
|
17
|
+
* A single validation rule. Used for both built-in and custom rules.
|
|
18
|
+
*/
|
|
19
|
+
interface PolicyRule {
|
|
20
|
+
/** Unique key. Appears in `policyState` and `requirements`. */
|
|
21
|
+
name: string;
|
|
22
|
+
/** For built-in rules: the option that switches the rule on. */
|
|
23
|
+
optionsKey?: keyof PasswordPolicyOptions;
|
|
24
|
+
/** Return `true` when the password passes. */
|
|
25
|
+
test: (password: string, options: ResolvedPolicyOptions) => boolean;
|
|
26
|
+
/** Human-readable requirement, e.g. "No spaces". Falls back to a prettified `name`. */
|
|
27
|
+
message?: RuleMessage;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Result of a strength estimator such as zxcvbn.
|
|
31
|
+
* `score` uses the zxcvbn scale: 0 (too guessable) … 4 (very unguessable).
|
|
32
|
+
*/
|
|
33
|
+
interface StrengthEstimate {
|
|
34
|
+
score: 0 | 1 | 2 | 3 | 4;
|
|
35
|
+
/** Optional hint to show the user, e.g. "This is a very common password". */
|
|
36
|
+
feedback?: string;
|
|
37
|
+
}
|
|
38
|
+
type StrengthEstimator = (password: string) => StrengthEstimate;
|
|
39
|
+
/** Every option is optional. Omitted options fall back to the defaults. */
|
|
40
|
+
interface PasswordPolicyOptions {
|
|
41
|
+
/** The password to validate (hook only — `validatePassword` takes it as the first argument). */
|
|
42
|
+
password?: string;
|
|
43
|
+
/** Minimum length. Default `8`. */
|
|
44
|
+
minLength?: number;
|
|
45
|
+
/** Maximum length. Default `0` (no maximum). */
|
|
46
|
+
maxLength?: number;
|
|
47
|
+
/** Require a lowercase letter. Default `true`. */
|
|
48
|
+
lowercaseCheck?: boolean;
|
|
49
|
+
/** Require an uppercase letter. Default `true`. */
|
|
50
|
+
uppercaseCheck?: boolean;
|
|
51
|
+
/** Require a digit. Default `true`. */
|
|
52
|
+
numberCheck?: boolean;
|
|
53
|
+
/** Require a special character. Default `true`. */
|
|
54
|
+
specialCharCheck?: boolean;
|
|
55
|
+
/** Reject very common passwords ("password", "qwerty123", "Password1!" …). Default `false`. */
|
|
56
|
+
commonPasswordCheck?: boolean;
|
|
57
|
+
/** Replace the built-in common-password list. */
|
|
58
|
+
commonPasswords?: readonly string[];
|
|
59
|
+
/**
|
|
60
|
+
* When set (even to `''`), adds a `match` rule that passes only if
|
|
61
|
+
* `password === confirmPassword`.
|
|
62
|
+
*/
|
|
63
|
+
confirmPassword?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Plug in a real strength estimator (e.g. zxcvbn via `fromZxcvbn`).
|
|
66
|
+
* When set, `strengthLabel` and `strengthPercent` come from the estimator.
|
|
67
|
+
*/
|
|
68
|
+
strengthEstimator?: StrengthEstimator;
|
|
69
|
+
/** With `strengthEstimator`: minimum score (0–4) required. Adds a `strength` rule. */
|
|
70
|
+
minStrength?: 0 | 1 | 2 | 3 | 4;
|
|
71
|
+
/** Your own rules, checked after the built-in ones. */
|
|
72
|
+
customRules?: PolicyRule[];
|
|
73
|
+
/** Override requirement text per rule name, e.g. `{ minLength: 'Mindestens 8 Zeichen' }`. */
|
|
74
|
+
messages?: Partial<Record<string, RuleMessage>>;
|
|
75
|
+
lowercaseRegex?: RegExp;
|
|
76
|
+
uppercaseRegex?: RegExp;
|
|
77
|
+
numberRegex?: RegExp;
|
|
78
|
+
specialCharRegex?: RegExp;
|
|
79
|
+
}
|
|
80
|
+
/** Options after defaults are applied. Passed to every rule's `test`. */
|
|
81
|
+
type ResolvedPolicyOptions = Required<Omit<PasswordPolicyOptions, 'password' | 'confirmPassword' | 'strengthEstimator' | 'minStrength'>> & Pick<PasswordPolicyOptions, 'confirmPassword' | 'strengthEstimator' | 'minStrength'>;
|
|
82
|
+
/** @deprecated Use `ResolvedPolicyOptions`. */
|
|
83
|
+
type PolicyDefaults = ResolvedPolicyOptions;
|
|
84
|
+
/** Pass/fail for each active rule, keyed by rule name. */
|
|
85
|
+
interface PasswordPolicyState {
|
|
86
|
+
[key: string]: boolean;
|
|
87
|
+
}
|
|
88
|
+
/** One row of a requirements checklist. */
|
|
89
|
+
interface Requirement {
|
|
90
|
+
name: string;
|
|
91
|
+
passed: boolean;
|
|
92
|
+
message: string;
|
|
93
|
+
}
|
|
94
|
+
/** Result of `validatePassword` (and the hook). */
|
|
95
|
+
interface ValidationResult {
|
|
96
|
+
/** `true` only when every active rule passes. */
|
|
97
|
+
isValid: boolean;
|
|
98
|
+
/** Pass/fail per rule name. */
|
|
99
|
+
policyState: PasswordPolicyState;
|
|
100
|
+
/** Ordered checklist with human-readable messages. */
|
|
101
|
+
requirements: Requirement[];
|
|
102
|
+
/** Messages of the rules that failed, in order. Handy for form errors. */
|
|
103
|
+
errors: string[];
|
|
104
|
+
/** Number of rules that passed. */
|
|
105
|
+
strengthScore: number;
|
|
106
|
+
/** 0–1. Share of rules passed, or the estimator score / 4 when an estimator is set. */
|
|
107
|
+
strengthPercent: number;
|
|
108
|
+
strengthLabel: StrengthLabel;
|
|
109
|
+
/** The estimator's result, if `strengthEstimator` is set. */
|
|
110
|
+
estimate?: StrengthEstimate;
|
|
111
|
+
}
|
|
112
|
+
/** What `usePasswordPolicy` returns. */
|
|
113
|
+
interface HookReturnValue extends ValidationResult {
|
|
114
|
+
password?: string;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface CheckPwnedOptions {
|
|
118
|
+
/** Abort the request (e.g. when the user keeps typing). */
|
|
119
|
+
signal?: AbortSignal;
|
|
120
|
+
/** Custom fetch implementation. Defaults to the global `fetch`. */
|
|
121
|
+
fetch?: typeof fetch;
|
|
122
|
+
/** Range API base URL. Defaults to Have I Been Pwned. */
|
|
123
|
+
endpoint?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Ask HIBP to pad the response so its size doesn't hint at the result.
|
|
126
|
+
* Sends an `Add-Padding` header. Default `false`.
|
|
127
|
+
*/
|
|
128
|
+
padding?: boolean;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* How many times this password appears in known data breaches, using the
|
|
132
|
+
* Have I Been Pwned range API (k-anonymity). Only the first 5 characters of
|
|
133
|
+
* the password's SHA-1 hash leave the device — never the password itself.
|
|
134
|
+
*
|
|
135
|
+
* Resolves to `0` when the password was not found.
|
|
136
|
+
*/
|
|
137
|
+
declare function checkPwnedPassword(password: string, options?: CheckPwnedOptions): Promise<number>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* use-password-policy/core
|
|
141
|
+
*
|
|
142
|
+
* Framework-free password validation. No React import, so it runs anywhere:
|
|
143
|
+
* the browser, Node, Deno, Bun, edge functions — which lets you enforce the
|
|
144
|
+
* exact same policy on the client and the server.
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
declare const DEFAULT_OPTIONS: ResolvedPolicyOptions;
|
|
148
|
+
/**
|
|
149
|
+
* Ready-made policies. Spread one and override what you need:
|
|
150
|
+
* `usePasswordPolicy({ ...presets.nist, password })`
|
|
151
|
+
*/
|
|
152
|
+
declare const presets: {
|
|
153
|
+
/** The classic checklist (these are also the defaults): 8+ chars, upper, lower, number, symbol. */
|
|
154
|
+
classic: {
|
|
155
|
+
minLength: number;
|
|
156
|
+
lowercaseCheck: true;
|
|
157
|
+
uppercaseCheck: true;
|
|
158
|
+
numberCheck: true;
|
|
159
|
+
specialCharCheck: true;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* NIST SP 800-63B-4 (Aug 2025) for passwords used on their own:
|
|
163
|
+
* at least 15 characters, allow up to 64, no composition rules, block common passwords.
|
|
164
|
+
*/
|
|
165
|
+
nist: {
|
|
166
|
+
minLength: number;
|
|
167
|
+
maxLength: number;
|
|
168
|
+
lowercaseCheck: false;
|
|
169
|
+
uppercaseCheck: false;
|
|
170
|
+
numberCheck: false;
|
|
171
|
+
specialCharCheck: false;
|
|
172
|
+
commonPasswordCheck: true;
|
|
173
|
+
};
|
|
174
|
+
/** NIST SP 800-63B-4 when the password is one factor of MFA: at least 8 characters. */
|
|
175
|
+
nistMfa: {
|
|
176
|
+
minLength: number;
|
|
177
|
+
maxLength: number;
|
|
178
|
+
lowercaseCheck: false;
|
|
179
|
+
uppercaseCheck: false;
|
|
180
|
+
numberCheck: false;
|
|
181
|
+
specialCharCheck: false;
|
|
182
|
+
commonPasswordCheck: true;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
declare const DEFAULT_MESSAGES: Record<string, RuleMessage>;
|
|
186
|
+
/** Merge user options over the defaults, ignoring keys set to `undefined`. */
|
|
187
|
+
declare function resolveOptions(options?: PasswordPolicyOptions): ResolvedPolicyOptions;
|
|
188
|
+
/**
|
|
189
|
+
* `true` if the password is on the list, or is a list entry with simple
|
|
190
|
+
* decoration: trailing digits/symbols ("password123!"), a leading number
|
|
191
|
+
* ("123qwerty") or leet swaps ("p@ssw0rd").
|
|
192
|
+
*/
|
|
193
|
+
declare function isCommonPassword(password: string, list?: readonly string[]): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Validate a password against a policy. Pure and synchronous.
|
|
196
|
+
*
|
|
197
|
+
* ```ts
|
|
198
|
+
* import { validatePassword, presets } from 'use-password-policy/core';
|
|
199
|
+
* const { isValid, errors } = validatePassword(req.body.password, presets.nist);
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
declare function validatePassword(password: string, options?: PasswordPolicyOptions): ValidationResult;
|
|
203
|
+
/** Anything shaped like the result of `zxcvbn(password)` or `@zxcvbn-ts/core`'s `zxcvbn(password)`. */
|
|
204
|
+
interface ZxcvbnLikeResult {
|
|
205
|
+
score: number;
|
|
206
|
+
feedback?: {
|
|
207
|
+
warning?: string | null;
|
|
208
|
+
suggestions?: readonly string[];
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
type ZxcvbnFn = (password: string, userInputs?: (string | number)[]) => ZxcvbnLikeResult;
|
|
212
|
+
/**
|
|
213
|
+
* Wrap zxcvbn as a `strengthEstimator`. Accepts either a function
|
|
214
|
+
* (`zxcvbn` package, @zxcvbn-ts v3) or an object with `check`
|
|
215
|
+
* (@zxcvbn-ts v4's `new ZxcvbnFactory(options)`).
|
|
216
|
+
*
|
|
217
|
+
* ```ts
|
|
218
|
+
* import { ZxcvbnFactory } from '@zxcvbn-ts/core';
|
|
219
|
+
* const zxcvbn = new ZxcvbnFactory(options);
|
|
220
|
+
* usePasswordPolicy({ password, strengthEstimator: fromZxcvbn(zxcvbn), minStrength: 3 });
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
declare function fromZxcvbn(zxcvbn: ZxcvbnFn | {
|
|
224
|
+
check: ZxcvbnFn;
|
|
225
|
+
}, userInputs?: (string | number)[]): StrengthEstimator;
|
|
226
|
+
/** Minimal shape of Zod's refinement context (works with Zod 3 and 4). */
|
|
227
|
+
interface ZodLikeRefinementCtx {
|
|
228
|
+
addIssue(issue: {
|
|
229
|
+
code: 'custom';
|
|
230
|
+
message: string;
|
|
231
|
+
}): void;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Use your policy inside a Zod schema:
|
|
235
|
+
*
|
|
236
|
+
* ```ts
|
|
237
|
+
* const schema = z.object({ password: z.string().superRefine(zodPasswordRule(policy)) });
|
|
238
|
+
* ```
|
|
239
|
+
* Adds one issue per failed rule (or only the first with `{ allErrors: false }`).
|
|
240
|
+
*/
|
|
241
|
+
declare function zodPasswordRule(options?: PasswordPolicyOptions, { allErrors }?: {
|
|
242
|
+
allErrors?: boolean | undefined;
|
|
243
|
+
}): (value: string, ctx: ZodLikeRefinementCtx) => void;
|
|
244
|
+
/**
|
|
245
|
+
* A validate function that returns `true` or the first error message.
|
|
246
|
+
* Drops straight into react-hook-form's `validate`, and works with anything
|
|
247
|
+
* that uses the same convention.
|
|
248
|
+
*
|
|
249
|
+
* ```ts
|
|
250
|
+
* register('password', { validate: passwordValidator(policy) })
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
declare function passwordValidator(options?: PasswordPolicyOptions): (value: string) => true | string;
|
|
254
|
+
|
|
255
|
+
export { COMMON_PASSWORDS, type CheckPwnedOptions, DEFAULT_MESSAGES, DEFAULT_OPTIONS, type HookReturnValue, type PasswordPolicyOptions, type PasswordPolicyState, type PolicyDefaults, type PolicyRule, type Requirement, type ResolvedPolicyOptions, type RuleMessage, type StrengthEstimate, type StrengthEstimator, type StrengthLabel, type ValidationResult, type ZodLikeRefinementCtx, type ZxcvbnLikeResult, checkPwnedPassword, fromZxcvbn, isCommonPassword, passwordValidator, presets, resolveOptions, validatePassword, zodPasswordRule };
|
package/dist/core.d.ts
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A small, bundled list of the most common passwords and password "base words".
|
|
3
|
+
* Matching is case-insensitive and also catches simple variations
|
|
4
|
+
* (trailing digits/symbols, a leading number, and common leet swaps),
|
|
5
|
+
* so "Password123!", "P@ssw0rd" and "qwerty2024" are all caught.
|
|
6
|
+
*
|
|
7
|
+
* It is intentionally small (a few KB) — for full coverage, pair it with
|
|
8
|
+
* `checkPwnedPassword` / `usePwnedPassword` (Have I Been Pwned).
|
|
9
|
+
*/
|
|
10
|
+
declare const COMMON_PASSWORDS: readonly string[];
|
|
11
|
+
|
|
12
|
+
/** Built-in strength labels, weakest to strongest. */
|
|
13
|
+
type StrengthLabel = 'Very Weak' | 'Weak' | 'Medium' | 'Strong' | 'Very Strong';
|
|
14
|
+
/** Text for a rule: a plain string, or a function of the resolved options (handy for i18n). */
|
|
15
|
+
type RuleMessage = string | ((options: ResolvedPolicyOptions) => string);
|
|
16
|
+
/**
|
|
17
|
+
* A single validation rule. Used for both built-in and custom rules.
|
|
18
|
+
*/
|
|
19
|
+
interface PolicyRule {
|
|
20
|
+
/** Unique key. Appears in `policyState` and `requirements`. */
|
|
21
|
+
name: string;
|
|
22
|
+
/** For built-in rules: the option that switches the rule on. */
|
|
23
|
+
optionsKey?: keyof PasswordPolicyOptions;
|
|
24
|
+
/** Return `true` when the password passes. */
|
|
25
|
+
test: (password: string, options: ResolvedPolicyOptions) => boolean;
|
|
26
|
+
/** Human-readable requirement, e.g. "No spaces". Falls back to a prettified `name`. */
|
|
27
|
+
message?: RuleMessage;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Result of a strength estimator such as zxcvbn.
|
|
31
|
+
* `score` uses the zxcvbn scale: 0 (too guessable) … 4 (very unguessable).
|
|
32
|
+
*/
|
|
33
|
+
interface StrengthEstimate {
|
|
34
|
+
score: 0 | 1 | 2 | 3 | 4;
|
|
35
|
+
/** Optional hint to show the user, e.g. "This is a very common password". */
|
|
36
|
+
feedback?: string;
|
|
37
|
+
}
|
|
38
|
+
type StrengthEstimator = (password: string) => StrengthEstimate;
|
|
39
|
+
/** Every option is optional. Omitted options fall back to the defaults. */
|
|
40
|
+
interface PasswordPolicyOptions {
|
|
41
|
+
/** The password to validate (hook only — `validatePassword` takes it as the first argument). */
|
|
42
|
+
password?: string;
|
|
43
|
+
/** Minimum length. Default `8`. */
|
|
44
|
+
minLength?: number;
|
|
45
|
+
/** Maximum length. Default `0` (no maximum). */
|
|
46
|
+
maxLength?: number;
|
|
47
|
+
/** Require a lowercase letter. Default `true`. */
|
|
48
|
+
lowercaseCheck?: boolean;
|
|
49
|
+
/** Require an uppercase letter. Default `true`. */
|
|
50
|
+
uppercaseCheck?: boolean;
|
|
51
|
+
/** Require a digit. Default `true`. */
|
|
52
|
+
numberCheck?: boolean;
|
|
53
|
+
/** Require a special character. Default `true`. */
|
|
54
|
+
specialCharCheck?: boolean;
|
|
55
|
+
/** Reject very common passwords ("password", "qwerty123", "Password1!" …). Default `false`. */
|
|
56
|
+
commonPasswordCheck?: boolean;
|
|
57
|
+
/** Replace the built-in common-password list. */
|
|
58
|
+
commonPasswords?: readonly string[];
|
|
59
|
+
/**
|
|
60
|
+
* When set (even to `''`), adds a `match` rule that passes only if
|
|
61
|
+
* `password === confirmPassword`.
|
|
62
|
+
*/
|
|
63
|
+
confirmPassword?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Plug in a real strength estimator (e.g. zxcvbn via `fromZxcvbn`).
|
|
66
|
+
* When set, `strengthLabel` and `strengthPercent` come from the estimator.
|
|
67
|
+
*/
|
|
68
|
+
strengthEstimator?: StrengthEstimator;
|
|
69
|
+
/** With `strengthEstimator`: minimum score (0–4) required. Adds a `strength` rule. */
|
|
70
|
+
minStrength?: 0 | 1 | 2 | 3 | 4;
|
|
71
|
+
/** Your own rules, checked after the built-in ones. */
|
|
72
|
+
customRules?: PolicyRule[];
|
|
73
|
+
/** Override requirement text per rule name, e.g. `{ minLength: 'Mindestens 8 Zeichen' }`. */
|
|
74
|
+
messages?: Partial<Record<string, RuleMessage>>;
|
|
75
|
+
lowercaseRegex?: RegExp;
|
|
76
|
+
uppercaseRegex?: RegExp;
|
|
77
|
+
numberRegex?: RegExp;
|
|
78
|
+
specialCharRegex?: RegExp;
|
|
79
|
+
}
|
|
80
|
+
/** Options after defaults are applied. Passed to every rule's `test`. */
|
|
81
|
+
type ResolvedPolicyOptions = Required<Omit<PasswordPolicyOptions, 'password' | 'confirmPassword' | 'strengthEstimator' | 'minStrength'>> & Pick<PasswordPolicyOptions, 'confirmPassword' | 'strengthEstimator' | 'minStrength'>;
|
|
82
|
+
/** @deprecated Use `ResolvedPolicyOptions`. */
|
|
83
|
+
type PolicyDefaults = ResolvedPolicyOptions;
|
|
84
|
+
/** Pass/fail for each active rule, keyed by rule name. */
|
|
85
|
+
interface PasswordPolicyState {
|
|
86
|
+
[key: string]: boolean;
|
|
87
|
+
}
|
|
88
|
+
/** One row of a requirements checklist. */
|
|
89
|
+
interface Requirement {
|
|
90
|
+
name: string;
|
|
91
|
+
passed: boolean;
|
|
92
|
+
message: string;
|
|
93
|
+
}
|
|
94
|
+
/** Result of `validatePassword` (and the hook). */
|
|
95
|
+
interface ValidationResult {
|
|
96
|
+
/** `true` only when every active rule passes. */
|
|
97
|
+
isValid: boolean;
|
|
98
|
+
/** Pass/fail per rule name. */
|
|
99
|
+
policyState: PasswordPolicyState;
|
|
100
|
+
/** Ordered checklist with human-readable messages. */
|
|
101
|
+
requirements: Requirement[];
|
|
102
|
+
/** Messages of the rules that failed, in order. Handy for form errors. */
|
|
103
|
+
errors: string[];
|
|
104
|
+
/** Number of rules that passed. */
|
|
105
|
+
strengthScore: number;
|
|
106
|
+
/** 0–1. Share of rules passed, or the estimator score / 4 when an estimator is set. */
|
|
107
|
+
strengthPercent: number;
|
|
108
|
+
strengthLabel: StrengthLabel;
|
|
109
|
+
/** The estimator's result, if `strengthEstimator` is set. */
|
|
110
|
+
estimate?: StrengthEstimate;
|
|
111
|
+
}
|
|
112
|
+
/** What `usePasswordPolicy` returns. */
|
|
113
|
+
interface HookReturnValue extends ValidationResult {
|
|
114
|
+
password?: string;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface CheckPwnedOptions {
|
|
118
|
+
/** Abort the request (e.g. when the user keeps typing). */
|
|
119
|
+
signal?: AbortSignal;
|
|
120
|
+
/** Custom fetch implementation. Defaults to the global `fetch`. */
|
|
121
|
+
fetch?: typeof fetch;
|
|
122
|
+
/** Range API base URL. Defaults to Have I Been Pwned. */
|
|
123
|
+
endpoint?: string;
|
|
124
|
+
/**
|
|
125
|
+
* Ask HIBP to pad the response so its size doesn't hint at the result.
|
|
126
|
+
* Sends an `Add-Padding` header. Default `false`.
|
|
127
|
+
*/
|
|
128
|
+
padding?: boolean;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* How many times this password appears in known data breaches, using the
|
|
132
|
+
* Have I Been Pwned range API (k-anonymity). Only the first 5 characters of
|
|
133
|
+
* the password's SHA-1 hash leave the device — never the password itself.
|
|
134
|
+
*
|
|
135
|
+
* Resolves to `0` when the password was not found.
|
|
136
|
+
*/
|
|
137
|
+
declare function checkPwnedPassword(password: string, options?: CheckPwnedOptions): Promise<number>;
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* use-password-policy/core
|
|
141
|
+
*
|
|
142
|
+
* Framework-free password validation. No React import, so it runs anywhere:
|
|
143
|
+
* the browser, Node, Deno, Bun, edge functions — which lets you enforce the
|
|
144
|
+
* exact same policy on the client and the server.
|
|
145
|
+
*/
|
|
146
|
+
|
|
147
|
+
declare const DEFAULT_OPTIONS: ResolvedPolicyOptions;
|
|
148
|
+
/**
|
|
149
|
+
* Ready-made policies. Spread one and override what you need:
|
|
150
|
+
* `usePasswordPolicy({ ...presets.nist, password })`
|
|
151
|
+
*/
|
|
152
|
+
declare const presets: {
|
|
153
|
+
/** The classic checklist (these are also the defaults): 8+ chars, upper, lower, number, symbol. */
|
|
154
|
+
classic: {
|
|
155
|
+
minLength: number;
|
|
156
|
+
lowercaseCheck: true;
|
|
157
|
+
uppercaseCheck: true;
|
|
158
|
+
numberCheck: true;
|
|
159
|
+
specialCharCheck: true;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* NIST SP 800-63B-4 (Aug 2025) for passwords used on their own:
|
|
163
|
+
* at least 15 characters, allow up to 64, no composition rules, block common passwords.
|
|
164
|
+
*/
|
|
165
|
+
nist: {
|
|
166
|
+
minLength: number;
|
|
167
|
+
maxLength: number;
|
|
168
|
+
lowercaseCheck: false;
|
|
169
|
+
uppercaseCheck: false;
|
|
170
|
+
numberCheck: false;
|
|
171
|
+
specialCharCheck: false;
|
|
172
|
+
commonPasswordCheck: true;
|
|
173
|
+
};
|
|
174
|
+
/** NIST SP 800-63B-4 when the password is one factor of MFA: at least 8 characters. */
|
|
175
|
+
nistMfa: {
|
|
176
|
+
minLength: number;
|
|
177
|
+
maxLength: number;
|
|
178
|
+
lowercaseCheck: false;
|
|
179
|
+
uppercaseCheck: false;
|
|
180
|
+
numberCheck: false;
|
|
181
|
+
specialCharCheck: false;
|
|
182
|
+
commonPasswordCheck: true;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
declare const DEFAULT_MESSAGES: Record<string, RuleMessage>;
|
|
186
|
+
/** Merge user options over the defaults, ignoring keys set to `undefined`. */
|
|
187
|
+
declare function resolveOptions(options?: PasswordPolicyOptions): ResolvedPolicyOptions;
|
|
188
|
+
/**
|
|
189
|
+
* `true` if the password is on the list, or is a list entry with simple
|
|
190
|
+
* decoration: trailing digits/symbols ("password123!"), a leading number
|
|
191
|
+
* ("123qwerty") or leet swaps ("p@ssw0rd").
|
|
192
|
+
*/
|
|
193
|
+
declare function isCommonPassword(password: string, list?: readonly string[]): boolean;
|
|
194
|
+
/**
|
|
195
|
+
* Validate a password against a policy. Pure and synchronous.
|
|
196
|
+
*
|
|
197
|
+
* ```ts
|
|
198
|
+
* import { validatePassword, presets } from 'use-password-policy/core';
|
|
199
|
+
* const { isValid, errors } = validatePassword(req.body.password, presets.nist);
|
|
200
|
+
* ```
|
|
201
|
+
*/
|
|
202
|
+
declare function validatePassword(password: string, options?: PasswordPolicyOptions): ValidationResult;
|
|
203
|
+
/** Anything shaped like the result of `zxcvbn(password)` or `@zxcvbn-ts/core`'s `zxcvbn(password)`. */
|
|
204
|
+
interface ZxcvbnLikeResult {
|
|
205
|
+
score: number;
|
|
206
|
+
feedback?: {
|
|
207
|
+
warning?: string | null;
|
|
208
|
+
suggestions?: readonly string[];
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
type ZxcvbnFn = (password: string, userInputs?: (string | number)[]) => ZxcvbnLikeResult;
|
|
212
|
+
/**
|
|
213
|
+
* Wrap zxcvbn as a `strengthEstimator`. Accepts either a function
|
|
214
|
+
* (`zxcvbn` package, @zxcvbn-ts v3) or an object with `check`
|
|
215
|
+
* (@zxcvbn-ts v4's `new ZxcvbnFactory(options)`).
|
|
216
|
+
*
|
|
217
|
+
* ```ts
|
|
218
|
+
* import { ZxcvbnFactory } from '@zxcvbn-ts/core';
|
|
219
|
+
* const zxcvbn = new ZxcvbnFactory(options);
|
|
220
|
+
* usePasswordPolicy({ password, strengthEstimator: fromZxcvbn(zxcvbn), minStrength: 3 });
|
|
221
|
+
* ```
|
|
222
|
+
*/
|
|
223
|
+
declare function fromZxcvbn(zxcvbn: ZxcvbnFn | {
|
|
224
|
+
check: ZxcvbnFn;
|
|
225
|
+
}, userInputs?: (string | number)[]): StrengthEstimator;
|
|
226
|
+
/** Minimal shape of Zod's refinement context (works with Zod 3 and 4). */
|
|
227
|
+
interface ZodLikeRefinementCtx {
|
|
228
|
+
addIssue(issue: {
|
|
229
|
+
code: 'custom';
|
|
230
|
+
message: string;
|
|
231
|
+
}): void;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Use your policy inside a Zod schema:
|
|
235
|
+
*
|
|
236
|
+
* ```ts
|
|
237
|
+
* const schema = z.object({ password: z.string().superRefine(zodPasswordRule(policy)) });
|
|
238
|
+
* ```
|
|
239
|
+
* Adds one issue per failed rule (or only the first with `{ allErrors: false }`).
|
|
240
|
+
*/
|
|
241
|
+
declare function zodPasswordRule(options?: PasswordPolicyOptions, { allErrors }?: {
|
|
242
|
+
allErrors?: boolean | undefined;
|
|
243
|
+
}): (value: string, ctx: ZodLikeRefinementCtx) => void;
|
|
244
|
+
/**
|
|
245
|
+
* A validate function that returns `true` or the first error message.
|
|
246
|
+
* Drops straight into react-hook-form's `validate`, and works with anything
|
|
247
|
+
* that uses the same convention.
|
|
248
|
+
*
|
|
249
|
+
* ```ts
|
|
250
|
+
* register('password', { validate: passwordValidator(policy) })
|
|
251
|
+
* ```
|
|
252
|
+
*/
|
|
253
|
+
declare function passwordValidator(options?: PasswordPolicyOptions): (value: string) => true | string;
|
|
254
|
+
|
|
255
|
+
export { COMMON_PASSWORDS, type CheckPwnedOptions, DEFAULT_MESSAGES, DEFAULT_OPTIONS, type HookReturnValue, type PasswordPolicyOptions, type PasswordPolicyState, type PolicyDefaults, type PolicyRule, type Requirement, type ResolvedPolicyOptions, type RuleMessage, type StrengthEstimate, type StrengthEstimator, type StrengthLabel, type ValidationResult, type ZodLikeRefinementCtx, type ZxcvbnLikeResult, checkPwnedPassword, fromZxcvbn, isCommonPassword, passwordValidator, presets, resolveOptions, validatePassword, zodPasswordRule };
|