mirror of
https://github.com/PostHog/posthog.git
synced 2024-11-21 21:49:51 +01:00
Added password strength bar (#1632)
* added password strength bar * minor style fixes * retry cypress * extract password strength logic to standalone component * Refactor with TypeScript * updated strength algo * fix linter comments * fix comment * made distinct chars test less strict * use zxcvbn * Make score numbers nicer and add a color between red and orange Slightly pedantically made passwordScore always a multiple of 20%. :) * run prettier Co-authored-by: Paolo D'Amico <paolodamico@users.noreply.github.com> Co-authored-by: Michael Matloka <dev@twixes.com> Co-authored-by: Marius Andra <marius.andra@gmail.com>
This commit is contained in:
parent
e9ce195b99
commit
8115e4969c
29
frontend/src/lib/components/PasswordStrength.tsx
Normal file
29
frontend/src/lib/components/PasswordStrength.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import React from 'react'
|
||||
import { Progress } from 'antd'
|
||||
import { red, volcano, orange, yellow, green } from '@ant-design/colors'
|
||||
import zxcvbn from 'zxcvbn'
|
||||
|
||||
export default function PasswordStrength({ password = '' }: { password: string }): JSX.Element {
|
||||
// passwordScore is 0 if no password input
|
||||
// passwordScore is 20, 40, 60, 80, or 100 if password input, based on zxcvbn score (which is 0, 1, 2, 3, or 4)
|
||||
const passwordScore: number = password.length && zxcvbn(password).score * 20 + 20
|
||||
|
||||
return (
|
||||
<Progress
|
||||
percent={passwordScore}
|
||||
size="small"
|
||||
strokeColor={
|
||||
passwordScore <= 20
|
||||
? red.primary
|
||||
: passwordScore <= 40
|
||||
? volcano.primary
|
||||
: passwordScore <= 60
|
||||
? orange.primary
|
||||
: passwordScore <= 80
|
||||
? yellow.primary
|
||||
: green.primary
|
||||
}
|
||||
showInfo={false}
|
||||
/>
|
||||
)
|
||||
}
|
@ -1,10 +1,11 @@
|
||||
import React, { useState, useRef, useEffect } from 'react'
|
||||
import React, { useState, useRef, useEffect, lazy, Suspense } from 'react'
|
||||
import { useActions, useValues } from 'kea'
|
||||
import { signupLogic } from './signupLogic'
|
||||
import hedgehogBlue from './../../../public/hedgehog-blue.png'
|
||||
import posthogLogo from './../../../public/posthog-icon.svg'
|
||||
import { Row, Space, Button, Input, Checkbox } from 'antd'
|
||||
import queryString from 'query-string'
|
||||
const PasswordStrength = lazy(() => import('../../lib/components/PasswordStrength'))
|
||||
|
||||
function Signup() {
|
||||
const [state, setState] = useState({ submitted: false })
|
||||
@ -24,7 +25,8 @@ function Signup() {
|
||||
const updateForm = (name, target, valueAttr = 'value') => {
|
||||
/* Validate password (if applicable) */
|
||||
if (name === 'password') {
|
||||
const valid = target[valueAttr].length >= 8
|
||||
let password = target[valueAttr]
|
||||
const valid = password.length >= 8
|
||||
setFormState({ ...formState, password: { ...formState.password, valid, value: target[valueAttr] } })
|
||||
} else {
|
||||
setFormState({ ...formState, [name]: { ...formState[name], value: target[valueAttr] } })
|
||||
@ -134,7 +136,12 @@ function Signup() {
|
||||
disabled={accountLoading}
|
||||
id="signupPassword"
|
||||
/>
|
||||
<span className="caption">At least 8 characters.</span>
|
||||
<Suspense fallback={<span></span>}>
|
||||
<PasswordStrength password={formState.password.value} />
|
||||
</Suspense>
|
||||
{!formState.password.valid && (
|
||||
<span className="caption">Your password must have at least 8 characters.</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
@ -30,6 +30,7 @@
|
||||
"@mariusandra/react-grid-layout": "0.18.3",
|
||||
"@mariusandra/simmerjs": "0.6.1-posthog.1",
|
||||
"@types/react-syntax-highlighter": "^11.0.4",
|
||||
"@types/zxcvbn": "^4.4.0",
|
||||
"antd": "^4.1.1",
|
||||
"babel-preset-nano-react-app": "^0.1.0",
|
||||
"bootstrap": "^4.4.1",
|
||||
@ -61,7 +62,8 @@
|
||||
"redux": "^4.0.5",
|
||||
"reselect": "^4.0.0",
|
||||
"sass": "^1.26.2",
|
||||
"styled-components": "^5.0.1"
|
||||
"styled-components": "^5.0.1",
|
||||
"zxcvbn": "^4.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
||||
|
10
yarn.lock
10
yarn.lock
@ -1162,6 +1162,11 @@
|
||||
"@types/webpack-sources" "*"
|
||||
source-map "^0.6.0"
|
||||
|
||||
"@types/zxcvbn@^4.4.0":
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.0.tgz#fbc1d941cc6d9d37d18405c513ba6b294f89b609"
|
||||
integrity sha512-GQLOT+SN20a+AI51y3fAimhyTF4Y0RG+YP3gf91OibIZ7CJmPFgoZi+ZR5a+vRbS01LbQosITWum4ATmJ1Z6Pg==
|
||||
|
||||
"@typescript-eslint/eslint-plugin@^3.6.0":
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-3.10.1.tgz#7e061338a1383f59edc204c605899f93dc2e2c8f"
|
||||
@ -10267,3 +10272,8 @@ yauzl@^2.10.0:
|
||||
dependencies:
|
||||
buffer-crc32 "~0.2.3"
|
||||
fd-slicer "~1.1.0"
|
||||
|
||||
zxcvbn@^4.4.2:
|
||||
version "4.4.2"
|
||||
resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30"
|
||||
integrity sha1-KOwXzwl0PtyrBW3dixsGJizHPDA=
|
||||
|
Loading…
Reference in New Issue
Block a user