Add check for most common passwords

This commit is contained in:
Tuan Dang
2023-06-07 00:06:35 +01:00
parent c5be497052
commit a8ed187443
9 changed files with 1547 additions and 6 deletions

View File

@@ -1,5 +1,7 @@
import * as Sentry from '@sentry/node';
import { Request, Response } from 'express';
import fs from 'fs';
import path from 'path';
import jwt from 'jsonwebtoken';
import * as bigintConversion from 'bigint-conversion';
// eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -224,6 +226,15 @@ export const logout = async (req: Request, res: Response) => {
});
};
export const getCommonPasswords = async (req: Request, res: Response) => {
const commonPasswords = fs.readFileSync(
path.resolve(__dirname, '../../data/' + 'common_passwords.txt'),
'utf8'
).split('\n');
return res.status(200).send(commonPasswords);
}
export const revokeAllSessions = async (req: Request, res: Response) => {
await TokenVersion.updateMany({
user: req.user._id

File diff suppressed because it is too large Load Diff

View File

@@ -59,8 +59,15 @@ router.get(
authController.handleAuthProviderCallback,
);
router.get(
'/common-passwords',
authLimiter,
authController.getCommonPasswords
);
router.delete(
'/sessions',
authLimiter,
requireAuth({
acceptedAuthModes: [AUTH_MODE_JWT]
}),

View File

@@ -19,6 +19,7 @@ import { deriveArgonKey } from '../utilities/cryptography/crypto';
import { saveTokenToLocalStorage } from '../utilities/saveTokenToLocalStorage';
import SecurityClient from '../utilities/SecurityClient';
import { Button, Input } from '../v2';
import { useGetCommonPasswords } from '@app/hooks/api';
// eslint-disable-next-line new-cap
const client = new jsrp.client();
@@ -72,6 +73,7 @@ export default function UserInfoStep({
setAttributionSource,
providerAuthToken,
}: UserInfoStepProps): JSX.Element {
const { data: commonPasswords } = useGetCommonPasswords();
const [nameError, setNameError] = useState(false);
const [organizationNameError, setOrganizationNameError] = useState(false);
const [passwordErrorLength, setPasswordErrorLength] = useState(false);
@@ -103,6 +105,7 @@ export default function UserInfoStep({
errorCheck = checkPassword({
password,
commonPasswords,
setErrors
});

View File

@@ -5,10 +5,12 @@ type Errors = {
number?: string,
specialChar?: string,
repeatedChar?: string,
commonPassword?: string
};
interface CheckPasswordParams {
password: string;
commonPasswords: string[];
setErrors: (value: Errors) => void;
}
@@ -30,6 +32,7 @@ interface CheckPasswordParams {
*/
const checkPassword = ({
password,
commonPasswords,
setErrors
}: CheckPasswordParams): boolean => {
let errors: Errors = {};
@@ -58,6 +61,10 @@ const checkPassword = ({
errors.repeatedChar = "No 3 repeat, consecutive characters";
}
if (commonPasswords.includes(password)) {
errors.commonPassword = "No common passwords";
}
setErrors(errors);
return Object.keys(errors).length > 0;
}

View File

@@ -2,5 +2,6 @@ export {
useGetAuthToken,
useSendMfaToken,
useVerifyMfaToken,
useRevokeAllSessions
useRevokeAllSessions,
useGetCommonPasswords
} from './queries'

View File

@@ -10,7 +10,8 @@ import {
VerifyMfaTokenRes} from './types';
const authKeys = {
getAuthToken: ['token'] as const
getAuthToken: ['token'] as const,
commonPasswords: ['common-passwords'] as const
};
export const useSendMfaToken = () => {
@@ -57,4 +58,12 @@ export const useRevokeAllSessions = () => {
return data;
}
});
}
}
const fetchCommonPasswords = async () => {
const { data } = await apiRequest.get('/api/v1/auth/common-passwords');
return data || [];
};
export const useGetCommonPasswords = () =>
useQuery({ queryKey: authKeys.commonPasswords, queryFn: fetchCommonPasswords });

View File

@@ -19,7 +19,8 @@ import AddApiKeyDialog from '../../../components/basic/dialog/AddApiKeyDialog';
import getAPIKeys from '../../api/apiKey/getAPIKeys';
import getUser from '../../api/user/getUser';
import {
useRevokeAllSessions
useRevokeAllSessions,
useGetCommonPasswords
} from '@app/hooks/api';
type Errors = {
@@ -32,6 +33,7 @@ type Errors = {
};
export default function PersonalSettings() {
const { data: commonPasswords } = useGetCommonPasswords();
const [personalEmail, setPersonalEmail] = useState('');
const [personalName, setPersonalName] = useState('');
const [currentPasswordError, setCurrentPasswordError] = useState(false);
@@ -168,6 +170,7 @@ export default function PersonalSettings() {
setNewPassword(password);
checkPassword({
password,
commonPasswords,
setErrors
});
}}

View File

@@ -17,7 +17,6 @@ import { encodeBase64 } from 'tweetnacl-util';
import Button from '@app/components/basic/buttons/Button';
import InputField from '@app/components/basic/InputField';
import attemptLogin from '@app/components/utilities/attemptLogin';
import passwordCheck from '@app/components/utilities/checks/PasswordCheck';
import checkPassword from '@app/components/utilities/checks/checkPassword';
@@ -28,7 +27,9 @@ import { saveTokenToLocalStorage } from '@app/components/utilities/saveTokenToLo
import SecurityClient from '@app/components/utilities/SecurityClient';
import getOrganizations from '@app/pages/api/organization/getOrgs';
import getOrganizationUserProjects from '@app/pages/api/organization/GetOrgUserProjects';
import {
useGetCommonPasswords
} from '@app/hooks/api';
import completeAccountInformationSignupInvite from './api/auth/CompleteAccountInformationSignupInvite';
import verifySignupInvite from './api/auth/VerifySignupInvite';
@@ -45,6 +46,7 @@ type Errors = {
};
export default function SignupInvite() {
const { data: commonPasswords } = useGetCommonPasswords();
const [password, setPassword] = useState('');
const [firstName, setFirstName] = useState('');
const [lastName, setLastName] = useState('');
@@ -81,6 +83,7 @@ export default function SignupInvite() {
errorCheck = checkPassword({
password,
commonPasswords,
setErrors
});