0
Fork 0
mirror of https://github.com/logto-io/logto.git synced 2024-12-16 20:26:19 -05:00

fix(console): generated passwords should pass the regex checks (#3925)

This commit is contained in:
Charles Zhao 2023-06-01 22:33:45 +08:00 committed by GitHub
parent f89af550de
commit 44e18c081a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 18 additions and 17 deletions

View file

@ -1,10 +1,10 @@
import type { User } from '@logto/schemas'; import type { User } from '@logto/schemas';
import { nanoid } from 'nanoid';
import { useState } from 'react'; import { useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import ConfirmModal from '@/components/ConfirmModal'; import ConfirmModal from '@/components/ConfirmModal';
import useApi from '@/hooks/use-api'; import useApi from '@/hooks/use-api';
import { generateRandomPassword } from '@/utils/password';
type Props = { type Props = {
userId: string; userId: string;
@ -19,7 +19,7 @@ function ResetPasswordForm({ onClose, userId }: Props) {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const onSubmit = async () => { const onSubmit = async () => {
const password = nanoid(8); const password = generateRandomPassword();
setIsLoading(true); setIsLoading(true);
await api.patch(`api/users/${userId}/password`, { json: { password } }).json<User>(); await api.patch(`api/users/${userId}/password`, { json: { password } }).json<User>();
setIsLoading(false); setIsLoading(false);

View file

@ -14,10 +14,10 @@ import TextInput from '@/components/TextInput';
import UserAccountInformation from '@/components/UserAccountInformation'; import UserAccountInformation from '@/components/UserAccountInformation';
import useApi from '@/hooks/use-api'; import useApi from '@/hooks/use-api';
import * as modalStyles from '@/scss/modal.module.scss'; import * as modalStyles from '@/scss/modal.module.scss';
import { generateRandomPassword } from '@/utils/password';
import { parsePhoneNumber } from '@/utils/phone'; import { parsePhoneNumber } from '@/utils/phone';
import * as styles from './index.module.scss'; import * as styles from './index.module.scss';
import { createInitialPassword } from './utils';
type FormData = Pick<CreateUser, 'name' | 'username' | 'primaryEmail' | 'primaryPhone'>; type FormData = Pick<CreateUser, 'name' | 'username' | 'primaryEmail' | 'primaryPhone'>;
@ -74,7 +74,7 @@ function CreateForm({ onClose, onCreate }: Props) {
return; return;
} }
const password = createInitialPassword(); const password = generateRandomPassword();
const { primaryPhone } = data; const { primaryPhone } = data;

View file

@ -1,13 +0,0 @@
import { customAlphabet } from 'nanoid';
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
const digits = '0123456789';
// Note: password requires a minimum of 8 characters and contains a mix of letters, numbers, and symbols.
export const createInitialPassword = () => {
const randomAlphabet = customAlphabet(alphabet);
const randomDigit = customAlphabet(digits);
const randomAlphabetOrDigit = customAlphabet(alphabet + digits);
return `${randomAlphabet(1)}${randomDigit(1)}${randomAlphabetOrDigit(6)}`;
};

View file

@ -0,0 +1,14 @@
import { passwordRegEx } from '@logto/core-kit';
import { nanoid } from 'nanoid';
// Note: password requires a minimum of 8 characters and contains a mix of letters, numbers, and symbols.
export const generateRandomPassword = (length = 8) => {
// eslint-disable-next-line @silverhand/fp/no-let
let generated = nanoid(length);
while (!passwordRegEx.test(generated)) {
// eslint-disable-next-line @silverhand/fp/no-mutation
generated = nanoid(length);
}
return generated;
};