diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry/permissions-modal/permission-add-entry-field.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry/permissions-modal/permission-add-entry-field.tsx index 5e7f1a02c..b24483108 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry/permissions-modal/permission-add-entry-field.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/permissions-sidebar-entry/permissions-modal/permission-add-entry-field.tsx @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import { useOnInputChange } from '../../../../../../hooks/common/use-on-input-change' +import { useLowercaseOnInputChange } from '../../../../../../hooks/common/use-lowercase-on-input-change' import { UiIcon } from '../../../../../common/icons/ui-icon' import type { PermissionDisabledProps } from './permission-disabled.prop' import React, { useCallback, useState } from 'react' @@ -31,7 +31,7 @@ export const PermissionAddEntryField: React.FC { onAddEntry(newEntryIdentifier) diff --git a/frontend/src/components/login-page/auth/fields/username-field.tsx b/frontend/src/components/login-page/auth/fields/username-field.tsx index fb33c1c85..def9a1472 100644 --- a/frontend/src/components/login-page/auth/fields/username-field.tsx +++ b/frontend/src/components/login-page/auth/fields/username-field.tsx @@ -8,19 +8,26 @@ import React from 'react' import { Form } from 'react-bootstrap' import { useTranslation } from 'react-i18next' +export interface UsernameFieldProps extends AuthFieldProps { + value: string +} + +//TODO: This should be replaced with the common username component. See https://github.com/hedgedoc/hedgedoc/issues/4128 /** * Renders an input field for a username. * * @param onChange Hook that is called when the input is changed. * @param invalid True indicates that the username is invalid, false otherwise. + * @param value the username value */ -export const UsernameField: React.FC = ({ onChange, invalid }) => { +export const UsernameField: React.FC = ({ onChange, invalid, value }) => { const { t } = useTranslation() return ( = ({ providerName, identifier }) => [username, password, identifier] ) - const onUsernameChange = useOnInputChange(setUsername) + const onUsernameChange = useLowercaseOnInputChange(setUsername) const onPasswordChange = useOnInputChange(setPassword) return ( @@ -48,7 +49,7 @@ export const ViaLdap: React.FC = ({ providerName, identifier }) =>
- + diff --git a/frontend/src/components/login-page/auth/via-local.tsx b/frontend/src/components/login-page/auth/via-local.tsx index 0cc8c8dfc..214fa2ea4 100644 --- a/frontend/src/components/login-page/auth/via-local.tsx +++ b/frontend/src/components/login-page/auth/via-local.tsx @@ -5,6 +5,7 @@ */ import { doLocalLogin } from '../../../api/auth/local' import { ErrorToI18nKeyMapper } from '../../../api/common/error-to-i18n-key-mapper' +import { useLowercaseOnInputChange } from '../../../hooks/common/use-lowercase-on-input-change' import { useOnInputChange } from '../../../hooks/common/use-on-input-change' import { useFrontendConfig } from '../../common/frontend-config-context/use-frontend-config' import { ShowIf } from '../../common/show-if/show-if' @@ -44,7 +45,7 @@ export const ViaLocal: React.FC = () => { [username, password] ) - const onUsernameChange = useOnInputChange(setUsername) + const onUsernameChange = useLowercaseOnInputChange(setUsername) const onPasswordChange = useOnInputChange(setPassword) return ( @@ -54,7 +55,7 @@ export const ViaLocal: React.FC = () => { - + diff --git a/frontend/src/hooks/common/use-lowercase-on-input-change.spec.tsx b/frontend/src/hooks/common/use-lowercase-on-input-change.spec.tsx new file mode 100644 index 000000000..c11a509b7 --- /dev/null +++ b/frontend/src/hooks/common/use-lowercase-on-input-change.spec.tsx @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { useLowercaseOnInputChange } from './use-lowercase-on-input-change' +import { fireEvent, render, screen } from '@testing-library/react' +import React from 'react' + +describe('useOnInputChange', () => { + it('executes the setter', async () => { + const callback = jest.fn() + const testValue = 'TEST VALUE' + + const Test: React.FC = () => { + const onChange = useLowercaseOnInputChange(callback) + return + } + + render() + + const element: HTMLInputElement = await screen.findByTestId('input') + + fireEvent.change(element, { target: { value: testValue } }) + + expect(callback).toBeCalledWith('test value') + }) +}) diff --git a/frontend/src/hooks/common/use-lowercase-on-input-change.ts b/frontend/src/hooks/common/use-lowercase-on-input-change.ts new file mode 100644 index 000000000..a741d48e0 --- /dev/null +++ b/frontend/src/hooks/common/use-lowercase-on-input-change.ts @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { useOnInputChange } from './use-on-input-change' +import type { ChangeEvent } from 'react' +import { useCallback } from 'react' + +/** + * Takes an input change event and sends the lower case event value to a state setter. + * + * @param setter The setter method for the state. + * @return Hook that can be used as callback for onChange. + */ +export const useLowercaseOnInputChange = ( + setter: (value: string) => void +): ((event: ChangeEvent) => void) => { + return useOnInputChange(useCallback((value) => setter(value.toLowerCase()), [setter])) +} diff --git a/frontend/src/hooks/common/use-on-input-change.spec.tsx b/frontend/src/hooks/common/use-on-input-change.spec.tsx new file mode 100644 index 000000000..e2c1160db --- /dev/null +++ b/frontend/src/hooks/common/use-on-input-change.spec.tsx @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { useOnInputChange } from './use-on-input-change' +import { fireEvent, render, screen } from '@testing-library/react' +import React from 'react' + +describe('useOnInputChange', () => { + it('executes the setter', async () => { + const callback = jest.fn() + const testValue = 'testValue' + + const Test: React.FC = () => { + const onChange = useOnInputChange(callback) + return + } + + render() + + const element: HTMLInputElement = await screen.findByTestId('input') + fireEvent.change(element, { target: { value: testValue } }) + + expect(callback).toBeCalledWith(testValue) + }) +}) diff --git a/frontend/src/hooks/common/use-on-input-change.ts b/frontend/src/hooks/common/use-on-input-change.ts index 707ff461b..58e3766d1 100644 --- a/frontend/src/hooks/common/use-on-input-change.ts +++ b/frontend/src/hooks/common/use-on-input-change.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -13,10 +13,5 @@ import { useCallback } from 'react' * @return Hook that can be used as callback for onChange. */ export const useOnInputChange = (setter: (value: string) => void): ((event: ChangeEvent) => void) => { - return useCallback( - (event) => { - setter(event.target.value) - }, - [setter] - ) + return useCallback((event) => setter(event.target.value), [setter]) } diff --git a/frontend/src/pages/register.tsx b/frontend/src/pages/register.tsx index 89e1d8538..2d58f1562 100644 --- a/frontend/src/pages/register.tsx +++ b/frontend/src/pages/register.tsx @@ -17,6 +17,7 @@ import { useUiNotifications } from '../components/notifications/ui-notification- import { RegisterError } from '../components/register-page/register-error' import { RegisterInfos } from '../components/register-page/register-infos' import { useApplicationState } from '../hooks/common/use-application-state' +import { useLowercaseOnInputChange } from '../hooks/common/use-lowercase-on-input-change' import { useOnInputChange } from '../hooks/common/use-on-input-change' import type { NextPage } from 'next' import { useRouter } from 'next/router' @@ -62,7 +63,7 @@ export const RegisterPage: NextPage = () => { return error?.backendErrorName === 'PasswordTooWeakError' }, [error]) - const onUsernameChange = useOnInputChange(setUsername) + const onUsernameChange = useLowercaseOnInputChange(setUsername) const onDisplayNameChange = useOnInputChange(setDisplayName) const onPasswordChange = useOnInputChange(setPassword) const onPasswordAgainChange = useOnInputChange(setPasswordAgain)