auth0-password-policies 2.2.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/index.js +18 -28
- package/package.json +1 -1
- package/test/test.js +59 -21
package/index.js
CHANGED
|
@@ -43,48 +43,39 @@ const CHARACTER_TYPES = {
|
|
|
43
43
|
};
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* @typedef {Object}
|
|
47
|
-
* @property {number}
|
|
48
|
-
* @property {Array<'uppercase'|'lowercase'|'number'|'special'>}
|
|
49
|
-
* @property {'all'|'three_of_four'}
|
|
50
|
-
* @property {'allow'|'block'}
|
|
51
|
-
* @property {'allow'|'block'}
|
|
52
|
-
* @property {'error'|'truncate'}
|
|
46
|
+
* @typedef {Object} PasswordComplexityOptions
|
|
47
|
+
* @property {number} min_length - Minimum password length (1-72)
|
|
48
|
+
* @property {Array<'uppercase'|'lowercase'|'number'|'special'>} character_types - Required character types
|
|
49
|
+
* @property {'all'|'three_of_four'} character_type_rule - How many character types are required
|
|
50
|
+
* @property {'allow'|'block'} identical_characters - Whether to allow >2 identical consecutive characters
|
|
51
|
+
* @property {'allow'|'block'} sequential_characters - Whether to allow sequential alphanumeric characters
|
|
52
|
+
* @property {'error'|'truncate'} max_length_exceeded - Behavior when password exceeds max length of 72 bytes
|
|
53
53
|
*/
|
|
54
54
|
|
|
55
|
-
/**
|
|
56
|
-
* Default values for password options
|
|
57
|
-
* @constant
|
|
58
|
-
* @type {PasswordOptions}
|
|
59
|
-
*/
|
|
60
|
-
const DEFAULT_PASSWORD_OPTIONS = {
|
|
61
|
-
min_length: 15,
|
|
62
|
-
character_types: [],
|
|
63
|
-
character_type_rule: "all",
|
|
64
|
-
identical_characters: "allow",
|
|
65
|
-
sequential_characters: "allow",
|
|
66
|
-
max_length_exceeded: "error"
|
|
67
|
-
};
|
|
68
|
-
|
|
69
55
|
/**
|
|
70
56
|
* Creates a PasswordPolicy rules configuration from an Auth0
|
|
71
57
|
* `connection.options.password_options.complexity` object.
|
|
72
58
|
*
|
|
73
|
-
* @param {
|
|
59
|
+
* @param {PasswordComplexityOptions} options - Auth0 password complexity configuration
|
|
74
60
|
* @returns {Object} password-sheriff rules configuration object that can be passed to PasswordPolicy constructor
|
|
75
61
|
*/
|
|
76
|
-
function createRulesFromOptions(options
|
|
62
|
+
function createRulesFromOptions(options) {
|
|
63
|
+
if (!options || typeof options !== 'object') {
|
|
64
|
+
throw new Error("options must be a PasswordComplexity object");
|
|
65
|
+
}
|
|
66
|
+
|
|
77
67
|
const rules = {};
|
|
78
68
|
|
|
79
|
-
// Apply defaults
|
|
80
69
|
const {
|
|
81
70
|
min_length: minLength,
|
|
82
71
|
character_types: requiredTypes,
|
|
83
72
|
character_type_rule: characterTypeRule,
|
|
84
73
|
identical_characters: identicalChars,
|
|
85
74
|
sequential_characters: sequentialChars,
|
|
86
|
-
max_length_exceeded:
|
|
87
|
-
} =
|
|
75
|
+
max_length_exceeded: maxLengthExceeded
|
|
76
|
+
} = options;
|
|
77
|
+
|
|
78
|
+
const require3of4 = characterTypeRule === "three_of_four";
|
|
88
79
|
|
|
89
80
|
// Validate min_length is within acceptable range
|
|
90
81
|
if (minLength < 1 || minLength > 72) {
|
|
@@ -95,7 +86,6 @@ function createRulesFromOptions(options = {}) {
|
|
|
95
86
|
rules.length = { minLength: minLength };
|
|
96
87
|
|
|
97
88
|
// Validate '3 of 4' prerequisite
|
|
98
|
-
const require3of4 = characterTypeRule === "three_of_four";
|
|
99
89
|
if (require3of4) {
|
|
100
90
|
const hasAllFourTypes = Object.values(CHARACTER_TYPES).every(function (
|
|
101
91
|
type
|
|
@@ -150,7 +140,7 @@ function createRulesFromOptions(options = {}) {
|
|
|
150
140
|
rules.sequentialChars = { max: 2 }
|
|
151
141
|
}
|
|
152
142
|
|
|
153
|
-
if (
|
|
143
|
+
if (maxLengthExceeded === "error") {
|
|
154
144
|
rules.maxLength = { maxBytes: 72 };
|
|
155
145
|
}
|
|
156
146
|
|
package/package.json
CHANGED
package/test/test.js
CHANGED
|
@@ -23,7 +23,9 @@ describe("password policies", function () {
|
|
|
23
23
|
it("should test min_length from 1 to 72", function () {
|
|
24
24
|
const auth0Config1 = {
|
|
25
25
|
min_length: 1,
|
|
26
|
+
character_types: [],
|
|
26
27
|
identical_characters: "allow",
|
|
28
|
+
sequential_characters: "allow",
|
|
27
29
|
max_length_exceeded: "truncate",
|
|
28
30
|
};
|
|
29
31
|
const rules = createRulesFromOptions(auth0Config1);
|
|
@@ -35,7 +37,9 @@ describe("password policies", function () {
|
|
|
35
37
|
|
|
36
38
|
const auth0Config72 = {
|
|
37
39
|
min_length: 72,
|
|
40
|
+
character_types: [],
|
|
38
41
|
identical_characters: "allow",
|
|
42
|
+
sequential_characters: "allow",
|
|
39
43
|
max_length_exceeded: "truncate",
|
|
40
44
|
};
|
|
41
45
|
const rules72 = createRulesFromOptions(auth0Config72);
|
|
@@ -59,9 +63,10 @@ describe("password policies", function () {
|
|
|
59
63
|
describe("character_types", function () {
|
|
60
64
|
it("should enforce required character types", function () {
|
|
61
65
|
const auth0Config = {
|
|
66
|
+
min_length: 4,
|
|
62
67
|
character_types: ["lowercase", "uppercase", "number", "special"],
|
|
63
68
|
identical_characters: "allow",
|
|
64
|
-
|
|
69
|
+
sequential_characters: "allow",
|
|
65
70
|
max_length_exceeded: "truncate",
|
|
66
71
|
};
|
|
67
72
|
const rules = createRulesFromOptions(auth0Config);
|
|
@@ -83,10 +88,11 @@ describe("password policies", function () {
|
|
|
83
88
|
describe("character_type_rule", function () {
|
|
84
89
|
it("when set to 'three_of_four', should enforce 3 out of 4 character types when all 4 types are specified", function () {
|
|
85
90
|
const auth0Config = {
|
|
91
|
+
min_length: 3,
|
|
86
92
|
character_types: ["lowercase", "uppercase", "number", "special"],
|
|
87
93
|
character_type_rule: "three_of_four",
|
|
88
94
|
identical_characters: "allow",
|
|
89
|
-
|
|
95
|
+
sequential_characters: "allow",
|
|
90
96
|
max_length_exceeded: "truncate",
|
|
91
97
|
};
|
|
92
98
|
const rules = createRulesFromOptions(auth0Config);
|
|
@@ -108,8 +114,11 @@ describe("password policies", function () {
|
|
|
108
114
|
it("when set to 'three_of_four', should throw an error when all 4 character types are NOT specified", function () {
|
|
109
115
|
expect(function () {
|
|
110
116
|
const auth0Config = {
|
|
117
|
+
min_length: 8,
|
|
111
118
|
character_types: ["lowercase", "uppercase"],
|
|
112
119
|
character_type_rule: "three_of_four",
|
|
120
|
+
identical_characters: "allow",
|
|
121
|
+
sequential_characters: "allow",
|
|
113
122
|
max_length_exceeded: "error",
|
|
114
123
|
};
|
|
115
124
|
createRulesFromOptions(auth0Config);
|
|
@@ -122,13 +131,16 @@ describe("password policies", function () {
|
|
|
122
131
|
describe("identical_characters", function () {
|
|
123
132
|
it("should disallow more than 2 identical characters when specified", function () {
|
|
124
133
|
const auth0Config = {
|
|
134
|
+
min_length: 8,
|
|
135
|
+
character_types: [],
|
|
125
136
|
identical_characters: "block",
|
|
137
|
+
sequential_characters: "allow",
|
|
126
138
|
max_length_exceeded: "error",
|
|
127
139
|
};
|
|
128
140
|
const rules = createRulesFromOptions(auth0Config);
|
|
129
141
|
expect(rules).toEqual({
|
|
130
142
|
length: {
|
|
131
|
-
minLength:
|
|
143
|
+
minLength: 8,
|
|
132
144
|
},
|
|
133
145
|
identicalChars: {
|
|
134
146
|
max: 2,
|
|
@@ -141,13 +153,16 @@ describe("password policies", function () {
|
|
|
141
153
|
|
|
142
154
|
it("should allow more than 2 identical characters when specified", function () {
|
|
143
155
|
const auth0Config = {
|
|
156
|
+
min_length: 8,
|
|
157
|
+
character_types: [],
|
|
144
158
|
identical_characters: "allow",
|
|
159
|
+
sequential_characters: "allow",
|
|
145
160
|
max_length_exceeded: "error",
|
|
146
161
|
};
|
|
147
162
|
const rules = createRulesFromOptions(auth0Config);
|
|
148
163
|
expect(rules).toEqual({
|
|
149
164
|
length: {
|
|
150
|
-
minLength:
|
|
165
|
+
minLength: 8,
|
|
151
166
|
},
|
|
152
167
|
maxLength: {
|
|
153
168
|
maxBytes: 72,
|
|
@@ -159,12 +174,16 @@ describe("password policies", function () {
|
|
|
159
174
|
describe("sequential_characters", function () {
|
|
160
175
|
it("should disallow more than 2 sequential characters when specified (set to block)", function () {
|
|
161
176
|
const auth0Config = {
|
|
177
|
+
min_length: 8,
|
|
178
|
+
character_types: [],
|
|
179
|
+
identical_characters: "allow",
|
|
162
180
|
sequential_characters: "block",
|
|
181
|
+
max_length_exceeded: "error",
|
|
163
182
|
};
|
|
164
183
|
const rules = createRulesFromOptions(auth0Config);
|
|
165
184
|
expect(rules).toEqual({
|
|
166
185
|
length: {
|
|
167
|
-
minLength:
|
|
186
|
+
minLength: 8,
|
|
168
187
|
},
|
|
169
188
|
sequentialChars: {
|
|
170
189
|
max: 2,
|
|
@@ -177,12 +196,16 @@ describe("password policies", function () {
|
|
|
177
196
|
|
|
178
197
|
it("should allow more than 2 sequential characters when specified (set to allow)", function () {
|
|
179
198
|
const auth0Config = {
|
|
199
|
+
min_length: 8,
|
|
200
|
+
character_types: [],
|
|
201
|
+
identical_characters: "allow",
|
|
180
202
|
sequential_characters: "allow",
|
|
203
|
+
max_length_exceeded: "error",
|
|
181
204
|
};
|
|
182
205
|
const rules = createRulesFromOptions(auth0Config);
|
|
183
206
|
expect(rules).toEqual({
|
|
184
207
|
length: {
|
|
185
|
-
minLength:
|
|
208
|
+
minLength: 8,
|
|
186
209
|
},
|
|
187
210
|
maxLength: {
|
|
188
211
|
maxBytes: 72,
|
|
@@ -193,7 +216,10 @@ describe("password policies", function () {
|
|
|
193
216
|
it("should correctly validate a password when sequential_characters is set to allow", function () {
|
|
194
217
|
const auth0Config = {
|
|
195
218
|
min_length: 2,
|
|
219
|
+
character_types: [],
|
|
220
|
+
identical_characters: "allow",
|
|
196
221
|
sequential_characters: "allow",
|
|
222
|
+
max_length_exceeded: "truncate",
|
|
197
223
|
};
|
|
198
224
|
const rules = createRulesFromOptions(auth0Config);
|
|
199
225
|
const policy = new PasswordPolicy(rules);
|
|
@@ -204,7 +230,10 @@ describe("password policies", function () {
|
|
|
204
230
|
it("should correctly validate a password when sequential_characters is set to block", function () {
|
|
205
231
|
const auth0Config = {
|
|
206
232
|
min_length: 2,
|
|
233
|
+
character_types: [],
|
|
234
|
+
identical_characters: "allow",
|
|
207
235
|
sequential_characters: "block",
|
|
236
|
+
max_length_exceeded: "truncate",
|
|
208
237
|
};
|
|
209
238
|
const rules = createRulesFromOptions(auth0Config);
|
|
210
239
|
const policy = new PasswordPolicy(rules);
|
|
@@ -217,12 +246,16 @@ describe("password policies", function () {
|
|
|
217
246
|
describe("max_length_exceeded", function () {
|
|
218
247
|
it("should disallow more than 72 bytes when creating password if max_length_exceeded is set to error", function () {
|
|
219
248
|
const auth0Config = {
|
|
249
|
+
min_length: 8,
|
|
250
|
+
character_types: [],
|
|
251
|
+
identical_characters: "allow",
|
|
252
|
+
sequential_characters: "allow",
|
|
220
253
|
max_length_exceeded: "error",
|
|
221
254
|
};
|
|
222
255
|
const rules = createRulesFromOptions(auth0Config);
|
|
223
256
|
expect(rules).toEqual({
|
|
224
257
|
length: {
|
|
225
|
-
minLength:
|
|
258
|
+
minLength: 8,
|
|
226
259
|
},
|
|
227
260
|
maxLength: {
|
|
228
261
|
maxBytes: 72,
|
|
@@ -232,12 +265,16 @@ describe("password policies", function () {
|
|
|
232
265
|
|
|
233
266
|
it("should not set a maxLength on rules when max_length_exceeded is set to truncate", function () {
|
|
234
267
|
const auth0Config = {
|
|
268
|
+
min_length: 8,
|
|
269
|
+
character_types: [],
|
|
270
|
+
identical_characters: "allow",
|
|
271
|
+
sequential_characters: "allow",
|
|
235
272
|
max_length_exceeded: "truncate",
|
|
236
273
|
};
|
|
237
274
|
const rules = createRulesFromOptions(auth0Config);
|
|
238
275
|
expect(rules).toEqual({
|
|
239
276
|
length: {
|
|
240
|
-
minLength:
|
|
277
|
+
minLength: 8,
|
|
241
278
|
},
|
|
242
279
|
});
|
|
243
280
|
});
|
|
@@ -245,6 +282,9 @@ describe("password policies", function () {
|
|
|
245
282
|
it("should correctly validate a password when max_length_exceeded is set to error", function () {
|
|
246
283
|
const auth0Config = {
|
|
247
284
|
min_length: 2,
|
|
285
|
+
character_types: [],
|
|
286
|
+
identical_characters: "allow",
|
|
287
|
+
sequential_characters: "allow",
|
|
248
288
|
max_length_exceeded: "error",
|
|
249
289
|
};
|
|
250
290
|
const rules = createRulesFromOptions(auth0Config);
|
|
@@ -257,6 +297,9 @@ describe("password policies", function () {
|
|
|
257
297
|
it("should correctly validate a password when max_length_exceeded is set to truncate", function () {
|
|
258
298
|
const auth0Config = {
|
|
259
299
|
min_length: 2,
|
|
300
|
+
character_types: [],
|
|
301
|
+
identical_characters: "allow",
|
|
302
|
+
sequential_characters: "allow",
|
|
260
303
|
max_length_exceeded: "truncate",
|
|
261
304
|
};
|
|
262
305
|
const rules = createRulesFromOptions(auth0Config);
|
|
@@ -267,23 +310,18 @@ describe("password policies", function () {
|
|
|
267
310
|
});
|
|
268
311
|
});
|
|
269
312
|
|
|
270
|
-
describe("
|
|
271
|
-
it("should
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
minLength: 15,
|
|
277
|
-
},
|
|
278
|
-
maxLength: {
|
|
279
|
-
maxBytes: 72,
|
|
280
|
-
},
|
|
281
|
-
});
|
|
313
|
+
describe("validation", function () {
|
|
314
|
+
it("should throw an error when options parameter is missing required properties", function () {
|
|
315
|
+
expect(function () {
|
|
316
|
+
const auth0Config = {};
|
|
317
|
+
createRulesFromOptions(auth0Config);
|
|
318
|
+
}).toThrow();
|
|
282
319
|
});
|
|
283
320
|
|
|
284
|
-
it("should
|
|
321
|
+
it("should accept valid configuration with all required properties", function () {
|
|
285
322
|
const auth0Config = {
|
|
286
323
|
min_length: 5,
|
|
324
|
+
character_types: [],
|
|
287
325
|
identical_characters: "allow",
|
|
288
326
|
sequential_characters: "allow",
|
|
289
327
|
max_length_exceeded: "truncate",
|