Skip to content

Commit

Permalink
Merge pull request #15 from TeskaLabs/refactor/client-add-new-input
Browse files Browse the repository at this point in the history
Add new input cookie_domain, fix styles for Custom component
  • Loading branch information
aringocode authored Feb 1, 2023
2 parents d0a33cc + fde6be9 commit 0339ad8
Show file tree
Hide file tree
Showing 10 changed files with 107 additions and 62 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

- Refactorization of CustomDataContainer to prevent passing invalid format of `uri` prop. Added documentation. (INDIGO Sprint 221209, [!11](https://github.com/TeskaLabs/seacat-admin-webui/pull/11))

- Add new input `cookie_domain` to Clients. Fix min-max height styles for CustomComponent (INDIGO Sprint 230120, [!15](https://github.com/TeskaLabs/seacat-admin-webui/pull/15))

## v22.48

### Compatibility
Expand Down
10 changes: 8 additions & 2 deletions public/locales/cs/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
"Grant types": "Typy grantů",
"Application type": "Typ aplikace",
"Token endpoint authentication method": "Způsob autentikace pro získání tokenu",
"Cookie domain": "Cookie doména",
"Redirect URIs": "URIs k přesměrování",
"Create client": "Vytvořit klienta",
"Unknown item": "Neznámá položka"
Expand All @@ -127,18 +128,23 @@
"Response types": "Typy odpovědí",
"Grant types": "Typy grantů",
"Token endpoint auth. method": "Způsob autentikace pro získání tokenu",
"Cookie domain": "Cookie doména",
"Redirect URIs": "URIs k přesměrování",
"Redirect URI must be in absolute format without a fragment component.": "URI k přesměrování musí být v absolutním formátu a bez fragment komponenty.",
"Remove client": "Odstranit klienta"
"Remove client": "Odstranit klienta",
"Save changes": "Uložit změny",
"No changes were made": "Nebyly provedeny žádné změny"
},
"ClientFormField": {
"Add new input": "Přidat pole",
"Remove input": "Odstranit pole",
"Invalid format, input should have minimum of 8 characters": "Nesprávný formát, pole musí mít minimálně 8 znaků",
"Invalid format for cookie_domain": "Nesprávný formát pro cookie_domain",
"URI can't be empty": "URI nemůže být prázdný",
"URI have to start with https": "URI musí začínat https",
"URL hash have to be empty": "URL hash musí být prázdný",
"Choose an option": "Zvolte možnost"
"Choose an option": "Zvolte možnost",
"Required field": "Povinný údaj"
},
"CredentialsCreateContainer": {
"Create new credentials": "Vytvořit nové údaje",
Expand Down
10 changes: 8 additions & 2 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
"Grant types": "Grant types",
"Application type": "Application type",
"Token endpoint authentication method": "Token endpoint authentication method",
"Cookie domain": "Cookie domain",
"Redirect URIs": "Redirect URIs",
"Create client": "Create client",
"Unknown item": "Unknown item"
Expand All @@ -127,18 +128,23 @@
"Response types": "Response types",
"Grant types": "Grant types",
"Token endpoint auth. method": "Token endpoint auth. method",
"Cookie domain": "Cookie domain",
"Redirect URIs": "Redirect URIs",
"Redirect URI must be in absolute format without a fragment component.": "Redirect URI must be in absolute format without a fragment component.",
"Remove client": "Remove client"
"Remove client": "Remove client",
"Save changes": "Save changes",
"No changes were made": "No changes were made"
},
"ClientFormField": {
"Add new input": "Add new input",
"Remove input": "Remove input",
"Invalid format, input should have minimum of 8 characters": "Invalid format, input should have minimum of 8 characters",
"Invalid format for cookie_domain": "Invalid format for cookie_domain",
"URI can't be empty": "URI can't be empty",
"URI have to start with https": "URI have to start with https",
"URL hash have to be empty": "URL hash have to be empty",
"Choose an option": "Choose an option"
"Choose an option": "Choose an option",
"Required field": "Required field"
},
"CredentialsCreateContainer": {
"Create new credentials": "Create new credentials",
Expand Down
13 changes: 11 additions & 2 deletions src/modules/auth/clients/ClientCreateContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ const ClientCreateContainer = (props) => {
delete body.preferred_client_id;
}

if (body.client_uri == "") {
delete body.client_uri;
}

if (body.cookie_domain == "") {
delete body.cookie_domain;
}

try {
let response = await SeaCatAuthAPI.post(`/client`, body);
if (response.statusText != 'OK') {
Expand Down Expand Up @@ -187,9 +195,10 @@ const ClientCreateContainer = (props) => {
</FormGroup>
{metaData["properties"] && Object.entries(metaData["properties"]).map(([key, value]) => {
switch(key) {
case 'redirect_uris': return(<URiInput key={key} name={key} control={control} errors={errors} append={append} remove={remove} fields={fields} labelName={t("ClientCreateContainer|Redirect URIs")}/>)
case 'client_name': return(<TextInput key={key} name={key} register={register} labelName={t('ClientCreateContainer|Client name')}/>)
case 'redirect_uris': return(<URiInput key={key} name={key} control={control} errors={errors} append={append} remove={remove} fields={fields} labelName={`${t("ClientCreateContainer|Redirect URIs")}*`}/>)
case 'client_name': return(<TextInput key={key} name={key} register={register} labelName={`${t("ClientCreateContainer|Client name")}*`}/>)
case 'client_uri': return(<TextInput key={key} name={key} register={register} labelName={t('ClientCreateContainer|Client URI')}/>)
case 'cookie_domain': return(<TextInput key={key} name={key} register={register} errors={errors} labelName={t('ClientCreateContainer|Cookie domain')}/>)
case 'preferred_client_id': return(<TextInput key={key} name={key} register={register} errors={errors} labelName={t('ClientCreateContainer|Preferred client ID')}/>)
case 'response_types': return(selectedTemplate === "Custom" && <MultiCheckbox key={key} name={key} value={value["items"]["enum"]} setValue={setValue} labelName={t('ClientCreateContainer|Response types')}/>)
case 'grant_types': return(selectedTemplate === "Custom" && <MultiCheckbox key={key} name={key} value={value["items"]["enum"]} setValue={setValue} labelName={t('ClientCreateContainer|Grant types')}/>)
Expand Down
87 changes: 49 additions & 38 deletions src/modules/auth/clients/ClientDetailContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const ClientDetailContainer = (props) => {
const advmode = useSelector(state => state.advmode.enabled);


const { handleSubmit, formState: { errors }, control, setValue, reset, register } = useForm({
const { handleSubmit, formState: { errors, isSubmitting, isDirty }, control, setValue, reset, register } = useForm({
defaultValues: {
redirect_uris: [{ text: ""}],
}
Expand Down Expand Up @@ -100,7 +100,9 @@ const ClientDetailContainer = (props) => {
await Promise.all(Object.values(values[key]).map((item, index) => {
uri.push(item.text)
}))
} else {
} else if (key == "client_name") {
body[key] = values[key];
} else if (key == "cookie_domain") {
body[key] = values[key];
}
}))
Expand All @@ -111,10 +113,7 @@ const ClientDetailContainer = (props) => {
}

try {
let response = await SeaCatAuthAPI.put(`/client/${client_id}`, {
redirect_uris: body?.redirect_uris,
client_name: body?.client_name
});
let response = await SeaCatAuthAPI.put(`/client/${client_id}`, body);
if (response.statusText != 'OK') {
throw new Error("Unable to change client details");
}
Expand All @@ -123,7 +122,6 @@ const ClientDetailContainer = (props) => {
setDisabled(false);
getClientDetail();
props.app.addAlert("success", t("ClientDetailContainer|Client updated successfully"));

} catch (e) {
setDisabled(false);
setEditMode(true);
Expand Down Expand Up @@ -169,38 +167,27 @@ const ClientDetailContainer = (props) => {
</div>
</CardHeader>
<CardBody className="card-body-client">
{client?.client_name ?
<Row className="card-body-row">
<Col md={4}>{t("ClientDetailContainer|Client name")}</Col>
{editMode ?
<Col className="client-name">
<TextInput name="client_name" register={register} disabled={disabled}/>
</Col>

<Row className="card-body-row">
<Col md={4} title="client_name">{t("ClientDetailContainer|Client name")}</Col>
{editMode ?
<Col className="client-edit">
<TextInput name="client_name" register={register} disabled={disabled}/>
</Col>
:
<Col className="client-name">{client?.client_name}</Col>
}
</Row>
:
editMode &&
<Row className="card-body-row">
<Col md={4}>{t("ClientDetailContainer|Client name")}</Col>
<TextInput name="client_name" register={register}/>
</Row>
}
<Col className="client-edit" title="client_name">{client?.client_name ? client.client_name : "N/A"}</Col>
}
</Row>
<Row className="card-body-row">
<Col md={4}>{t("ClientDetailContainer|Client ID")}</Col>
<Col md={4} title="client_id">{t("ClientDetailContainer|Client ID")}</Col>
<Col><code>{client?.client_id}</code></Col>
</Row>
{client?.client_uri &&
<Row className="card-body-row">
<Col md={4}>{t("ClientDetailContainer|Client URI")}</Col>
<Col>{client?.client_uri}</Col>
</Row>
}
<Row className="card-body-row">
<Col md={4} title="client_uri">{t("ClientDetailContainer|Client URI")}</Col>
<Col>{client?.client_uri ? client.client_uri : "N/A"}</Col>
</Row>
{client?.client_secret &&
<Row className="card-body-row">
<Col md={4}>{t("ClientDetailContainer|Client secret")}</Col>
<Col md={4} title="client_secret">{t("ClientDetailContainer|Client secret")}</Col>
<Col>
<code>{client?.client_secret}</code>
<Button
Expand All @@ -214,11 +201,11 @@ const ClientDetailContainer = (props) => {
</Row>
}
<Row className="mt-2 card-body-row">
<Col md={4}>{t("Created at")}</Col>
<Col md={4} title="created_at">{t("Created at")}</Col>
<Col><DateTime value={client?._c} /></Col>
</Row>
<Row className="card-body-row">
<Col md={4}>{t("Modified at")}</Col>
<Col md={4} title="modified_at">{t("Modified at")}</Col>
<Col><DateTime value={client?._m} /></Col>
</Row>
<Row className="card-body-row">
Expand Down Expand Up @@ -249,6 +236,16 @@ const ClientDetailContainer = (props) => {
<Col md={4} title="token_endpoint_auth_method">{t("ClientDetailContainer|Token endpoint auth. method")}</Col>
<Col title="token_endpoint_auth_method">{client?.token_endpoint_auth_method}</Col>
</Row>
<Row className="card-body-row">
<Col md={4} title="cookie_domain">{t("ClientDetailContainer|Cookie domain")}</Col>
{editMode ?
<Col className="client-edit">
<TextInput name="cookie_domain" register={register} errors={errors} disabled={disabled}/>
</Col>
:
<Col className="client-edit" title="cookie_domain">{client?.cookie_domain ? client.cookie_domain : "N/A"}</Col>
}
</Row>
<Row className="mt-3 card-body-row">
<Col md={4} title="redirect_uris">{t("ClientDetailContainer|Redirect URIs")}</Col>
<Col title="redirect_uris" className={"redirect_uris" + (editMode ? "" : " edit")}>
Expand All @@ -269,10 +266,24 @@ const ClientDetailContainer = (props) => {
<ButtonGroup>
{editMode ?
<>
<Button color="primary" type="submit" >{t("Save")}</Button>
<Button color="outline-primary" type="button" onClick={(e) => (setEditMode(false))}>{t("Cancel")}</Button>
<Button
color="primary"
type="submit"
title={isDirty ? t("ClientDetailContainer|Save changes") : t("ClientDetailContainer|No changes were made")}
disabled={!isDirty || isSubmitting}
>
{t("Save")}
</Button>
<Button
color="outline-primary"
type="button"
disabled={isSubmitting}
onClick={(e) => (setEditMode(false))}
>
{t("Cancel")}
</Button>
</>
:
:
<>
<ButtonWithAuthz
title={t("Edit")}
Expand Down
26 changes: 20 additions & 6 deletions src/modules/auth/clients/FormFields.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,41 @@ export function TextInput ({ name, register, errors, labelName, disabled }) {
const { t } = useTranslation();
const reg = register(
name,
(name == "preferred_client_id") && {
(name === "preferred_client_id") ? {
validate: {
validation: value => (/^[-_a-zA-Z0-9]{8,64}$|^$/).test(value) || t("ClientFormField|Invalid format, input should have minimum of 8 characters"),
}
}
:
(name === "cookie_domain") && {
validate: {
validation: value => (/^[a-z0-9\.-]{1,61}\.[a-z]{2,}$|^$/).test(value) || t("ClientFormField|Invalid format for cookie_domain"),
}
}
);

const isInvalid = (name) => {
if (((name === "preferred_client_id") || (name === "cookie_domain")) && (errors[name] != undefined)) {
return true;
}
return false;
}
return (
<FormGroup key={name}>
{labelName && <Label for={name}>{labelName}</Label>}
{labelName && <Label for={name} title={(name === "client_name") && t("ClientFormField|Required field")}>{labelName}</Label>}
<Input
id={name}
name={name}
type="text"
disabled={disabled}
required={name == "client_name" ? true : false}
required={(name === "client_name") ? true : false}
onChange={reg.onChange}
onBlur={reg.onBlur}
innerRef={reg.ref}
invalid={errors?.preferred_client_id && errors.preferred_client_id}
invalid={isInvalid(name)}
/>
{errors?.preferred_client_id && <FormFeedback>{errors.preferred_client_id.message}</FormFeedback>}
{name === "preferred_client_id" && (errors.preferred_client_id != undefined && <FormFeedback>{errors.preferred_client_id?.message}</FormFeedback>)}
{name === "cookie_domain" && (errors?.cookie_domain && <FormFeedback>{errors.cookie_domain?.message}</FormFeedback>)}
</FormGroup>
)
}
Expand Down Expand Up @@ -69,7 +83,7 @@ export function URiInput ({ name, control, errors, append, remove, fields, label
return (
<FormGroup title={name}>
{(labelName && name) &&
<Label for={name} title={name}>{labelName}</Label>}
<Label for={name} title={t("ClientFormField|Required field")}>{labelName}</Label>}
{fields && fields.map((item, idx) => {
return (
<InputGroup key={item.id} className="mb-1">
Expand Down
2 changes: 1 addition & 1 deletion src/modules/auth/clients/clients.scss
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ $svg-arrow: var(--svg-arrow);
.form-group {
margin-bottom: 0;
}
.client-name {
.client-edit {
height: 40px;
}
.redirect_uris {
Expand Down
2 changes: 1 addition & 1 deletion src/modules/auth/components/CustomDataContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export function CustomDataContainer({app, resources, customData, setCustomData,
</div>
</CardHeader>

<Form onSubmit={handleSubmit((values) => {onSave(values)})}>
<Form className="d-flex flex-column justify-content-between h-100" onSubmit={handleSubmit((values) => {onSave(values)})}>
<CardBody className="card-body-scroll-sm " >
{loading ?
<CellContentLoader cols={2} rows={5} />
Expand Down
6 changes: 5 additions & 1 deletion src/modules/auth/components/customdata.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.input-group .input-group-append{
margin-left: "0";
margin-left: 0;
}

.custom-data {
Expand All @@ -18,6 +18,10 @@

.custom-data-card {
grid-area: q;
.card-body-scroll-sm {
height: 200px !important;
overflow-y: auto;
}
}

@media (max-width: 576px) {
Expand Down
11 changes: 2 additions & 9 deletions src/modules/auth/credentials/credentials.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,6 @@
min-height: 20vh !important;
}

//CredentialCustomDataContainer
.card-body-scroll-sm {
max-height: 15vh;
min-height: 15vh !important;
overflow-y: auto;
}

//CredentialsDetailContainer/Credentials Status
.credential-status {
display: inline-block;
Expand Down Expand Up @@ -78,7 +71,7 @@
grid-template-areas:
"top"
"bottom";
grid-template-columns: "1fr";
grid-template-rows: 2fr 1fr;
}

.info-detail-area {
Expand All @@ -88,7 +81,7 @@
grid-template-areas:
"i"
"q";
grid-template-columns: "1fr";
grid-template-rows: 1fr 1fr;
}
}

Expand Down

0 comments on commit 0339ad8

Please sign in to comment.