Skip to content
This repository was archived by the owner on Apr 10, 2024. It is now read-only.

Commit 27b27ad

Browse files
author
Mateusz Wijas
committed
implement password too long check
1 parent 7727f5c commit 27b27ad

File tree

4 files changed

+42
-9
lines changed

4 files changed

+42
-9
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,11 @@ Using in a __Universal JS App__ (server-side rendering):
5656

5757
- Minimum password length acceptable for password to be considered valid
5858

59+
#### maxLength (Default: 1000)
60+
61+
- Maximum password length acceptable for password to be considered valid
62+
- Used to prevent DDOS attacks with exceptionally long passwords meant to overload servers with work.
63+
5964
#### minScore (Default: 2)
6065

6166
- Minimum score acceptable for password to be considered valid
@@ -70,6 +75,10 @@ Using in a __Universal JS App__ (server-side rendering):
7075

7176
- A string to describe when password is too short (based on minLength prop).
7277

78+
#### tooLongWord (Default: 'too long')
79+
80+
- A string to describe when password is too long (based on maxLength prop).
81+
7382
#### changeCallback
7483

7584
- Callback after input has changed (and score was recomputed)

example/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class App extends React.Component {
2828
<ReactPasswordStrength
2929
ref={ref => this.ReactPasswordStrength = ref}
3030
minLength={6}
31+
maxLength={10}
32+
tooLongWord="woah there"
3133
inputProps={inputProps}
3234
changeCallback={this.changeCallback}
3335
/>
@@ -40,7 +42,8 @@ class App extends React.Component {
4042

4143
<ReactPasswordStrength
4244
minLength={6}
43-
inputProps={inputProps}
45+
maxLength={10}
46+
inputProps={{ ...inputProps, id: "inputPassword2" }}
4447
defaultValue="defaultValue"
4548
/>
4649
</div>

src/index.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import zxcvbn from 'zxcvbn';
55
import PropTypes from 'prop-types';
66

77
const isTooShort = (password, minLength) => password.length < minLength;
8+
const isTooLong = (password, maxLength) => password.length > maxLength;
89

910
export default class ReactPasswordStrength extends Component {
1011
static propTypes = {
@@ -13,6 +14,7 @@ export default class ReactPasswordStrength extends Component {
1314
defaultValue: PropTypes.string,
1415
inputProps: PropTypes.object,
1516
minLength: PropTypes.number,
17+
maxLength: PropTypes.number,
1618
minScore: PropTypes.number,
1719
namespaceClassName: PropTypes.string,
1820
scoreWords: PropTypes.array,
@@ -25,10 +27,12 @@ export default class ReactPasswordStrength extends Component {
2527
changeCallback: null,
2628
className: '',
2729
defaultValue: '',
30+
maxLength: 1000,
2831
minLength: 5,
2932
minScore: 2,
3033
namespaceClassName: 'ReactPasswordStrength',
3134
scoreWords: ['weak', 'weak', 'okay', 'good', 'strong'],
35+
tooLongWord: 'too long',
3236
tooShortWord: 'too short',
3337
userInputs: [],
3438
}
@@ -64,21 +68,21 @@ export default class ReactPasswordStrength extends Component {
6468
}
6569

6670
handleChange = () => {
67-
const { changeCallback, minScore, userInputs, minLength } = this.props;
71+
const { changeCallback, minScore, userInputs, minLength, maxLength } = this.props;
6872
const password = this.reactPasswordStrengthInput.value;
6973

7074
let score = 0;
7175
let result = null;
7276

7377
// always sets a zero score when min length requirement is not met
7478
// avoids unnecessary zxcvbn computations (CPU intensive)
75-
if (isTooShort(password, minLength) === false) {
79+
if (isTooShort(password, minLength) === false && isTooLong(password, maxLength) === false) {
7680
result = zxcvbn(password, userInputs);
7781
score = result.score;
7882
}
7983

8084
this.setState({
81-
isValid: score >= minScore,
85+
isValid: score >= minScore && !isTooLong(password, maxLength),
8286
password,
8387
score,
8488
}, () => {
@@ -93,10 +97,12 @@ export default class ReactPasswordStrength extends Component {
9397
const {
9498
className,
9599
inputProps,
100+
maxLength,
96101
minLength,
97102
namespaceClassName,
98103
scoreWords,
99104
style,
105+
tooLongWord,
100106
tooShortWord,
101107
} = this.props;
102108

@@ -106,11 +112,11 @@ export default class ReactPasswordStrength extends Component {
106112
className ? className : '',
107113
password.length > 0 ? `is-strength-${score}` : '',
108114
];
109-
const strengthDesc = (
110-
isTooShort(password, minLength)
111-
? tooShortWord
112-
: scoreWords[score]
113-
);
115+
116+
let strengthDesc = scoreWords[score];
117+
118+
if (isTooShort(password, minLength)) strengthDesc = tooShortWord;
119+
if (isTooLong(password, maxLength)) strengthDesc = tooLongWord;
114120

115121
if (isValid === true) {
116122
inputClasses.push('is-password-valid');
@@ -126,6 +132,7 @@ export default class ReactPasswordStrength extends Component {
126132
<div className={wrapperClasses.join(' ')} style={style}>
127133
<input
128134
type="password"
135+
maxLength={maxLength}
129136
{...inputProps}
130137
className={inputClasses.join(' ')}
131138
onChange={this.handleChange}

test/index.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,20 @@ describe('ReactPasswordStrength Events', () => {
143143
expect(result.state.isValid).toBe(false);
144144
})
145145

146+
it('invalidates too long passwords', () => {
147+
const result = renderIntoDocument(<PassStrength maxLength={9} />);
148+
let input = findRenderedDOMComponentWithClass(result, 'ReactPasswordStrength-input');
149+
150+
// this normally passes but must fail because it exceeds the max length
151+
input.value = '4mf2df32df52df3';
152+
153+
Simulate.change(input);
154+
155+
expect(result.state.password).toBe('4mf2df32df52df3');
156+
expect(result.state.score).toBe(0);
157+
expect(result.state.isValid).toBe(false);
158+
})
159+
146160
it('adds strings in userInputs to zxcvbn dictionary', () => {
147161
const knownKeyword = 'longwordthatiscommon';
148162
const result = renderIntoDocument(<PassStrength minScore={2} userInputs={[knownKeyword]} />);

0 commit comments

Comments
 (0)