web: migrate checkbox to switch (#4409)

* start migrating to switch

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* general cleanup

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* remove broken Create provider

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate all

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* migrate table selectors, fix dark theme

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens L 2023-01-11 13:37:49 +01:00 committed by GitHub
parent f7037b9f33
commit ddbd8153e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 702 additions and 399 deletions

View File

@ -243,15 +243,15 @@ export class AdminInterface extends AKElement {
<ak-sidebar-item path="/policy/policies"> <ak-sidebar-item path="/policy/policies">
<span slot="label">${t`Policies`}</span> <span slot="label">${t`Policies`}</span>
</ak-sidebar-item> </ak-sidebar-item>
<ak-sidebar-item path="/policy/reputation">
<span slot="label">${t`Reputation scores`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/core/property-mappings"> <ak-sidebar-item path="/core/property-mappings">
<span slot="label">${t`Property Mappings`}</span> <span slot="label">${t`Property Mappings`}</span>
</ak-sidebar-item> </ak-sidebar-item>
<ak-sidebar-item path="/blueprints/instances"> <ak-sidebar-item path="/blueprints/instances">
<span slot="label">${t`Blueprints`}</span> <span slot="label">${t`Blueprints`}</span>
</ak-sidebar-item> </ak-sidebar-item>
<ak-sidebar-item path="/policy/reputation">
<span slot="label">${t`Reputation scores`}</span>
</ak-sidebar-item>
</ak-sidebar-item> </ak-sidebar-item>
<ak-sidebar-item> <ak-sidebar-item>
<span slot="label">${t`Flows & Stages`}</span> <span slot="label">${t`Flows & Stages`}</span>

View File

@ -1,4 +1,3 @@
import "@goauthentik/admin/providers/ProviderWizard";
import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG, config } from "@goauthentik/common/api/config";
import { first, groupBy } from "@goauthentik/common/utils"; import { first, groupBy } from "@goauthentik/common/utils";
import "@goauthentik/elements/forms/FormGroup"; import "@goauthentik/elements/forms/FormGroup";
@ -139,15 +138,8 @@ export class ApplicationForm extends ModelForm<Application, string> {
> >
</ak-search-select> </ak-search-select>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Select a provider that this application should use. Alternatively, create a new provider.`} ${t`Select a provider that this application should use.`}
</p> </p>
<ak-provider-wizard
.finalHandler=${async () => {
this.requestUpdate();
}}
createText=${t`Create provider`}
>
</ak-provider-wizard>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${t`Policy engine mode`} label=${t`Policy engine mode`}
@ -172,7 +164,7 @@ export class ApplicationForm extends ModelForm<Application, string> {
> >
</ak-radio> </ak-radio>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-group .expanded=${true}> <ak-form-group>
<span slot="header"> ${t`UI settings`} </span> <span slot="header"> ${t`UI settings`} </span>
<div slot="body" class="pf-c-form"> <div slot="body" class="pf-c-form">
<ak-form-element-horizontal label=${t`Launch URL`} name="metaLaunchUrl"> <ak-form-element-horizontal label=${t`Launch URL`} name="metaLaunchUrl">
@ -186,14 +178,19 @@ export class ApplicationForm extends ModelForm<Application, string> {
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="openInNewTab"> <ak-form-element-horizontal name="openInNewTab">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.openInNewTab, false)} ?checked=${first(this.instance?.openInNewTab, false)}
/> />
<label class="pf-c-check__label"> ${t`Open in new tab`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Open in new tab`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`If checked, the launch URL will open in a new browser tab or window from the user's application library.`} ${t`If checked, the launch URL will open in a new browser tab or window from the user's application library.`}
</p> </p>
@ -218,20 +215,28 @@ export class ApplicationForm extends ModelForm<Application, string> {
${this.instance?.metaIcon ${this.instance?.metaIcon
? html` ? html`
<ak-form-element-horizontal> <ak-form-element-horizontal>
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
@change=${(ev: Event) => { @change=${(ev: Event) => {
const target = const target =
ev.target as HTMLInputElement; ev.target as HTMLInputElement;
this.clearIcon = target.checked; this.clearIcon = target.checked;
}} }}
/> />
<label class="pf-c-check__label"> <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">
${t`Clear icon`} ${t`Clear icon`}
</label> </span>
</div> </label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Delete currently set icon.`} ${t`Delete currently set icon.`}
</p> </p>

View File

@ -87,14 +87,19 @@ export class BlueprintForm extends ModelForm<BlueprintInstance, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled"> <ak-form-element-horizontal name="enabled">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.enabled, true)} ?checked=${first(this.instance?.enabled, true)}
/> />
<label class="pf-c-check__label"> ${t`Enabled`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Enabled`}</span>
</label>
<p class="pf-c-form__helper-text">${t`Disabled blueprints are never applied.`}</p> <p class="pf-c-form__helper-text">${t`Disabled blueprints are never applied.`}</p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<div class="pf-c-card pf-m-selectable pf-m-selected"> <div class="pf-c-card pf-m-selectable pf-m-selected">

View File

@ -163,14 +163,19 @@ export class TransportForm extends ModelForm<NotificationTransport, string> {
</ak-search-select> </ak-search-select>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="sendOnce"> <ak-form-element-horizontal name="sendOnce">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.sendOnce, false)} ?checked=${first(this.instance?.sendOnce, false)}
/> />
<label class="pf-c-check__label"> ${t`Send once`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Send once`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Only send notification once, for example when sending a webhook into a chat channel.`} ${t`Only send notification once, for example when sending a webhook into a chat channel.`}
</p> </p>

View File

@ -205,14 +205,19 @@ export class FlowForm extends ModelForm<Flow, string> {
<span slot="header"> ${t`Behavior settings`} </span> <span slot="header"> ${t`Behavior settings`} </span>
<div slot="body" class="pf-c-form"> <div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="compatibilityMode"> <ak-form-element-horizontal name="compatibilityMode">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.compatibilityMode, false)} ?checked=${first(this.instance?.compatibilityMode, false)}
/> />
<label class="pf-c-check__label"> ${t`Compatibility mode`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Compatibility mode`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Increases compatibility with password managers and mobile devices.`} ${t`Increases compatibility with password managers and mobile devices.`}
</p> </p>
@ -333,20 +338,28 @@ export class FlowForm extends ModelForm<Flow, string> {
${this.instance?.background ${this.instance?.background
? html` ? html`
<ak-form-element-horizontal> <ak-form-element-horizontal>
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
@change=${(ev: Event) => { @change=${(ev: Event) => {
const target = const target =
ev.target as HTMLInputElement; ev.target as HTMLInputElement;
this.clearBackground = target.checked; this.clearBackground = target.checked;
}} }}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Clear background image`} <span class="pf-c-switch__toggle-icon">
</label> <i
</div> class="fas fa-check"
aria-hidden="true"
></i>
</span>
</span>
<span class="pf-c-switch__label">
${t`Clear icon`}
</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Delete currently set background image.`} ${t`Delete currently set background image.`}
</p> </p>

View File

@ -8,7 +8,7 @@ import "@goauthentik/elements/forms/SearchSelect";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit"; import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import { until } from "lit/directives/until.js"; import { until } from "lit/directives/until.js";
@ -24,15 +24,20 @@ import {
@customElement("ak-stage-binding-form") @customElement("ak-stage-binding-form")
export class StageBindingForm extends ModelForm<FlowStageBinding, string> { export class StageBindingForm extends ModelForm<FlowStageBinding, string> {
loadInstance(pk: string): Promise<FlowStageBinding> { async loadInstance(pk: string): Promise<FlowStageBinding> {
return new FlowsApi(DEFAULT_CONFIG).flowsBindingsRetrieve({ const binding = await new FlowsApi(DEFAULT_CONFIG).flowsBindingsRetrieve({
fsbUuid: pk, fsbUuid: pk,
}); });
this.defaultOrder = await this.getOrder();
return binding;
} }
@property() @property()
targetPk?: string; targetPk?: string;
@state()
defaultOrder = 0;
getSuccessMessage(): string { getSuccessMessage(): string {
if (this.instance?.pk) { if (this.instance?.pk) {
return t`Successfully updated binding.`; return t`Successfully updated binding.`;
@ -131,36 +136,45 @@ export class StageBindingForm extends ModelForm<FlowStageBinding, string> {
</ak-search-select> </ak-search-select>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Order`} ?required=${true} name="order"> <ak-form-element-horizontal label=${t`Order`} ?required=${true} name="order">
<!-- @ts-ignore -->
<input <input
type="number" type="number"
value="${until(this.getOrder())}" value="${first(this.instance?.order, this.defaultOrder)}"
class="pf-c-form-control" class="pf-c-form-control"
required required
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="evaluateOnPlan"> <ak-form-element-horizontal name="evaluateOnPlan">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.evaluateOnPlan, true)} ?checked=${first(this.instance?.evaluateOnPlan, true)}
/> />
<label class="pf-c-check__label"> ${t`Evaluate on plan`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Evaluate on plan`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Evaluate policies during the Flow planning process. Disable this for input-based policies. Should be used in conjunction with 'Re-evaluate policies', as with both options disabled, policies are **not** evaluated.`} ${t`Evaluate policies during the Flow planning process. Disable this for input-based policies. Should be used in conjunction with 'Re-evaluate policies', as with both options disabled, policies are **not** evaluated.`}
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="reEvaluatePolicies"> <ak-form-element-horizontal name="reEvaluatePolicies">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.reEvaluatePolicies, false)} ?checked=${first(this.instance?.reEvaluatePolicies, false)}
/> />
<label class="pf-c-check__label"> ${t`Re-evaluate policies`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Re-evaluate policies`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Evaluate policies before the Stage is present to the user.`} ${t`Evaluate policies before the Stage is present to the user.`}
</p> </p>

View File

@ -71,14 +71,19 @@ export class GroupForm extends ModelForm<Group, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="isSuperuser"> <ak-form-element-horizontal name="isSuperuser">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.isSuperuser, false)} ?checked=${first(this.instance?.isSuperuser, false)}
/> />
<label class="pf-c-check__label"> ${t`Is superuser`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Is superuser`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Users added to this group will be superusers.`} ${t`Users added to this group will be superusers.`}
</p> </p>

View File

@ -1,21 +1,21 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { docLink } from "@goauthentik/common/global"; import { docLink } from "@goauthentik/common/global";
import { groupBy } from "@goauthentik/common/utils"; import { first, groupBy } from "@goauthentik/common/utils";
import "@goauthentik/elements/CodeMirror"; import "@goauthentik/elements/CodeMirror";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "@goauthentik/elements/forms/HorizontalFormElement";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm"; import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
import "@goauthentik/elements/forms/SearchSelect"; import "@goauthentik/elements/forms/SearchSelect";
import YAML from "yaml";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit"; import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import { until } from "lit/directives/until.js"; import { until } from "lit/directives/until.js";
import { import {
Outpost, Outpost,
OutpostDefaultConfig,
OutpostTypeEnum, OutpostTypeEnum,
OutpostsApi, OutpostsApi,
OutpostsServiceConnectionsAllListRequest, OutpostsServiceConnectionsAllListRequest,
@ -31,17 +31,20 @@ export class OutpostForm extends ModelForm<Outpost, string> {
@property({ type: Boolean }) @property({ type: Boolean })
embedded = false; embedded = false;
loadInstance(pk: string): Promise<Outpost> { async loadInstance(pk: string): Promise<Outpost> {
return new OutpostsApi(DEFAULT_CONFIG) const o = await new OutpostsApi(DEFAULT_CONFIG).outpostsInstancesRetrieve({
.outpostsInstancesRetrieve({ uuid: pk,
uuid: pk, });
}) this.type = o.type || OutpostTypeEnum.Proxy;
.then((o) => { this.defaultConfig = await new OutpostsApi(
this.type = o.type || OutpostTypeEnum.Proxy; DEFAULT_CONFIG,
return o; ).outpostsInstancesDefaultSettingsRetrieve();
}); return o;
} }
@state()
defaultConfig?: OutpostDefaultConfig;
getSuccessMessage(): string { getSuccessMessage(): string {
if (this.instance) { if (this.instance) {
return t`Successfully updated outpost.`; return t`Successfully updated outpost.`;
@ -205,20 +208,9 @@ export class OutpostForm extends ModelForm<Outpost, string> {
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Configuration`} name="config"> <ak-form-element-horizontal label=${t`Configuration`} name="config">
<!-- @ts-ignore -->
<ak-codemirror <ak-codemirror
mode="yaml" mode="yaml"
value="${until( value="${first(this.instance?.config, this.defaultConfig)}"
new OutpostsApi(DEFAULT_CONFIG)
.outpostsInstancesDefaultSettingsRetrieve()
.then((config) => {
let fc = config.config;
if (this.instance) {
fc = this.instance.config;
}
return YAML.stringify(fc);
}),
)}"
></ak-codemirror> ></ak-codemirror>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Set custom attributes using YAML or JSON.`} ${t`Set custom attributes using YAML or JSON.`}

View File

@ -58,14 +58,19 @@ export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnecti
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="local"> <ak-form-element-horizontal name="local">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.local, false)} ?checked=${first(this.instance?.local, false)}
/> />
<label class="pf-c-check__label"> ${t`Local`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Local`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`If enabled, use the local connection. Required Docker socket/Kubernetes Integration.`} ${t`If enabled, use the local connection. Required Docker socket/Kubernetes Integration.`}
</p> </p>

View File

@ -56,14 +56,19 @@ export class ServiceConnectionKubernetesForm extends ModelForm<
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="local"> <ak-form-element-horizontal name="local">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.local, false)} ?checked=${first(this.instance?.local, false)}
/> />
<label class="pf-c-check__label"> ${t`Local`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Local`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`If enabled, use the local connection. Required Docker socket/Kubernetes Integration.`} ${t`If enabled, use the local connection. Required Docker socket/Kubernetes Integration.`}
</p> </p>
@ -79,16 +84,21 @@ export class ServiceConnectionKubernetesForm extends ModelForm<
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="verifySsl"> <ak-form-element-horizontal name="verifySsl">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.verifySsl, true)} ?checked=${first(this.instance?.verifySsl, true)}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Verify Kubernetes API SSL Certificate`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label"
>${t`Verify Kubernetes API SSL Certificate`}</span
>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
</form>`; </form>`;
} }

View File

@ -8,9 +8,8 @@ import { t } from "@lingui/macro";
import { CSSResult, css } from "lit"; import { CSSResult, css } from "lit";
import { TemplateResult, html } from "lit"; import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import { until } from "lit/directives/until.js";
import PFContent from "@patternfly/patternfly/components/Content/content.css"; import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFToggleGroup from "@patternfly/patternfly/components/ToggleGroup/toggle-group.css"; import PFToggleGroup from "@patternfly/patternfly/components/ToggleGroup/toggle-group.css";
@ -35,23 +34,21 @@ enum target {
@customElement("ak-policy-binding-form") @customElement("ak-policy-binding-form")
export class PolicyBindingForm extends ModelForm<PolicyBinding, string> { export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
loadInstance(pk: string): Promise<PolicyBinding> { async loadInstance(pk: string): Promise<PolicyBinding> {
return new PoliciesApi(DEFAULT_CONFIG) const binding = await new PoliciesApi(DEFAULT_CONFIG).policiesBindingsRetrieve({
.policiesBindingsRetrieve({ policyBindingUuid: pk,
policyBindingUuid: pk, });
}) if (binding?.policyObj) {
.then((binding) => { this.policyGroupUser = target.policy;
if (binding?.policyObj) { }
this.policyGroupUser = target.policy; if (binding?.groupObj) {
} this.policyGroupUser = target.group;
if (binding?.groupObj) { }
this.policyGroupUser = target.group; if (binding?.userObj) {
} this.policyGroupUser = target.user;
if (binding?.userObj) { }
this.policyGroupUser = target.user; this.defaultOrder = await this.getOrder();
} return binding;
return binding;
});
} }
@property() @property()
@ -63,6 +60,9 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
@property({ type: Boolean }) @property({ type: Boolean })
policyOnly = false; policyOnly = false;
@state()
defaultOrder = 0;
getSuccessMessage(): string { getSuccessMessage(): string {
if (this.instance?.pk) { if (this.instance?.pk) {
return t`Successfully updated binding.`; return t`Successfully updated binding.`;
@ -277,33 +277,42 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
value=${ifDefined(this.instance?.target || this.targetPk)} value=${ifDefined(this.instance?.target || this.targetPk)}
/> />
<ak-form-element-horizontal name="enabled"> <ak-form-element-horizontal name="enabled">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.enabled, true)} ?checked=${first(this.instance?.enabled, true)}
/> />
<label class="pf-c-check__label"> ${t`Enabled`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Enabled`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="negate"> <ak-form-element-horizontal name="negate">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.negate, false)} ?checked=${first(this.instance?.negate, false)}
/> />
<label class="pf-c-check__label"> ${t`Negate result`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Negate result`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Negates the outcome of the binding. Messages are unaffected.`} ${t`Negates the outcome of the binding. Messages are unaffected.`}
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Order`} ?required=${true} name="order"> <ak-form-element-horizontal label=${t`Order`} ?required=${true} name="order">
<!-- @ts-ignore -->
<input <input
type="number" type="number"
value="${until(this.getOrder())}" value="${first(this.instance?.order, this.defaultOrder)}"
class="pf-c-form-control" class="pf-c-form-control"
required required
/> />

View File

@ -55,14 +55,19 @@ export class DummyPolicyForm extends ModelForm<DummyPolicy, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging"> <ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, true)}
?checked=${first(this.instance?.executionLogging, false)}
/> />
<label class="pf-c-check__label"> ${t`Execution logging`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Execution logging`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`} ${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`}
</p> </p>
@ -71,14 +76,19 @@ export class DummyPolicyForm extends ModelForm<DummyPolicy, string> {
<span slot="header"> ${t`Policy-specific settings`} </span> <span slot="header"> ${t`Policy-specific settings`} </span>
<div slot="body" class="pf-c-form"> <div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="result"> <ak-form-element-horizontal name="result">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.result, false)} ?checked=${first(this.instance?.result, false)}
/> />
<label class="pf-c-check__label"> ${t`Pass policy?`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Pass policy?`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${t`Wait (min)`} label=${t`Wait (min)`}

View File

@ -57,14 +57,19 @@ export class EventMatcherPolicyForm extends ModelForm<EventMatcherPolicy, string
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging"> <ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, true)}
?checked=${first(this.instance?.executionLogging, false)}
/> />
<label class="pf-c-check__label"> ${t`Execution logging`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Execution logging`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`} ${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`}
</p> </p>

View File

@ -55,14 +55,19 @@ export class PasswordExpiryPolicyForm extends ModelForm<PasswordExpiryPolicy, st
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging"> <ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, true)}
?checked=${first(this.instance?.executionLogging, false)}
/> />
<label class="pf-c-check__label"> ${t`Execution logging`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Execution logging`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`} ${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`}
</p> </p>
@ -83,16 +88,21 @@ export class PasswordExpiryPolicyForm extends ModelForm<PasswordExpiryPolicy, st
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="denyOnly"> <ak-form-element-horizontal name="denyOnly">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.denyOnly, false)} ?checked=${first(this.instance?.denyOnly, false)}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Only fail the policy, don't invalidate user's password.`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label"
>${t`Only fail the policy, don't invalidate user's password`}</span
>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
</div> </div>
</ak-form-group> </ak-form-group>

View File

@ -57,14 +57,19 @@ export class ExpressionPolicyForm extends ModelForm<ExpressionPolicy, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging"> <ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, true)}
?checked=${first(this.instance?.executionLogging, false)}
/> />
<label class="pf-c-check__label"> ${t`Execution logging`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Execution logging`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`} ${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`}
</p> </p>

View File

@ -233,14 +233,19 @@ export class PasswordPolicyForm extends ModelForm<PasswordPolicy, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging"> <ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, true)}
?checked=${first(this.instance?.executionLogging, false)}
/> />
<label class="pf-c-check__label"> ${t`Execution logging`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Execution logging`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`} ${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`}
</p> </p>
@ -262,32 +267,42 @@ export class PasswordPolicyForm extends ModelForm<PasswordPolicy, string> {
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="checkStaticRules"> <ak-form-element-horizontal name="checkStaticRules">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.checkStaticRules, true)} ?checked=${first(this.instance?.checkStaticRules, true)}
@change=${(ev: Event) => { @change=${(ev: Event) => {
const el = ev.target as HTMLInputElement; const el = ev.target as HTMLInputElement;
this.showStatic = el.checked; this.showStatic = el.checked;
}} }}
/> />
<label class="pf-c-check__label"> ${t`Check static rules`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Check static rules`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="checkHaveIBeenPwned"> <ak-form-element-horizontal name="checkHaveIBeenPwned">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.checkHaveIBeenPwned, true)} ?checked=${first(this.instance?.checkHaveIBeenPwned, true)}
@change=${(ev: Event) => { @change=${(ev: Event) => {
const el = ev.target as HTMLInputElement; const el = ev.target as HTMLInputElement;
this.showHIBP = el.checked; this.showHIBP = el.checked;
}} }}
/> />
<label class="pf-c-check__label"> ${t`Check haveibeenpwned.com`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Check haveibeenpwned.com`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`For more info see:`} ${t`For more info see:`}
<a href="https://haveibeenpwned.com/API/v2#SearchingPwnedPasswordsByRange" <a href="https://haveibeenpwned.com/API/v2#SearchingPwnedPasswordsByRange"
@ -296,18 +311,23 @@ export class PasswordPolicyForm extends ModelForm<PasswordPolicy, string> {
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="checkZxcvbn"> <ak-form-element-horizontal name="checkZxcvbn">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.checkZxcvbn, true)} ?checked=${first(this.instance?.checkZxcvbn, true)}
@change=${(ev: Event) => { @change=${(ev: Event) => {
const el = ev.target as HTMLInputElement; const el = ev.target as HTMLInputElement;
this.showZxcvbn = el.checked; this.showZxcvbn = el.checked;
}} }}
/> />
<label class="pf-c-check__label"> ${t`Check zxcvbn`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Check zxcvbn`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Password strength estimator created by Dropbox, see:`} ${t`Password strength estimator created by Dropbox, see:`}
<a href="https://github.com/dropbox/zxcvbn#readme">dropbox/zxcvbn</a> <a href="https://github.com/dropbox/zxcvbn#readme">dropbox/zxcvbn</a>

View File

@ -64,14 +64,19 @@ export class ReputationPolicyForm extends ModelForm<ReputationPolicy, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging"> <ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, true)}
?checked=${first(this.instance?.executionLogging, false)}
/> />
<label class="pf-c-check__label"> ${t`Execution logging`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Execution logging`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`} ${t`When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.`}
</p> </p>
@ -80,24 +85,34 @@ export class ReputationPolicyForm extends ModelForm<ReputationPolicy, string> {
<span slot="header"> ${t`Policy-specific settings`} </span> <span slot="header"> ${t`Policy-specific settings`} </span>
<div slot="body" class="pf-c-form"> <div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="checkIp"> <ak-form-element-horizontal name="checkIp">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.checkIp, false)} ?checked=${first(this.instance?.checkIp, false)}
/> />
<label class="pf-c-check__label"> ${t`Check IP`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Check IP`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="checkUsername"> <ak-form-element-horizontal name="checkUsername">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.checkUsername, false)} ?checked=${first(this.instance?.checkUsername, false)}
/> />
<label class="pf-c-check__label"> ${t`Check Username`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Check Username`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${t`Threshold`} label=${t`Threshold`}

View File

@ -130,12 +130,10 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
<div class="pf-c-toolbar__group pf-m-filter-group"> <div class="pf-c-toolbar__group pf-m-filter-group">
<div class="pf-c-toolbar__item pf-m-search-filter"> <div class="pf-c-toolbar__item pf-m-search-filter">
<div class="pf-c-input-group"> <div class="pf-c-input-group">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-check__input" class="pf-c-switch__input"
type="checkbox" type="checkbox"
id="hide-managed"
name="hide-managed"
?checked=${this.hideManaged} ?checked=${this.hideManaged}
@change=${() => { @change=${() => {
this.hideManaged = !this.hideManaged; this.hideManaged = !this.hideManaged;
@ -146,10 +144,13 @@ export class PropertyMappingListPage extends TablePage<PropertyMapping> {
}); });
}} }}
/> />
<label class="pf-c-check__label" for="hide-managed" <span class="pf-c-switch__toggle">
>${t`Hide managed mappings`}</label <span class="pf-c-switch__toggle-icon">
> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label">${t`Hide managed mappings`}</span>
</label>
</div> </div>
</div> </div>
</div>`; </div>`;

View File

@ -13,8 +13,7 @@ import "@goauthentik/elements/events/ObjectChangelog";
import { t } from "@lingui/macro"; import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, html } from "lit"; import { CSSResult, TemplateResult, html } from "lit";
import { until } from "lit-html/directives/until.js"; import { customElement, property, state } from "lit/decorators.js";
import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import AKGlobal from "@goauthentik/common/styles/authentik.css"; import AKGlobal from "@goauthentik/common/styles/authentik.css";
@ -30,7 +29,7 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css"; import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { LDAPProvider, ProvidersApi } from "@goauthentik/api"; import { LDAPProvider, ProvidersApi, SessionUser } from "@goauthentik/api";
@customElement("ak-provider-ldap-view") @customElement("ak-provider-ldap-view")
export class LDAPProviderViewPage extends AKElement { export class LDAPProviderViewPage extends AKElement {
@ -51,6 +50,9 @@ export class LDAPProviderViewPage extends AKElement {
@property({ attribute: false }) @property({ attribute: false })
provider?: LDAPProvider; provider?: LDAPProvider;
@state()
me?: SessionUser;
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return [ return [
PFBase, PFBase,
@ -74,6 +76,9 @@ export class LDAPProviderViewPage extends AKElement {
if (!this.provider?.pk) return; if (!this.provider?.pk) return;
this.providerID = this.provider?.pk; this.providerID = this.provider?.pk;
}); });
me().then((user) => {
this.me = user;
});
} }
render(): TemplateResult { render(): TemplateResult {
@ -185,18 +190,13 @@ export class LDAPProviderViewPage extends AKElement {
<label class="pf-c-form__label"> <label class="pf-c-form__label">
<span class="pf-c-form__label-text">${t`Bind DN`}</span> <span class="pf-c-form__label-text">${t`Bind DN`}</span>
</label> </label>
<!-- @ts-ignore -->
<input <input
class="pf-c-form-control" class="pf-c-form-control"
readonly readonly
type="text" type="text"
value=${until( value=${`cn=${
me().then((m) => { this.me?.user.username
return `cn=${ },ou=users,${this.provider?.baseDn?.toLowerCase()}`}
m.user.username
},ou=users,${this.provider?.baseDn?.toLowerCase()}`;
}),
)}
/> />
</div> </div>
<div class="pf-c-form__group"> <div class="pf-c-form__group">

View File

@ -347,16 +347,19 @@ ${this.instance?.redirectUris}</textarea
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="includeClaimsInIdToken"> <ak-form-element-horizontal name="includeClaimsInIdToken">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.includeClaimsInIdToken, true)} ?checked=${first(this.instance?.includeClaimsInIdToken, true)}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Include claims in id_token`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label">${t`Include claims in id_token`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint.`} ${t`Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint.`}
</p> </p>

View File

@ -204,16 +204,21 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="internalHostSslValidation"> <ak-form-element-horizontal name="internalHostSslValidation">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.internalHostSslValidation, true)} ?checked=${first(this.instance?.internalHostSslValidation, true)}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Internal host SSL Validation`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label"
>${t`Internal host SSL Validation`}</span
>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Validate SSL Certificates of upstream servers.`} ${t`Validate SSL Certificates of upstream servers.`}
</p> </p>
@ -437,20 +442,25 @@ ${this.instance?.skipPathRegex}</textarea
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="basicAuthEnabled"> <ak-form-element-horizontal name="basicAuthEnabled">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.basicAuthEnabled, false)} ?checked=${first(this.instance?.basicAuthEnabled, false)}
@change=${(ev: Event) => { @change=${(ev: Event) => {
const el = ev.target as HTMLInputElement; const el = ev.target as HTMLInputElement;
this.showHttpBasic = el.checked; this.showHttpBasic = el.checked;
}} }}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Set HTTP-Basic Authentication`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label"
>${t`Set HTTP-Basic Authentication`}</span
>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Set a custom HTTP-Basic Authentication header based on values from authentik.`} ${t`Set a custom HTTP-Basic Authentication header based on values from authentik.`}
</p> </p>

View File

@ -73,47 +73,67 @@ export class LDAPSourceForm extends ModelForm<LDAPSource, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled"> <ak-form-element-horizontal name="enabled">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.enabled, true)} ?checked=${first(this.instance?.enabled, true)}
/> />
<label class="pf-c-check__label"> ${t`Enabled`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Enabled`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="syncUsers"> <ak-form-element-horizontal name="syncUsers">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.syncUsers, true)} ?checked=${first(this.instance?.syncUsers, true)}
/> />
<label class="pf-c-check__label"> ${t`Sync users`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Sync users`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="syncUsersPassword"> <ak-form-element-horizontal name="syncUsersPassword">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.syncUsersPassword, true)} ?checked=${first(this.instance?.syncUsersPassword, true)}
/> />
<label class="pf-c-check__label"> ${t`User password writeback`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`User password writeback`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Login password is synced from LDAP into authentik automatically. Enable this option only to write password changes in authentik back to LDAP.`} ${t`Login password is synced from LDAP into authentik automatically. Enable this option only to write password changes in authentik back to LDAP.`}
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="syncGroups"> <ak-form-element-horizontal name="syncGroups">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.syncGroups, true)} ?checked=${first(this.instance?.syncGroups, true)}
/> />
<label class="pf-c-check__label"> ${t`Sync groups`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Sync groups`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-group .expanded=${true}> <ak-form-group .expanded=${true}>
<span slot="header"> ${t`Connection settings`} </span> <span slot="header"> ${t`Connection settings`} </span>
@ -135,14 +155,19 @@ export class LDAPSourceForm extends ModelForm<LDAPSource, string> {
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="startTls"> <ak-form-element-horizontal name="startTls">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.startTls, true)} ?checked=${first(this.instance?.startTls, true)}
/> />
<label class="pf-c-check__label"> ${t`Enable StartTLS`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Enable StartTLS`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`To use SSL instead, use 'ldaps://' and disable this option.`} ${t`To use SSL instead, use 'ldaps://' and disable this option.`}
</p> </p>

View File

@ -244,14 +244,19 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled"> <ak-form-element-horizontal name="enabled">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.enabled, true)} ?checked=${first(this.instance?.enabled, true)}
/> />
<label class="pf-c-check__label"> ${t`Enabled`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Enabled`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${t`User matching mode`} label=${t`User matching mode`}
@ -325,19 +330,28 @@ export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
${this.instance?.icon ${this.instance?.icon
? html` ? html`
<ak-form-element-horizontal> <ak-form-element-horizontal>
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
@change=${(ev: Event) => { @change=${(ev: Event) => {
const target = ev.target as HTMLInputElement; const target = ev.target as HTMLInputElement;
this.clearIcon = target.checked; this.clearIcon = target.checked;
}} }}
/> />
<label class="pf-c-check__label"> <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">
${t`Clear icon`} ${t`Clear icon`}
</label> </span>
</div> </label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Delete currently set icon.`} ${t`Delete currently set icon.`}
</p> </p>

View File

@ -135,16 +135,21 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
${t`Re-authenticate with plex`} ${t`Re-authenticate with plex`}
</button> </button>
<ak-form-element-horizontal name="allowFriends"> <ak-form-element-horizontal name="allowFriends">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.allowFriends, true)} ?checked=${first(this.instance?.allowFriends, true)}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Allow friends to authenticate via Plex, even if you don't share any servers`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label"
>${t`Allow friends to authenticate via Plex, even if you don't share any servers`}</span
>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${t`Allowed servers`} label=${t`Allowed servers`}
@ -191,14 +196,19 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled"> <ak-form-element-horizontal name="enabled">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.enabled, true)} ?checked=${first(this.instance?.enabled, true)}
/> />
<label class="pf-c-check__label"> ${t`Enabled`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Enabled`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${t`User matching mode`} label=${t`User matching mode`}
@ -272,19 +282,27 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
${this.instance?.icon ${this.instance?.icon
? html` ? html`
<ak-form-element-horizontal> <ak-form-element-horizontal>
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
@change=${(ev: Event) => { @change=${(ev: Event) => {
const target = ev.target as HTMLInputElement; const target = ev.target as HTMLInputElement;
this.clearIcon = target.checked; this.clearIcon = target.checked;
}} }}
/> />
<label class="pf-c-check__label"> <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">
${t`Clear icon`} ${t`Clear icon`}
</label> </span>
</div> </label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Delete currently set icon.`} ${t`Delete currently set icon.`}
</p> </p>

View File

@ -103,14 +103,19 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled"> <ak-form-element-horizontal name="enabled">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.enabled, true)} ?checked=${first(this.instance?.enabled, true)}
/> />
<label class="pf-c-check__label"> ${t`Enabled`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Enabled`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal <ak-form-element-horizontal
label=${t`User matching mode`} label=${t`User matching mode`}
@ -171,19 +176,27 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
${this.instance?.icon ${this.instance?.icon
? html` ? html`
<ak-form-element-horizontal> <ak-form-element-horizontal>
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
@change=${(ev: Event) => { @change=${(ev: Event) => {
const target = ev.target as HTMLInputElement; const target = ev.target as HTMLInputElement;
this.clearIcon = target.checked; this.clearIcon = target.checked;
}} }}
/> />
<label class="pf-c-check__label"> <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">
${t`Clear icon`} ${t`Clear icon`}
</label> </span>
</div> </label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Delete currently set icon.`} ${t`Delete currently set icon.`}
</p> </p>
@ -304,16 +317,21 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
<span slot="header"> ${t`Advanced protocol settings`} </span> <span slot="header"> ${t`Advanced protocol settings`} </span>
<div slot="body" class="pf-c-form"> <div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="allowIdpInitiated"> <ak-form-element-horizontal name="allowIdpInitiated">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.allowIdpInitiated, false)} ?checked=${first(this.instance?.allowIdpInitiated, false)}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t` Allow IDP-initiated logins`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label"
>${t` Allow IDP-initiated logins`}</span
>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Allows authentication flows initiated by the IdP. This can be a security risk, as no validation of the request ID is done.`} ${t`Allows authentication flows initiated by the IdP. This can be a security risk, as no validation of the request ID is done.`}
</p> </p>

View File

@ -258,14 +258,19 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage,
? this.renderProviderGeneric() ? this.renderProviderGeneric()
: this.renderProviderTwillio()} : this.renderProviderTwillio()}
<ak-form-element-horizontal name="verifyOnly"> <ak-form-element-horizontal name="verifyOnly">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.verifyOnly, false)} ?checked=${first(this.instance?.verifyOnly, false)}
/> />
<label class="pf-c-check__label">${t`Hash phone number`}</label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Hash phone number`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`If enabled, only a hash of the phone number will be saved. This can be done for data-protection reasons. Devices created from a stage with this enabled cannot be used with the authenticator validation stage.`} ${t`If enabled, only a hash of the phone number will be saved. This can be done for data-protection reasons. Devices created from a stage with this enabled cannot be used with the authenticator validation stage.`}
</p> </p>

View File

@ -54,14 +54,19 @@ export class DummyStageForm extends ModelForm<DummyStage, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="throwError"> <ak-form-element-horizontal name="throwError">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.throwError, false)} ?checked=${first(this.instance?.throwError, false)}
/> />
<label class="pf-c-check__label"> ${t`Throw error?`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Throw error?`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
</form>`; </form>`;
} }

View File

@ -88,24 +88,34 @@ export class EmailStageForm extends ModelForm<EmailStage, string> {
<input type="text" value="" class="pf-c-form-control" /> <input type="text" value="" class="pf-c-form-control" />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="useTls"> <ak-form-element-horizontal name="useTls">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.useTls, true)} ?checked=${first(this.instance?.useTls, true)}
/> />
<label class="pf-c-check__label"> ${t`Use TLS`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Use TLS`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="useSsl"> <ak-form-element-horizontal name="useSsl">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.useSsl, false)} ?checked=${first(this.instance?.useSsl, false)}
/> />
<label class="pf-c-check__label"> ${t`Use SSL`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Use SSL`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Timeout`} ?required=${true} name="timeout"> <ak-form-element-horizontal label=${t`Timeout`} ?required=${true} name="timeout">
<input <input
@ -148,33 +158,43 @@ export class EmailStageForm extends ModelForm<EmailStage, string> {
<span slot="header"> ${t`Stage-specific settings`} </span> <span slot="header"> ${t`Stage-specific settings`} </span>
<div slot="body" class="pf-c-form"> <div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="activateUserOnSuccess"> <ak-form-element-horizontal name="activateUserOnSuccess">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.activateUserOnSuccess, true)} ?checked=${first(this.instance?.activateUserOnSuccess, true)}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Activate pending user on success`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label"
>${t`Activate pending user on success`}</span
>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When a user returns from the email successfully, their account will be activated.`} ${t`When a user returns from the email successfully, their account will be activated.`}
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="useGlobalSettings"> <ak-form-element-horizontal name="useGlobalSettings">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.useGlobalSettings, true)} ?checked=${first(this.instance?.useGlobalSettings, true)}
@change=${(ev: Event) => { @change=${(ev: Event) => {
const target = ev.target as HTMLInputElement; const target = ev.target as HTMLInputElement;
this.showConnectionSettings = !target.checked; this.showConnectionSettings = !target.checked;
}} }}
/> />
<label class="pf-c-check__label"> ${t`Use global settings`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Use global settings`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When enabled, global Email connection settings will be used and connection settings below will be ignored.`} ${t`When enabled, global Email connection settings will be used and connection settings below will be ignored.`}
</p> </p>

View File

@ -140,29 +140,37 @@ export class IdentificationStageForm extends ModelForm<IdentificationStage, stri
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="caseInsensitiveMatching"> <ak-form-element-horizontal name="caseInsensitiveMatching">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.caseInsensitiveMatching, true)} ?checked=${first(this.instance?.caseInsensitiveMatching, true)}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Case insensitive matching`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label">${t`Case insensitive matching`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When enabled, user fields are matched regardless of their casing.`} ${t`When enabled, user fields are matched regardless of their casing.`}
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="showMatchedUser"> <ak-form-element-horizontal name="showMatchedUser">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.showMatchedUser, true)} ?checked=${first(this.instance?.showMatchedUser, true)}
/> />
<label class="pf-c-check__label"> ${t`Show matched user`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Show matched user`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown.`} ${t`When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown.`}
</p> </p>
@ -216,14 +224,19 @@ export class IdentificationStageForm extends ModelForm<IdentificationStage, stri
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="showSourceLabels"> <ak-form-element-horizontal name="showSourceLabels">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.showSourceLabels, false)} ?checked=${first(this.instance?.showSourceLabels, false)}
/> />
<label class="pf-c-check__label"> ${t`Show sources' labels`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Show sources' labels`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`By default, only icons are shown for sources. Enable this to show their full names.`} ${t`By default, only icons are shown for sources. Enable this to show their full names.`}
</p> </p>

View File

@ -117,14 +117,19 @@ export class InvitationForm extends ModelForm<Invitation, string> {
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="singleUse"> <ak-form-element-horizontal name="singleUse">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.singleUse, true)} ?checked=${first(this.instance?.singleUse, true)}
/> />
<label class="pf-c-check__label"> ${t`Single use`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Single use`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When enabled, the invitation will be deleted after usage.`} ${t`When enabled, the invitation will be deleted after usage.`}
</p> </p>

View File

@ -57,19 +57,24 @@ export class InvitationStageForm extends ModelForm<InvitationStage, string> {
<span slot="header"> ${t`Stage-specific settings`} </span> <span slot="header"> ${t`Stage-specific settings`} </span>
<div slot="body" class="pf-c-form"> <div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="continueFlowWithoutInvitation"> <ak-form-element-horizontal name="continueFlowWithoutInvitation">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first( ?checked=${first(
this.instance?.continueFlowWithoutInvitation, this.instance?.continueFlowWithoutInvitation,
true, true,
)} )}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Continue flow without invitation`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label"
>${t`Continue flow without invitation`}</span
>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given.`} ${t`If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given.`}
</p> </p>

View File

@ -161,26 +161,36 @@ export class PromptForm extends ModelForm<Prompt, string> {
</select> </select>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="required"> <ak-form-element-horizontal name="required">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.required, false)} ?checked=${first(this.instance?.required, false)}
/> />
<label class="pf-c-check__label"> ${t`Required`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Required`}</span>
</label>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="placeholderExpression"> <ak-form-element-horizontal name="placeholderExpression">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.placeholderExpression, false)} ?checked=${first(this.instance?.placeholderExpression, false)}
/> />
<label class="pf-c-check__label" <span class="pf-c-switch__toggle">
>${t`Interpret placeholder as expression`}</label <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label"
>${t`Interpret placeholder as expression`}</span
> >
</div> </label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`When checked, the placeholder will be evaluated in the same way environment as a property mapping. ${t`When checked, the placeholder will be evaluated in the same way environment as a property mapping.
If the evaluation failed, the placeholder itself is returned.`} If the evaluation failed, the placeholder itself is returned.`}

View File

@ -86,16 +86,19 @@ export class UserWriteStageForm extends ModelForm<UserWriteStage, string> {
</ak-radio> </ak-radio>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="createUsersAsInactive"> <ak-form-element-horizontal name="createUsersAsInactive">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.createUsersAsInactive, true)} ?checked=${first(this.instance?.createUsersAsInactive, true)}
/> />
<label class="pf-c-check__label"> <span class="pf-c-switch__toggle">
${t`Create users as inactive`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label">${t`Create users as inactive`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Mark newly created users as inactive.`} ${t`Mark newly created users as inactive.`}
</p> </p>

View File

@ -68,14 +68,19 @@ export class TenantForm extends ModelForm<Tenant, string> {
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="_default"> <ak-form-element-horizontal name="_default">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?._default, false)} ?checked=${first(this.instance?._default, false)}
/> />
<label class="pf-c-check__label"> ${t`Default`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Default`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Use this tenant for each domain that doesn't have a dedicated tenant.`} ${t`Use this tenant for each domain that doesn't have a dedicated tenant.`}
</p> </p>

View File

@ -109,14 +109,19 @@ export class TokenForm extends ModelForm<Token, string> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="expiring"> <ak-form-element-horizontal name="expiring">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.expiring, true)} ?checked=${first(this.instance?.expiring, true)}
/> />
<label class="pf-c-check__label"> ${t`Expiring?`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Expiring`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`If this is selected, the token will expire. Upon expiration, the token will be rotated.`} ${t`If this is selected, the token will expire. Upon expiration, the token will be rotated.`}
</p> </p>

View File

@ -393,12 +393,10 @@ export class RelatedUserList extends Table<User> {
<div class="pf-c-toolbar__group pf-m-filter-group"> <div class="pf-c-toolbar__group pf-m-filter-group">
<div class="pf-c-toolbar__item pf-m-search-filter"> <div class="pf-c-toolbar__item pf-m-search-filter">
<div class="pf-c-input-group"> <div class="pf-c-input-group">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-check__input" class="pf-c-switch__input"
type="checkbox" type="checkbox"
id="hide-service-accounts"
name="hide-service-accounts"
?checked=${this.hideServiceAccounts} ?checked=${this.hideServiceAccounts}
@change=${() => { @change=${() => {
this.hideServiceAccounts = !this.hideServiceAccounts; this.hideServiceAccounts = !this.hideServiceAccounts;
@ -409,10 +407,13 @@ export class RelatedUserList extends Table<User> {
}); });
}} }}
/> />
<label class="pf-c-check__label" for="hide-service-accounts"> <span class="pf-c-switch__toggle">
${t`Hide service-accounts`} <span class="pf-c-switch__toggle-icon">
</label> <i class="fas fa-check" aria-hidden="true"></i>
</div> </span>
</span>
<span class="pf-c-switch__label">${t`Hide service-accounts`}</span>
</label>
</div> </div>
</div> </div>
</div>`; </div>`;

View File

@ -43,10 +43,15 @@ export class ServiceAccountForm extends Form<UserServiceAccountRequest> {
</p> </p>
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="createGroup"> <ak-form-element-horizontal name="createGroup">
<div class="pf-c-check"> <label class="pf-c-switch">
<input type="checkbox" class="pf-c-check__input" ?checked=${true} /> <input class="pf-c-switch__input" type="checkbox" ?checked=${true} />
<label class="pf-c-check__label"> ${t`Create group`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Create group`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Enabling this toggle will create a group named after the user, with the user as member.`} ${t`Enabling this toggle will create a group named after the user, with the user as member.`}
</p> </p>

View File

@ -93,14 +93,19 @@ export class UserForm extends ModelForm<User, number> {
/> />
</ak-form-element-horizontal> </ak-form-element-horizontal>
<ak-form-element-horizontal name="isActive"> <ak-form-element-horizontal name="isActive">
<div class="pf-c-check"> <label class="pf-c-switch">
<input <input
class="pf-c-switch__input"
type="checkbox" type="checkbox"
class="pf-c-check__input"
?checked=${first(this.instance?.isActive, true)} ?checked=${first(this.instance?.isActive, true)}
/> />
<label class="pf-c-check__label"> ${t`Is active`} </label> <span class="pf-c-switch__toggle">
</div> <span class="pf-c-switch__toggle-icon">
<i class="fas fa-check" aria-hidden="true"></i>
</span>
</span>
<span class="pf-c-switch__label">${t`Is active`}</span>
</label>
<p class="pf-c-form__helper-text"> <p class="pf-c-form__helper-text">
${t`Designates whether this user should be treated as active. Unselect this instead of deleting accounts.`} ${t`Designates whether this user should be treated as active. Unselect this instead of deleting accounts.`}
</p> </p>

View File

@ -265,6 +265,9 @@ html > form > input {
.pf-c-form-control[readonly] { .pf-c-form-control[readonly] {
background-color: var(--ak-dark-background-light); background-color: var(--ak-dark-background-light);
} }
.pf-c-switch__input:checked ~ .pf-c-switch__label {
--pf-c-switch__input--checked__label--Color: var(--ak-dark-foreground);
}
/* select toggle */ /* select toggle */
.pf-c-select__toggle::before { .pf-c-select__toggle::before {
--pf-c-select__toggle--before--BorderTopColor: var(--ak-dark-background-lighter); --pf-c-select__toggle--before--BorderTopColor: var(--ak-dark-background-lighter);

View File

@ -197,7 +197,6 @@ export class TreeView extends AKElement {
const rootItem = this.parse(this.items); const rootItem = this.parse(this.items);
return html`<div class="pf-c-tree-view pf-m-guides"> return html`<div class="pf-c-tree-view pf-m-guides">
<ul class="pf-c-tree-view__list" role="tree"> <ul class="pf-c-tree-view__list" role="tree">
<!-- @ts-ignore -->
<ak-treeview-node <ak-treeview-node
.item=${rootItem} .item=${rootItem}
activePath=${this.activePath} activePath=${this.activePath}

View File

@ -19,6 +19,7 @@ import PFCard from "@patternfly/patternfly/components/Card/card.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css"; import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css"; import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFInputGroup from "@patternfly/patternfly/components/InputGroup/input-group.css"; import PFInputGroup from "@patternfly/patternfly/components/InputGroup/input-group.css";
import PFSwitch from "@patternfly/patternfly/components/Switch/switch.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { ResponseError, ValidationError } from "@goauthentik/api"; import { ResponseError, ValidationError } from "@goauthentik/api";
@ -60,6 +61,7 @@ export class Form<T> extends AKElement {
PFAlert, PFAlert,
PFInputGroup, PFInputGroup,
PFFormControl, PFFormControl,
PFSwitch,
AKGlobal, AKGlobal,
css` css`
select[multiple] { select[multiple] {

View File

@ -11,6 +11,7 @@ import { ifDefined } from "lit/directives/if-defined.js";
import PFContent from "@patternfly/patternfly/components/Content/content.css"; import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css"; import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFSidebar from "@patternfly/patternfly/components/Sidebar/sidebar.css"; import PFSidebar from "@patternfly/patternfly/components/Sidebar/sidebar.css";
import PFSwitch from "@patternfly/patternfly/components/Switch/switch.css";
export abstract class TablePage<T> extends Table<T> { export abstract class TablePage<T> extends Table<T> {
abstract pageTitle(): string; abstract pageTitle(): string;
@ -18,7 +19,7 @@ export abstract class TablePage<T> extends Table<T> {
abstract pageIcon(): string; abstract pageIcon(): string;
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return super.styles.concat(PFPage, PFContent, PFSidebar); return super.styles.concat(PFPage, PFContent, PFSwitch, PFSidebar);
} }
renderSidebarBefore(): TemplateResult { renderSidebarBefore(): TemplateResult {

View File

@ -51,7 +51,6 @@ export class OAuth2DeviceCode extends BaseStage<
class="pf-c-form__group" class="pf-c-form__group"
.errors=${(this.challenge?.responseErrors || {})["code"]} .errors=${(this.challenge?.responseErrors || {})["code"]}
> >
<!-- @ts-ignore -->
<input <input
type="text" type="text"
name="code" name="code"

View File

@ -60,7 +60,6 @@ export class AuthenticatorSMSStage extends BaseStage<
class="pf-c-form__group" class="pf-c-form__group"
.errors=${(this.challenge?.responseErrors || {})["phone_number"]} .errors=${(this.challenge?.responseErrors || {})["phone_number"]}
> >
<!-- @ts-ignore -->
<input <input
type="tel" type="tel"
name="phoneNumber" name="phoneNumber"

View File

@ -77,7 +77,6 @@ export class AuthenticatorTOTPStage extends BaseStage<
<input type="hidden" name="otp_uri" value=${this.challenge.configUrl} /> <input type="hidden" name="otp_uri" value=${this.challenge.configUrl} />
<ak-form-element> <ak-form-element>
<div class="qr-container"> <div class="qr-container">
<!-- @ts-ignore -->
<qr-code data="${this.challenge.configUrl}"></qr-code> <qr-code data="${this.challenge.configUrl}"></qr-code>
<button <button
type="button" type="button"

View File

@ -195,32 +195,29 @@ export class AuthenticatorValidateStage
case DeviceClassesEnum.Static: case DeviceClassesEnum.Static:
case DeviceClassesEnum.Totp: case DeviceClassesEnum.Totp:
case DeviceClassesEnum.Sms: case DeviceClassesEnum.Sms:
return html`<!-- @ts-ignore --> return html` <ak-stage-authenticator-validate-code
<ak-stage-authenticator-validate-code .host=${this}
.host=${this} .challenge=${this.challenge}
.challenge=${this.challenge} .deviceChallenge=${this.selectedDeviceChallenge}
.deviceChallenge=${this.selectedDeviceChallenge} .showBackButton=${(this.challenge?.deviceChallenges.length || []) > 1}
.showBackButton=${(this.challenge?.deviceChallenges.length || []) > 1} >
> </ak-stage-authenticator-validate-code>`;
</ak-stage-authenticator-validate-code>`;
case DeviceClassesEnum.Webauthn: case DeviceClassesEnum.Webauthn:
return html`<!-- @ts-ignore --> return html` <ak-stage-authenticator-validate-webauthn
<ak-stage-authenticator-validate-webauthn .host=${this}
.host=${this} .challenge=${this.challenge}
.challenge=${this.challenge} .deviceChallenge=${this.selectedDeviceChallenge}
.deviceChallenge=${this.selectedDeviceChallenge} .showBackButton=${(this.challenge?.deviceChallenges.length || []) > 1}
.showBackButton=${(this.challenge?.deviceChallenges.length || []) > 1} >
> </ak-stage-authenticator-validate-webauthn>`;
</ak-stage-authenticator-validate-webauthn>`;
case DeviceClassesEnum.Duo: case DeviceClassesEnum.Duo:
return html`<!-- @ts-ignore --> return html` <ak-stage-authenticator-validate-duo
<ak-stage-authenticator-validate-duo .host=${this}
.host=${this} .challenge=${this.challenge}
.challenge=${this.challenge} .deviceChallenge=${this.selectedDeviceChallenge}
.deviceChallenge=${this.selectedDeviceChallenge} .showBackButton=${(this.challenge?.deviceChallenges.length || []) > 1}
.showBackButton=${(this.challenge?.deviceChallenges.length || []) > 1} >
> </ak-stage-authenticator-validate-duo>`;
</ak-stage-authenticator-validate-duo>`;
} }
return html``; return html``;
} }

View File

@ -14,7 +14,7 @@ import { PromptTypeEnum, StagePrompt } from "@goauthentik/api";
@customElement("ak-user-stage-prompt") @customElement("ak-user-stage-prompt")
export class UserSettingsPromptStage extends PromptStage { export class UserSettingsPromptStage extends PromptStage {
static get styles(): CSSResult[] { static get styles(): CSSResult[] {
return super.styles.concat([PFCheck]); return super.styles.concat(PFCheck);
} }
renderPromptInner(prompt: StagePrompt, placeholderAsValue: boolean): string { renderPromptInner(prompt: StagePrompt, placeholderAsValue: boolean): string {