Radius form has been isolated.
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
|
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
|
||||||
import "@goauthentik/admin/common/ak-crypto-certificate-search";
|
import "@goauthentik/admin/common/ak-crypto-certificate-search";
|
||||||
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
|
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
|
||||||
|
import { renderForm } from "@goauthentik/admin/providers/radius/RadiusProviderFormForm.js";
|
||||||
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
|
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
|
||||||
import "@goauthentik/components/ak-text-input";
|
import "@goauthentik/components/ak-text-input";
|
||||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
||||||
@ -10,91 +11,21 @@ import "@goauthentik/elements/forms/HorizontalFormElement";
|
|||||||
import { msg } from "@lit/localize";
|
import { msg } from "@lit/localize";
|
||||||
import { customElement } from "@lit/reactive-element/decorators.js";
|
import { customElement } from "@lit/reactive-element/decorators.js";
|
||||||
import { html } from "lit";
|
import { html } from "lit";
|
||||||
import { ifDefined } from "lit/directives/if-defined.js";
|
|
||||||
|
|
||||||
import { FlowsInstancesListDesignationEnum, RadiusProvider } from "@goauthentik/api";
|
import { RadiusProvider } from "@goauthentik/api";
|
||||||
|
|
||||||
import BaseProviderPanel from "../BaseProviderPanel";
|
import BaseProviderPanel from "../BaseProviderPanel";
|
||||||
|
|
||||||
@customElement("ak-application-wizard-authentication-by-radius")
|
@customElement("ak-application-wizard-authentication-by-radius")
|
||||||
export class ApplicationWizardAuthenticationByRadius extends WithBrandConfig(BaseProviderPanel) {
|
export class ApplicationWizardAuthenticationByRadius extends WithBrandConfig(BaseProviderPanel) {
|
||||||
render() {
|
render() {
|
||||||
const provider = this.wizard.provider as RadiusProvider | undefined;
|
|
||||||
const errors = this.wizard.errors.provider;
|
|
||||||
|
|
||||||
return html`<ak-wizard-title>${msg("Configure Radius Provider")}</ak-wizard-title>
|
return html`<ak-wizard-title>${msg("Configure Radius Provider")}</ak-wizard-title>
|
||||||
<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
<form class="pf-c-form pf-m-horizontal" @input=${this.handleChange}>
|
||||||
<ak-text-input
|
${renderForm(
|
||||||
name="name"
|
this.wizard.provider as RadiusProvider | undefined,
|
||||||
label=${msg("Name")}
|
this.wizard.errors.provider,
|
||||||
value=${ifDefined(provider?.name)}
|
this.brand,
|
||||||
.errorMessages=${errors?.name ?? []}
|
)}
|
||||||
required
|
|
||||||
>
|
|
||||||
</ak-text-input>
|
|
||||||
|
|
||||||
<ak-form-element-horizontal
|
|
||||||
label=${msg("Authentication flow")}
|
|
||||||
?required=${true}
|
|
||||||
name="authorizationFlow"
|
|
||||||
.errorMessages=${errors?.authorizationFlow ?? []}
|
|
||||||
>
|
|
||||||
<ak-branded-flow-search
|
|
||||||
flowType=${FlowsInstancesListDesignationEnum.Authentication}
|
|
||||||
.currentFlow=${provider?.authorizationFlow}
|
|
||||||
.brandFlow=${this.brand.flowAuthentication}
|
|
||||||
required
|
|
||||||
></ak-branded-flow-search>
|
|
||||||
<p class="pf-c-form__helper-text">
|
|
||||||
${msg("Flow used for users to authenticate.")}
|
|
||||||
</p>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
|
|
||||||
<ak-form-group expanded>
|
|
||||||
<span slot="header"> ${msg("Protocol settings")} </span>
|
|
||||||
<div slot="body" class="pf-c-form">
|
|
||||||
<ak-text-input
|
|
||||||
name="sharedSecret"
|
|
||||||
label=${msg("Shared secret")}
|
|
||||||
.errorMessages=${errors?.sharedSecret ?? []}
|
|
||||||
value=${first(
|
|
||||||
provider?.sharedSecret,
|
|
||||||
randomString(128, ascii_letters + digits),
|
|
||||||
)}
|
|
||||||
required
|
|
||||||
></ak-text-input>
|
|
||||||
<ak-text-input
|
|
||||||
name="clientNetworks"
|
|
||||||
label=${msg("Client Networks")}
|
|
||||||
value=${first(provider?.clientNetworks, "0.0.0.0/0, ::/0")}
|
|
||||||
.errorMessages=${errors?.clientNetworks ?? []}
|
|
||||||
required
|
|
||||||
help=${msg(`List of CIDRs (comma-seperated) that clients can connect from. A more specific
|
|
||||||
CIDR will match before a looser one. Clients connecting from a non-specified CIDR
|
|
||||||
will be dropped.`)}
|
|
||||||
></ak-text-input>
|
|
||||||
</div>
|
|
||||||
</ak-form-group>
|
|
||||||
<ak-form-group>
|
|
||||||
<span slot="header"> ${msg("Advanced flow settings")} </span>
|
|
||||||
<div slot="body" class="pf-c-form">
|
|
||||||
<ak-form-element-horizontal
|
|
||||||
label=${msg("Invalidation flow")}
|
|
||||||
name="invalidationFlow"
|
|
||||||
required
|
|
||||||
>
|
|
||||||
<ak-flow-search
|
|
||||||
flowType=${FlowsInstancesListDesignationEnum.Invalidation}
|
|
||||||
.currentFlow=${provider?.invalidationFlow}
|
|
||||||
defaultFlowSlug="default-provider-invalidation-flow"
|
|
||||||
required
|
|
||||||
></ak-flow-search>
|
|
||||||
<p class="pf-c-form__helper-text">
|
|
||||||
${msg("Flow used when logging out of this provider.")}
|
|
||||||
</p>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
</div></ak-form-group
|
|
||||||
>
|
|
||||||
</form>`;
|
</form>`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,48 +1,12 @@
|
|||||||
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
|
|
||||||
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
|
|
||||||
import { BaseProviderForm } from "@goauthentik/admin/providers/BaseProviderForm";
|
import { BaseProviderForm } from "@goauthentik/admin/providers/BaseProviderForm";
|
||||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
|
|
||||||
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
|
||||||
import { DualSelectPair } from "@goauthentik/elements/ak-dual-select/types";
|
|
||||||
import "@goauthentik/elements/forms/FormGroup";
|
|
||||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
|
||||||
import "@goauthentik/elements/forms/SearchSelect";
|
|
||||||
|
|
||||||
import { msg } from "@lit/localize";
|
|
||||||
import { TemplateResult, html } from "lit";
|
|
||||||
import { ifDefined } from "lit-html/directives/if-defined.js";
|
|
||||||
import { customElement } from "lit/decorators.js";
|
import { customElement } from "lit/decorators.js";
|
||||||
|
|
||||||
import {
|
import { ProvidersApi, RadiusProvider } from "@goauthentik/api";
|
||||||
FlowsInstancesListDesignationEnum,
|
|
||||||
PropertymappingsApi,
|
|
||||||
ProvidersApi,
|
|
||||||
RadiusProvider,
|
|
||||||
RadiusProviderPropertyMapping,
|
|
||||||
} from "@goauthentik/api";
|
|
||||||
|
|
||||||
export async function radiusPropertyMappingsProvider(page = 1, search = "") {
|
import { renderForm } from "./RadiusProviderFormForm.js";
|
||||||
const propertyMappings = await new PropertymappingsApi(
|
|
||||||
DEFAULT_CONFIG,
|
|
||||||
).propertymappingsProviderRadiusList({
|
|
||||||
ordering: "name",
|
|
||||||
pageSize: 20,
|
|
||||||
search: search.trim(),
|
|
||||||
page,
|
|
||||||
});
|
|
||||||
return {
|
|
||||||
pagination: propertyMappings.pagination,
|
|
||||||
options: propertyMappings.results.map((m) => [m.pk, m.name, m.name, m]),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function makeRadiusPropertyMappingsSelector(instanceMappings?: string[]) {
|
|
||||||
const localMappings = instanceMappings ? new Set(instanceMappings) : undefined;
|
|
||||||
return localMappings
|
|
||||||
? ([pk, _]: DualSelectPair) => localMappings.has(pk)
|
|
||||||
: ([_0, _1, _2, _]: DualSelectPair<RadiusProviderPropertyMapping>) => [];
|
|
||||||
}
|
|
||||||
|
|
||||||
@customElement("ak-provider-radius-form")
|
@customElement("ak-provider-radius-form")
|
||||||
export class RadiusProviderFormPage extends WithBrandConfig(BaseProviderForm<RadiusProvider>) {
|
export class RadiusProviderFormPage extends WithBrandConfig(BaseProviderForm<RadiusProvider>) {
|
||||||
@ -65,127 +29,8 @@ export class RadiusProviderFormPage extends WithBrandConfig(BaseProviderForm<Rad
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// All Provider objects have an Authorization flow, but not all providers have an Authentication
|
renderForm() {
|
||||||
// flow. Radius needs only one field, but it is not the Authorization field, it is an
|
return renderForm(this.instance ?? {}, [], this.brand);
|
||||||
// Authentication field. So, yeah, we're using the authorization field to store the
|
|
||||||
// authentication information, which is why the ak-branded-flow-search call down there looks so
|
|
||||||
// weird-- we're looking up Authentication flows, but we're storing them in the Authorization
|
|
||||||
// field of the target Provider.
|
|
||||||
renderForm(): TemplateResult {
|
|
||||||
return html`
|
|
||||||
<ak-form-element-horizontal label=${msg("Name")} required name="name">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value="${ifDefined(this.instance?.name)}"
|
|
||||||
class="pf-c-form-control"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
<ak-form-element-horizontal
|
|
||||||
label=${msg("Authentication flow")}
|
|
||||||
required
|
|
||||||
name="authorizationFlow"
|
|
||||||
>
|
|
||||||
<ak-branded-flow-search
|
|
||||||
flowType=${FlowsInstancesListDesignationEnum.Authentication}
|
|
||||||
.currentFlow=${this.instance?.authorizationFlow}
|
|
||||||
.brandFlow=${this.brand?.flowAuthentication}
|
|
||||||
required
|
|
||||||
></ak-branded-flow-search>
|
|
||||||
<p class="pf-c-form__helper-text">${msg("Flow used for users to authenticate.")}</p>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
<ak-form-element-horizontal name="mfaSupport">
|
|
||||||
<label class="pf-c-switch">
|
|
||||||
<input
|
|
||||||
class="pf-c-switch__input"
|
|
||||||
type="checkbox"
|
|
||||||
?checked=${first(this.instance?.mfaSupport, true)}
|
|
||||||
/>
|
|
||||||
<span class="pf-c-switch__toggle">
|
|
||||||
<span class="pf-c-switch__toggle-icon">
|
|
||||||
<i class="fas fa-check" aria-hidden="true"></i>
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
<span class="pf-c-switch__label">${msg("Code-based MFA Support")}</span>
|
|
||||||
</label>
|
|
||||||
<p class="pf-c-form__helper-text">
|
|
||||||
${msg(
|
|
||||||
"When enabled, code-based multi-factor authentication can be used by appending a semicolon and the TOTP code to the password. This should only be enabled if all users that will bind to this provider have a TOTP device configured, as otherwise a password may incorrectly be rejected if it contains a semicolon.",
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
|
|
||||||
<ak-form-group expanded>
|
|
||||||
<span slot="header"> ${msg("Protocol settings")} </span>
|
|
||||||
<div slot="body" class="pf-c-form">
|
|
||||||
<ak-form-element-horizontal
|
|
||||||
label=${msg("Shared secret")}
|
|
||||||
required
|
|
||||||
name="sharedSecret"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value="${first(
|
|
||||||
this.instance?.sharedSecret,
|
|
||||||
randomString(128, ascii_letters + digits),
|
|
||||||
)}"
|
|
||||||
class="pf-c-form-control"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
<ak-form-element-horizontal
|
|
||||||
label=${msg("Client Networks")}
|
|
||||||
required
|
|
||||||
name="clientNetworks"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
value="${first(this.instance?.clientNetworks, "0.0.0.0/0, ::/0")}"
|
|
||||||
class="pf-c-form-control"
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
<p class="pf-c-form__helper-text">
|
|
||||||
${msg(`List of CIDRs (comma-seperated) that clients can connect from. A more specific
|
|
||||||
CIDR will match before a looser one. Clients connecting from a non-specified CIDR
|
|
||||||
will be dropped.`)}
|
|
||||||
</p>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
<ak-form-element-horizontal
|
|
||||||
label=${msg("Property mappings")}
|
|
||||||
name="propertyMappings"
|
|
||||||
>
|
|
||||||
<ak-dual-select-dynamic-selected
|
|
||||||
.provider=${radiusPropertyMappingsProvider}
|
|
||||||
.selector=${makeRadiusPropertyMappingsSelector(
|
|
||||||
this.instance?.propertyMappings,
|
|
||||||
)}
|
|
||||||
available-label=${msg("Available Property Mappings")}
|
|
||||||
selected-label=${msg("Selected Property Mappings")}
|
|
||||||
></ak-dual-select-dynamic-selected>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
</div>
|
|
||||||
</ak-form-group>
|
|
||||||
<ak-form-group>
|
|
||||||
<span slot="header"> ${msg("Advanced flow settings")} </span>
|
|
||||||
<div slot="body" class="pf-c-form">
|
|
||||||
<ak-form-element-horizontal
|
|
||||||
label=${msg("Invalidation flow")}
|
|
||||||
name="invalidationFlow"
|
|
||||||
required
|
|
||||||
>
|
|
||||||
<ak-flow-search
|
|
||||||
flowType=${FlowsInstancesListDesignationEnum.Invalidation}
|
|
||||||
.currentFlow=${this.instance?.invalidationFlow}
|
|
||||||
defaultFlowSlug="default-provider-invalidation-flow"
|
|
||||||
required
|
|
||||||
></ak-flow-search>
|
|
||||||
<p class="pf-c-form__helper-text">
|
|
||||||
${msg("Flow used when logging out of this provider.")}
|
|
||||||
</p>
|
|
||||||
</ak-form-element-horizontal>
|
|
||||||
</div></ak-form-group
|
|
||||||
>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
161
web/src/admin/providers/radius/RadiusProviderFormForm.ts
Normal file
161
web/src/admin/providers/radius/RadiusProviderFormForm.ts
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
|
||||||
|
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
|
||||||
|
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||||
|
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
|
||||||
|
import { DualSelectPair } from "@goauthentik/elements/ak-dual-select/types";
|
||||||
|
import "@goauthentik/elements/forms/FormGroup";
|
||||||
|
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||||
|
import "@goauthentik/elements/forms/SearchSelect";
|
||||||
|
|
||||||
|
import { msg } from "@lit/localize";
|
||||||
|
import { html } from "lit";
|
||||||
|
import { ifDefined } from "lit/directives/if-defined.js";
|
||||||
|
|
||||||
|
import {
|
||||||
|
FlowsInstancesListDesignationEnum,
|
||||||
|
PropertymappingsApi,
|
||||||
|
RadiusProviderPropertyMapping,
|
||||||
|
ValidationError,
|
||||||
|
} from "@goauthentik/api";
|
||||||
|
|
||||||
|
export async function radiusPropertyMappingsProvider(page = 1, search = "") {
|
||||||
|
const propertyMappings = await new PropertymappingsApi(
|
||||||
|
DEFAULT_CONFIG,
|
||||||
|
).propertymappingsProviderRadiusList({
|
||||||
|
ordering: "name",
|
||||||
|
pageSize: 20,
|
||||||
|
search: search.trim(),
|
||||||
|
page,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
pagination: propertyMappings.pagination,
|
||||||
|
options: propertyMappings.results.map((m) => [m.pk, m.name, m.name, m]),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function makeRadiusPropertyMappingsSelector(instanceMappings?: string[]) {
|
||||||
|
const localMappings = instanceMappings ? new Set(instanceMappings) : undefined;
|
||||||
|
return localMappings
|
||||||
|
? ([pk, _]: DualSelectPair) => localMappings.has(pk)
|
||||||
|
: ([_0, _1, _2, _]: DualSelectPair<RadiusProviderPropertyMapping>) => [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const mfaHelp = msg(
|
||||||
|
"When enabled, code-based multi-factor authentication can be used by appending a semicolon and the TOTP code to the password. This should only be enabled if all users that will bind to this provider have a TOTP device configured, as otherwise a password may incorrectly be rejected if it contains a semicolon.",
|
||||||
|
);
|
||||||
|
|
||||||
|
const clientNetworksHelp = msg(
|
||||||
|
"List of CIDRs (comma-seperated) that clients can connect from. A more specific CIDR will match before a looser one. Clients connecting from a non-specified CIDR will be dropped.",
|
||||||
|
);
|
||||||
|
|
||||||
|
// All Provider objects have an Authorization flow, but not all providers have an Authentication
|
||||||
|
// flow. Radius needs only one field, but it is not the Authorization field, it is an
|
||||||
|
// Authentication field. So, yeah, we're using the authorization field to store the
|
||||||
|
// authentication information, which is why the ak-branded-flow-search call down there looks so
|
||||||
|
// weird-- we're looking up Authentication flows, but we're storing them in the Authorization
|
||||||
|
// field of the target Provider.
|
||||||
|
|
||||||
|
export function renderForm(
|
||||||
|
provider?: Partial<RadiusProvider>,
|
||||||
|
errors: ValidationError = {},
|
||||||
|
brand?: CurrentBrand,
|
||||||
|
) {
|
||||||
|
return html`
|
||||||
|
<ak-text-input
|
||||||
|
name="name"
|
||||||
|
label=${msg("Name")}
|
||||||
|
value=${ifDefined(provider?.name)}
|
||||||
|
.errorMessages=${errors?.name ?? []}
|
||||||
|
required
|
||||||
|
>
|
||||||
|
</ak-text-input>
|
||||||
|
|
||||||
|
<ak-form-element-horizontal
|
||||||
|
label=${msg("Authentication flow")}
|
||||||
|
?required=${true}
|
||||||
|
name="authorizationFlow"
|
||||||
|
.errorMessages=${errors?.authorizationFlow ?? []}
|
||||||
|
>
|
||||||
|
<ak-branded-flow-search
|
||||||
|
flowType=${FlowsInstancesListDesignationEnum.Authentication}
|
||||||
|
.currentFlow=${provider?.authorizationFlow}
|
||||||
|
.brandFlow=${brand?.flowAuthentication}
|
||||||
|
required
|
||||||
|
></ak-branded-flow-search>
|
||||||
|
<p class="pf-c-form__helper-text">${msg("Flow used for users to authenticate.")}</p>
|
||||||
|
</ak-form-element-horizontal>
|
||||||
|
|
||||||
|
<ak-form-element-horizontal name="mfaSupport">
|
||||||
|
<label class="pf-c-switch">
|
||||||
|
<input
|
||||||
|
class="pf-c-switch__input"
|
||||||
|
type="checkbox"
|
||||||
|
?checked=${provider?.mfaSupport ?? true}
|
||||||
|
/>
|
||||||
|
<span class="pf-c-switch__toggle">
|
||||||
|
<span class="pf-c-switch__toggle-icon">
|
||||||
|
<i class="fas fa-check" aria-hidden="true"></i>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
<span class="pf-c-switch__label">${msg("Code-based MFA Support")}</span>
|
||||||
|
</label>
|
||||||
|
<p class="pf-c-form__helper-text">${mfaHelp}</p>
|
||||||
|
</ak-form-element-horizontal>
|
||||||
|
|
||||||
|
<ak-form-group expanded>
|
||||||
|
<span slot="header"> ${msg("Protocol settings")} </span>
|
||||||
|
<div slot="body" class="pf-c-form">
|
||||||
|
<ak-text-input
|
||||||
|
name="sharedSecret"
|
||||||
|
label=${msg("Shared secret")}
|
||||||
|
.errorMessages=${errors?.sharedSecret ?? []}
|
||||||
|
value=${first(
|
||||||
|
provider?.sharedSecret,
|
||||||
|
randomString(128, ascii_letters + digits),
|
||||||
|
)}
|
||||||
|
required
|
||||||
|
></ak-text-input>
|
||||||
|
<ak-text-input
|
||||||
|
name="clientNetworks"
|
||||||
|
label=${msg("Client Networks")}
|
||||||
|
value=${first(provider?.clientNetworks, "0.0.0.0/0, ::/0")}
|
||||||
|
.errorMessages=${errors?.clientNetworks ?? []}
|
||||||
|
required
|
||||||
|
help=${clientNetworksHelp}
|
||||||
|
></ak-text-input>
|
||||||
|
<ak-form-element-horizontal
|
||||||
|
label=${msg("Property mappings")}
|
||||||
|
name="propertyMappings"
|
||||||
|
>
|
||||||
|
<ak-dual-select-dynamic-selected
|
||||||
|
.provider=${radiusPropertyMappingsProvider}
|
||||||
|
.selector=${makeRadiusPropertyMappingsSelector(provider?.propertyMappings)}
|
||||||
|
available-label=${msg("Available Property Mappings")}
|
||||||
|
selected-label=${msg("Selected Property Mappings")}
|
||||||
|
></ak-dual-select-dynamic-selected>
|
||||||
|
</ak-form-element-horizontal>
|
||||||
|
</div>
|
||||||
|
</ak-form-group>
|
||||||
|
<ak-form-group>
|
||||||
|
<span slot="header"> ${msg("Advanced flow settings")} </span>
|
||||||
|
<div slot="body" class="pf-c-form">
|
||||||
|
<ak-form-element-horizontal
|
||||||
|
label=${msg("Invalidation flow")}
|
||||||
|
name="invalidationFlow"
|
||||||
|
required
|
||||||
|
>
|
||||||
|
<ak-flow-search
|
||||||
|
flowType=${FlowsInstancesListDesignationEnum.Invalidation}
|
||||||
|
.currentFlow=${provider?.invalidationFlow}
|
||||||
|
.errorMessages=${errors?.invalidationFlow ?? []}
|
||||||
|
defaultFlowSlug="default-provider-invalidation-flow"
|
||||||
|
required
|
||||||
|
></ak-flow-search>
|
||||||
|
<p class="pf-c-form__helper-text">
|
||||||
|
${msg("Flow used when logging out of this provider.")}
|
||||||
|
</p>
|
||||||
|
</ak-form-element-horizontal>
|
||||||
|
</div></ak-form-group
|
||||||
|
>
|
||||||
|
`;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user