├── .gitignore
├── .nvmrc
├── LICENSE
├── README.md
├── examples
└── index.html
├── main.js
├── package.json
├── password-strength-meter.js
├── style.css
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | lib
3 | public
4 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | 4.2.2
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 Abhijeet Mishra (https://github.com/abhijeetNmishra)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [React Password Strength Meter](https://github.com/abhijeetNmishra/react-password-strength-meter)
2 | React Component to display password strength meter with message and warning
3 |
4 | ## Dependencies
5 | This Component is built using [Dropbox zxcvbn password strength estimator library](https://github.com/dropbox/zxcvbn)
6 |
7 | ## Installation & Usage
8 |
9 | ```
10 | npm install react-password-strength-meter --save
11 | ```
12 |
13 | ## Password Strength Meter and values
14 | This component will 'strength' meter as prop value (type: object).
15 |
16 | ```
17 | strength default value :
18 | strength : {
19 | 0: "Worst ☹",
20 | 1: "Bad ☹",
21 | 2: "Weak ☹",
22 | 3: "Good ☺",
23 | 4: "Strong ☻"
24 | }
25 | ```
26 |
27 | ### Include the Component
28 |
29 | ```
30 | var React = require('react');
31 | var PasswordStrengthMeter = require('react-password-strength-meter');
32 |
33 | class Component extends React.Component {
34 | constructor(props){
35 | super(props);
36 | this.onChange = this.onChange.bind(this);
37 | }
38 |
39 | onChange(event){
40 |
41 | }
42 |
43 | render() {
44 | return ;
45 | }
46 | }
47 | ```
48 |
49 | ## License
50 |
51 | React Password Strength Meter is released under the MIT license. See [LICENSE](LICENSE) for details.
52 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | react password strength meter
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { render } from 'react-dom';
3 | import PasswordStrengthMeter from './password-strength-meter';
4 |
5 | require('./style.css');
6 |
7 | render(
8 | ,document.getElementById('content')
9 | )
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-password-strength-meter",
3 | "version": "1.0.5",
4 | "description": "react component to display password strength meter",
5 | "license": "MIT",
6 | "repository": "abhijeetNmishra/react-password-strength-meter",
7 | "main": "lib/index.js",
8 | "author": {
9 | "name": "Abhijeet Mishra",
10 | "email": "geminiabhijeet@gmail.com"
11 | },
12 | "engines": {
13 | "node": "4.2.2"
14 | },
15 | "scripts": {
16 | "build": "babel password-strength-meter.js --out-file lib/index.js",
17 | "prepublish": "npm run build"
18 | },
19 | "files": [
20 | "lib/index.js"
21 | ],
22 | "keywords": [
23 | "react",
24 | "password meter",
25 | "react-component",
26 | "password strength checker",
27 | "zxcvbn"
28 | ],
29 | "dependencies": {
30 | "zxcvbn": "^4.2.0"
31 | },
32 | "peerDependencies": {
33 | "react": "^0.14.3",
34 | "react-dom": "^0.14.3"
35 | },
36 | "devDependencies": {
37 | "babel-core": "^6.2.1",
38 | "babel-loader": "^6.2.0",
39 | "babel-polyfill": "^6.2.0",
40 | "babel-runtime": "^6.2.0",
41 | "babel-plugin-transform-runtime": "^6.1.18",
42 | "babel-preset-es2015": "^6.1.18",
43 | "babel-preset-react": "^6.1.18",
44 | "css-loader": "^0.23.0",
45 | "style-loader": "^0.13.0",
46 | "webpack": "^1.12.9",
47 | "webpack-dev-server": "^1.14.0"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/password-strength-meter.js:
--------------------------------------------------------------------------------
1 | import React, {Component,PropTypes} from 'react';
2 | import ReactDom from 'react-dom';
3 | import zxcvbn from 'zxcvbn';
4 |
5 | export default class PasswordStrengthMeter extends Component{
6 | constructor(props){
7 | super(props);
8 | this.handleInput = this.handleInput.bind(this);
9 | this.state = {
10 | resultScore: '',
11 | warning: '',
12 | suggestions:''
13 | };
14 | }
15 |
16 | handleInput(event){
17 | event.preventDefault();
18 | let { strength } = this.props;
19 | strength = (strength) ? strength : {
20 | 0: "Worst ☹",
21 | 1: "Bad ☹",
22 | 2: "Weak ☹",
23 | 3: "Good ☺",
24 | 4: "Strong ☻"
25 | }
26 |
27 | const password = ReactDom.findDOMNode(this.refs.password);
28 | const meter = ReactDom.findDOMNode(this.refs.passwordStrengthMeter);
29 | const text = ReactDom.findDOMNode(this.refs.passwordStrengthText);
30 |
31 | let val = password.value;
32 | let result = zxcvbn(val);
33 |
34 | // Update the password strength meter
35 | meter.value = result.score;
36 |
37 | // Update the text indicator
38 | if(val !== "") {
39 | this.setState({
40 | resultScore:strength[result.score],
41 | warning:result.feedback.warning,
42 | suggestions:result.feedback.suggestions
43 | });
44 | }
45 | else {
46 | this.setState({
47 | resultScore:'',
48 | warning:'',
49 | suggestions:''
50 | })
51 | }
52 |
53 | if(typeof this.props.onChange === 'function'){
54 | this.props.onChange(event);
55 | }
56 | }
57 |
58 | render(){
59 | const { passwordText } = this.props;
60 | const passwordHeader = (passwordText) ? passwordText : 'Enter Password';
61 | const {resultScore,warning,suggestions} = this.state;
62 | return(
63 |
74 | )
75 | }
76 | }
77 |
78 | PasswordStrengthMeter.propTypes = {
79 | passwordText: React.PropTypes.string,
80 | strength: React.PropTypes.object,
81 | onChange: React.PropTypes.func,
82 | }
83 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Signika:400,700|Courgette);
2 |
3 | #content section {
4 | margin: 0em auto 0;
5 | width: 100%;
6 | max-width: 800px;
7 | }
8 |
9 | #content input {
10 | display: block;
11 | margin: .5em auto 0em;
12 | padding: -0.5em 1em 0.5em 0.7em;
13 | width: 100%;
14 | border: none;
15 | background: #159957;
16 | color: white;
17 | font-size: 2em;
18 | line-height: 0;
19 | transition: all .5s linear;
20 | }
21 |
22 | input:hover, input:focus {
23 | outline: 0;
24 | transition: all .5s linear;
25 | box-shadow: inset 0px 0px 10px #ccc;
26 | }
27 |
28 | meter {
29 | /* Reset the default appearance */
30 | -webkit-appearance: none;
31 | -moz-appearance: none;
32 | appearance: none;
33 |
34 | margin: 0 auto 1em;
35 | width: 100%;
36 | height: .5em;
37 |
38 | /* Applicable only to Firefox */
39 | background: none;
40 | background-color: rgba(0,0,0,0.1);
41 | }
42 |
43 | meter::-webkit-meter-bar {
44 | background: none;
45 | background-color: rgba(0,0,0,0.1);
46 | }
47 |
48 | meter[value="1"]::-webkit-meter-optimum-value { background: red; }
49 | meter[value="2"]::-webkit-meter-optimum-value { background: yellow; }
50 | meter[value="3"]::-webkit-meter-optimum-value { background: orange; }
51 | meter[value="4"]::-webkit-meter-optimum-value { background: green; }
52 |
53 | meter[value="1"]::-moz-meter-bar { background: red; }
54 | meter[value="2"]::-moz-meter-bar { background: yellow; }
55 | meter[value="3"]::-moz-meter-bar { background: orange; }
56 | meter[value="4"]::-moz-meter-bar { background: green; }
57 |
58 | .feedback {
59 | color: #9ab;
60 | font-size: 90%;
61 | padding: 0 .25em;
62 | font-family: Courgette, cursive;
63 | margin-top: 1em;
64 | }
65 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var path = require('path');
2 | var webpack = require('webpack');
3 | var nodeModulesPath = path.join(__dirname, 'node_modules');
4 |
5 | module.exports = {
6 | entry: [
7 | // Set up an ES6-ish environment
8 | // Add your application's scripts below
9 | './main',
10 | ],
11 | output: {
12 | filename: 'main.js',
13 | path: path.join(__dirname, 'public'),
14 | publicPath: '/public/'
15 | },
16 | module: {
17 | loaders: [{
18 | loader: "babel-loader",
19 |
20 | exclude: nodeModulesPath,
21 |
22 | // Only run `.js` and `.jsx` files through Babel
23 | test: /\.jsx?$/,
24 |
25 | // Options to configure babel with
26 | query: {
27 | plugins: [],
28 | presets: ['es2015', 'react'],
29 | }
30 | },{ test: /\.css$/, loader: "style-loader!css-loader" }]
31 | },
32 | plugins: [
33 | new webpack.optimize.UglifyJsPlugin({
34 | compress: {
35 | warnings: false
36 | }
37 | }),
38 | new webpack.optimize.DedupePlugin()
39 | ]
40 | }
41 |
--------------------------------------------------------------------------------