Skip to content

Commit

Permalink
fix: add hint for display name at idp creation (#1222)
Browse files Browse the repository at this point in the history
  • Loading branch information
Usmanfee authored Dec 4, 2024
1 parent 1ea0fa2 commit 95f4cc7
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 38 deletions.
7 changes: 6 additions & 1 deletion src/assets/locales/de/idp.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,12 @@
"field": {
"display": {
"name": "Display name",
"hint": "The name how this IdP is shown in the Central IdP selection (usually your company name)"
"hint": "The name how this IdP is shown in the Central IdP selection (usually your company name)",
"mandatoryMessage": "Display name ist obligatorisch",
"minimum": "Mindestens",
"maximum": "Maximal",
"charactersRequired": " Zeichen erforderlich",
"validCharactersIncludes": "Erlaubte Zeichen: a-z, A-Z, 0-9, !?@&#\"()_-=/*.,;: (einfache Leerzeichen, keine doppelten Leerzeichen)"
},
"alias": {
"name": "Alias",
Expand Down
7 changes: 6 additions & 1 deletion src/assets/locales/en/idp.json
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,12 @@
"field": {
"display": {
"name": "Display name",
"hint": "The name how this IdP is shown in the Central IdP selection (usually your company name)"
"hint": "The name how this IdP is shown in the Central IdP selection (usually your company name)",
"mandatoryMessage": "Display name field is mandatory",
"minimum": "Minimum",
"maximum": "Maximum",
"charactersRequired": " characters required",
"validCharactersIncludes": "Allowed characters: a-z, A-Z, 0-9, !?@&#\"()_-=/*.,;: (single spaces only, no double spacing)"
},
"alias": {
"name": "Alias",
Expand Down
97 changes: 62 additions & 35 deletions src/components/overlays/AddIDP/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,13 @@ import {
setName,
} from 'features/admin/idpApiSlice'
import { OVERLAYS } from 'types/Constants'
import { ValidatingInput } from '../CXValidatingOverlay/ValidatingInput'
import { isName } from 'types/Patterns'
import Patterns from 'types/Patterns'
import { getCentralIdp } from 'services/EnvironmentService'
import HelpOutlineIcon from '@mui/icons-material/HelpOutline'
import WarningAmberIcon from '@mui/icons-material/WarningAmber'
import { success } from 'services/NotifyService'
import CommonConnectorFormInputField from 'components/shared/basic/ReleaseProcess/components/CommonConnectorFormInputField'
import { useForm } from 'react-hook-form'

const SelectIdpProviderType = () => {
const { t } = useTranslation('idp')
Expand Down Expand Up @@ -161,35 +162,18 @@ const SelectIdpAuthType = () => {
)
}

const AddIDPPrepareForm = () => {
const { t } = useTranslation('idp')
const dispatch = useDispatch()

return (
<>
<ValidatingInput
name="name"
label={t('field.display.name')}
tooltipMessage={t('field.display.hint')}
validate={isName}
onValid={(_name, value) => {
if (!value) return
dispatch(setName(value))
}}
/>
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
}}
>
<SelectIdpAuthType />
<SelectIdpProviderType />
</div>
</>
)
}
const AddIDPPrepareForm = () => (
<div
style={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'space-between',
}}
>
<SelectIdpAuthType />
<SelectIdpProviderType />
</div>
)

export const AddIdp = () => {
const { t } = useTranslation('idp')
Expand All @@ -201,6 +185,21 @@ export const AddIdp = () => {
const [addIdp] = useAddIDPMutation()
const [updateIdp] = useUpdateIDPMutation()

const defaultFormFieldValues = {
displayName: idpData.name,
}

const {
handleSubmit,
control,
trigger,
formState: { errors, isValid },
getValues,
} = useForm({
defaultValues: defaultFormFieldValues,
mode: 'onChange',
})

const doCreateIDP = async () => {
setLoading(true)
try {
Expand All @@ -211,7 +210,7 @@ export const AddIdp = () => {
const idpUpdateData: IdentityProviderUpdate = {
identityProviderId: idp.identityProviderId,
body: {
displayName: idpData.name,
displayName: getValues()?.displayName,
oidc: {
metadataUrl: `${getCentralIdp()}/realms/CX-Central/.well-known/openid-configuration`,
clientAuthMethod: OIDCAuthMethod.SECRET_BASIC,
Expand All @@ -223,7 +222,7 @@ export const AddIdp = () => {
}
await updateIdp(idpUpdateData).unwrap()
dispatch(show(OVERLAYS.UPDATE_IDP, idp.identityProviderId))
success(t('add.success'), idpData.name)
success(t('add.success'), getValues()?.displayName)
} catch (err) {
setShowError(true)
}
Expand Down Expand Up @@ -269,6 +268,34 @@ export const AddIdp = () => {
<Trans>
<Typography variant="label3">{t('add.desc')}</Typography>
</Trans>
<CommonConnectorFormInputField
{...{
control,
trigger,
errors,
}}
name="displayName"
pattern={Patterns.idp.displayName}
trigger={() => dispatch(setName(getValues().displayName))}
maxLength={40}
minLength={3}
label={
<>
{t('field.display.name')}
<span style={{ color: 'red' }}> *</span>
</>
}
rules={{
required: `${t('field.display.mandatoryMessage')}`,
minLength: `${t('field.display.minimum')} 3 ${t(
'field.display.charactersRequired'
)}`,
pattern: `${t('field.display.validCharactersIncludes')}`,
maxLength: `${t('field.display.maximum')} 40 ${t(
'field.display.charactersRequired'
)}`,
}}
/>
<AddIDPPrepareForm />
<Typography
variant="label3"
Expand Down Expand Up @@ -338,8 +365,8 @@ export const AddIdp = () => {
) : (
<Button
variant="contained"
disabled={!idpData.name}
onClick={() => doCreateIDP()}
disabled={!isValid}
onClick={handleSubmit(() => doCreateIDP())}
>
{t('action.createIdp')}
</Button>
Expand Down
28 changes: 27 additions & 1 deletion src/types/Patterns.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
isPersonName,
isSearchUserEmail,
isValidAppOverviewSearch,
isValidIDPName,
} from './Patterns'

const TESTDATA = {
Expand All @@ -49,6 +50,24 @@ const TESTDATA = {
'BPNL01',
],
},
IDP: {
valid: [
'Tractusx',
'0000001234',
'Tract Usx123@!',
'BPN lannn',
'Foo Bar@!',
],
invalid: [
'Foo Bar ',
'Foo Bar',
' FooBar',
' ',
'FooBar%',
'FooBar$',
'0000001234$%',
],
},
MAIL: {
valid: [
'julia.jeroch@bmw.de',
Expand Down Expand Up @@ -350,7 +369,6 @@ describe('Input Pattern Tests', () => {
expect(isClientID(expr)).toBe(false)
})
})

it('Validate email search for users', () => {
TESTDATA.EMAIL_SEARCH.valid.forEach((expr) => {
expect(isSearchUserEmail(expr)).toBe(true)
Expand All @@ -367,4 +385,12 @@ describe('Input Pattern Tests', () => {
expect(isValidAppOverviewSearch(expr)).toBe(false)
})
})
it('validate idp displayName', () => {
TESTDATA.IDP.valid.forEach((expr) => {
expect(isValidIDPName(expr)).toBe(true)
})
TESTDATA.IDP.invalid.forEach((expr) => {
expect(isValidIDPName(expr)).toBe(false)
})
})
})
3 changes: 3 additions & 0 deletions src/types/Patterns.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ export const Patterns = {
idp: {
clientId: /^[a-zA-Z0-9-_]{2,80}$/,
clientSecret: /^.{1,200}$/,
displayName: /^(?!.*\s{2,})[a-zA-Z0-9!?@&#'"()_\-=/*.,;: ]*$/,
},
connectors: {
NAME: /^[^-\s()'"#@.&](?!.*[%&?,';:!\s-]{2}).{1,19}$/,
Expand Down Expand Up @@ -213,5 +214,7 @@ export const isSearchUserEmail = (expr: string) =>
Patterns.EMAIL_SEARCH.test(expr)
export const isValidAppOverviewSearch = (expr: string) =>
Patterns.appOverview.SEARCH.test(expr)
export const isValidIDPName = (expr: string) =>
Patterns.idp.displayName.test(expr)

export default Patterns

0 comments on commit 95f4cc7

Please sign in to comment.