Merge pull request #862 from goauthentik/form-refresh-on-save

Form refresh on save
This commit is contained in:
Jens L 2021-05-11 14:23:32 +02:00 committed by GitHub
commit 36f7cad23b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
82 changed files with 2342 additions and 2393 deletions

View File

@ -34,7 +34,6 @@ class PlexSourceSerializer(SourceSerializer):
"allow_friends",
"plex_token",
]
extra_kwargs = {"plex_token": {"write_only": True}}
class PlexTokenRedeemSerializer(PassiveSerializer):

View File

@ -15,6 +15,7 @@ import { MessageLevel } from "../messages/Message";
import { IronFormElement } from "@polymer/iron-form/iron-form";
import { camelToSnake, convertToSlug } from "../../utils";
import { ValidationError } from "authentik-api/src";
import { EVENT_REFRESH } from "../../constants";
export class APIError extends Error {
@ -140,6 +141,12 @@ export class Form<T> extends LitElement {
level: MessageLevel.success,
message: this.getSuccessMessage()
});
this.dispatchEvent(
new CustomEvent(EVENT_REFRESH, {
bubbles: true,
composed: true,
})
);
return r;
}).catch((ex: Response) => {
if (ex.status > 399 && ex.status < 500) {

View File

@ -0,0 +1,36 @@
import { property } from "lit-element";
import { EVENT_REFRESH } from "../../constants";
import { Form } from "./Form";
export abstract class ModelForm<T, PKT extends string | number> extends Form<T> {
abstract loadInstance(pk: PKT): Promise<T>;
@property({attribute: false})
set instancePk(value: PKT) {
this._instancePk = value;
this.loadInstance(value).then(instance => {
this.instance = instance;
});
}
private _instancePk?: PKT;
@property({ attribute: false })
instance?: T = this.defaultInstance;
get defaultInstance(): T | undefined {
return undefined;
}
constructor() {
super();
this.addEventListener(EVENT_REFRESH, () => {
if (!this._instancePk) return;
this.loadInstance(this._instancePk).then(instance => {
this.instance = instance;
});
});
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,6 @@ import { t } from "@lingui/macro";
import { CSSResult, customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/buttons/Dropdown";
@ -13,18 +12,22 @@ import "../../elements/forms/ModalForm";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/forms/FormGroup";
import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-application-form")
export class ApplicationForm extends Form<Application> {
export class ApplicationForm extends ModelForm<Application, string> {
@property({ attribute: false })
application?: Application;
loadInstance(pk: string): Promise<Application> {
return new CoreApi(DEFAULT_CONFIG).coreApplicationsRead({
slug: pk
});
}
@property({ attribute: false })
provider?: number;
getSuccessMessage(): string {
if (this.application) {
if (this.instance) {
return t`Successfully updated application.`;
} else {
return t`Successfully created application.`;
@ -37,9 +40,9 @@ export class ApplicationForm extends Form<Application> {
send = (data: Application): Promise<Application | void> => {
let writeOp: Promise<Application>;
if (this.application) {
if (this.instance) {
writeOp = new CoreApi(DEFAULT_CONFIG).coreApplicationsUpdate({
slug: this.application.slug,
slug: this.instance.slug,
data: data
});
} else {
@ -72,7 +75,7 @@ export class ApplicationForm extends Form<Application> {
${Array.from(m).map(([group, providers]) => {
return html`<optgroup label=${group}>
${providers.map(p => {
const selected = (this.application?.provider === p.pk) || (this.provider === p.pk);
const selected = (this.instance?.provider === p.pk) || (this.provider === p.pk);
return html`<option ?selected=${selected} value=${ifDefined(p.pk)}>${p.name}</option>`;
})}
</optgroup>`;
@ -86,21 +89,21 @@ export class ApplicationForm extends Form<Application> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.application?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Application's display Name.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Slug`}
?required=${true}
name="slug">
<input type="text" value="${ifDefined(this.application?.slug)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.slug)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Internal application name, used in URLs.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Provider`}
name="provider">
<select class="pf-c-form-control">
<option value="" ?selected=${this.application?.provider === undefined}>---------</option>
<option value="" ?selected=${this.instance?.provider === undefined}>---------</option>
${until(new ProvidersApi(DEFAULT_CONFIG).providersAllList({}).then(providers => {
return this.groupProviders(providers.results);
}), html`<option>${t`Loading...`}</option>`)}
@ -142,10 +145,10 @@ export class ApplicationForm extends Form<Application> {
?required=${true}
name="policyEngineMode">
<select class="pf-c-form-control">
<option value=${ApplicationPolicyEngineModeEnum.Any} ?selected=${this.application?.policyEngineMode === ApplicationPolicyEngineModeEnum.Any}>
<option value=${ApplicationPolicyEngineModeEnum.Any} ?selected=${this.instance?.policyEngineMode === ApplicationPolicyEngineModeEnum.Any}>
${t`ANY, any policy must match to grant access.`}
</option>
<option value=${ApplicationPolicyEngineModeEnum.All} ?selected=${this.application?.policyEngineMode === ApplicationPolicyEngineModeEnum.All}>
<option value=${ApplicationPolicyEngineModeEnum.All} ?selected=${this.instance?.policyEngineMode === ApplicationPolicyEngineModeEnum.All}>
${t`ALL, all policies must match to grant access.`}
</option>
</select>
@ -158,23 +161,23 @@ export class ApplicationForm extends Form<Application> {
<ak-form-element-horizontal
label=${t`Launch URL`}
name="metaLaunchUrl">
<input type="text" value="${ifDefined(this.application?.metaLaunchUrl)}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.metaLaunchUrl)}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`If left empty, authentik will try to extract the launch URL based on the selected provider.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Icon`}
name="metaIcon">
<input type="file" value="${ifDefined(this.application?.metaIcon)}" class="pf-c-form-control">
<input type="file" value="${ifDefined(this.instance?.metaIcon)}" class="pf-c-form-control">
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Description`}
name="metaDescription">
<textarea class="pf-c-form-control">${ifDefined(this.application?.metaDescription)}</textarea>
<textarea class="pf-c-form-control">${ifDefined(this.instance?.metaDescription)}</textarea>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Publisher`}
name="metaPublisher">
<input type="text" value="${ifDefined(this.application?.metaPublisher)}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.metaPublisher)}" class="pf-c-form-control">
</ak-form-element-horizontal>
</div>
</ak-form-group>

View File

@ -89,7 +89,7 @@ export class ApplicationListPage extends TablePage<Application> {
<span slot="header">
${t`Update Application`}
</span>
<ak-application-form slot="form" .application=${item}>
<ak-application-form slot="form" .instancePk=${item.slug}>
</ak-application-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -102,7 +102,7 @@ export class ApplicationViewPage extends LitElement {
<span slot="header">
${t`Update Application`}
</span>
<ak-application-form slot="form" .application=${this.application}>
<ak-application-form slot="form" .instancePk=${this.application.slug}>
</ak-application-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -1,21 +1,24 @@
import { CertificateKeyPair, CryptoApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/CodeMirror";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-crypto-certificate-form")
export class CertificateKeyPairForm extends Form<CertificateKeyPair> {
export class CertificateKeyPairForm extends ModelForm<CertificateKeyPair, string> {
@property({attribute: false})
keyPair?: CertificateKeyPair;
loadInstance(pk: string): Promise<CertificateKeyPair> {
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsRead({
kpUuid: pk,
});
}
getSuccessMessage(): string {
if (this.keyPair) {
if (this.instance) {
return t`Successfully updated certificate-key pair.`;
} else {
return t`Successfully created certificate-key pair.`;
@ -23,9 +26,9 @@ export class CertificateKeyPairForm extends Form<CertificateKeyPair> {
}
send = (data: CertificateKeyPair): Promise<CertificateKeyPair> => {
if (this.keyPair) {
if (this.instance) {
return new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsPartialUpdate({
kpUuid: this.keyPair.pk || "",
kpUuid: this.instance.pk || "",
data: data
});
} else {
@ -41,21 +44,21 @@ export class CertificateKeyPairForm extends Form<CertificateKeyPair> {
label=${t`Name`}
name="name"
?required=${true}>
<input type="text" value="${ifDefined(this.keyPair?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Certificate`}
name="certificateData"
?writeOnly=${this.keyPair !== undefined}
?writeOnly=${this.instance !== undefined}
?required=${true}>
<textarea class="pf-c-form-control" required>${ifDefined(this.keyPair?.certificateData)}</textarea>
<textarea class="pf-c-form-control" required>${ifDefined(this.instance?.certificateData)}</textarea>
<p class="pf-c-form__helper-text">${t`PEM-encoded Certificate data.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
name="keyData"
?writeOnly=${this.keyPair !== undefined}
?writeOnly=${this.instance !== undefined}
label=${t`Private Key`}>
<textarea class="pf-c-form-control" >${ifDefined(this.keyPair?.keyData)}</textarea>
<textarea class="pf-c-form-control" >${ifDefined(this.instance?.keyData)}</textarea>
<p class="pf-c-form__helper-text">${t`Optional Private Key. If this is set, you can use this keypair for encryption.`}</p>
</ak-form-element-horizontal>
</form>`;

View File

@ -70,7 +70,7 @@ export class CertificateKeyPairListPage extends TablePage<CertificateKeyPair> {
<span slot="header">
${t`Update Certificate-Key Pair`}
</span>
<ak-crypto-certificate-form slot="form" .keyPair=${item}>
<ak-crypto-certificate-form slot="form" .instancePk=${item.pk}>
</ak-crypto-certificate-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -1,21 +1,24 @@
import { CoreApi, EventsApi, NotificationRule, NotificationRuleSeverityEnum } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import { until } from "lit-html/directives/until";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-event-rule-form")
export class RuleForm extends Form<NotificationRule> {
export class RuleForm extends ModelForm<NotificationRule, string> {
@property({attribute: false})
rule?: NotificationRule;
loadInstance(pk: string): Promise<NotificationRule> {
return new EventsApi(DEFAULT_CONFIG).eventsRulesRead({
pbmUuid: pk,
});
}
getSuccessMessage(): string {
if (this.rule) {
if (this.instance) {
return t`Successfully updated rule.`;
} else {
return t`Successfully created rule.`;
@ -23,9 +26,9 @@ export class RuleForm extends Form<NotificationRule> {
}
send = (data: NotificationRule): Promise<NotificationRule> => {
if (this.rule) {
if (this.instance) {
return new EventsApi(DEFAULT_CONFIG).eventsRulesUpdate({
pbmUuid: this.rule.pk || "",
pbmUuid: this.instance.pk || "",
data: data
});
} else {
@ -37,13 +40,13 @@ export class RuleForm extends Form<NotificationRule> {
renderSeverity(): TemplateResult {
return html`
<option value=${NotificationRuleSeverityEnum.Alert} ?selected=${this.rule?.severity === NotificationRuleSeverityEnum.Alert}>
<option value=${NotificationRuleSeverityEnum.Alert} ?selected=${this.instance?.severity === NotificationRuleSeverityEnum.Alert}>
${t`Alert`}
</option>
<option value=${NotificationRuleSeverityEnum.Warning} ?selected=${this.rule?.severity === NotificationRuleSeverityEnum.Warning}>
<option value=${NotificationRuleSeverityEnum.Warning} ?selected=${this.instance?.severity === NotificationRuleSeverityEnum.Warning}>
${t`Warning`}
</option>
<option value=${NotificationRuleSeverityEnum.Notice} ?selected=${this.rule?.severity === NotificationRuleSeverityEnum.Notice}>
<option value=${NotificationRuleSeverityEnum.Notice} ?selected=${this.instance?.severity === NotificationRuleSeverityEnum.Notice}>
${t`Notice`}
</option>
`;
@ -55,16 +58,16 @@ export class RuleForm extends Form<NotificationRule> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.rule?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Group`}
name="group">
<select class="pf-c-form-control">
<option value="" ?selected=${this.rule?.group === undefined}>---------</option>
<option value="" ?selected=${this.instance?.group === undefined}>---------</option>
${until(new CoreApi(DEFAULT_CONFIG).coreGroupsList({}).then(groups => {
return groups.results.map(group => {
return html`<option value=${ifDefined(group.pk)} ?selected=${this.rule?.group?.groupUuid === group.pk}>${group.name}</option>`;
return html`<option value=${ifDefined(group.pk)} ?selected=${this.instance?.group?.groupUuid === group.pk}>${group.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -76,7 +79,7 @@ export class RuleForm extends Form<NotificationRule> {
<select name="users" class="pf-c-form-control" multiple>
${until(new EventsApi(DEFAULT_CONFIG).eventsTransportsList({}).then(transports => {
return transports.results.map(transport => {
const selected = Array.from(this.rule?.transports || []).some(su => {
const selected = Array.from(this.instance?.transports || []).some(su => {
return su.uuid == transport.pk;
});
return html`<option value=${ifDefined(transport.pk)} ?selected=${selected}>${transport.name}</option>`;

View File

@ -64,7 +64,7 @@ export class RuleListPage extends TablePage<NotificationRule> {
<span slot="header">
${t`Update Notification Rule`}
</span>
<ak-event-rule-form slot="form" .rule=${item}>
<ak-event-rule-form slot="form" .instancePk=${item.pk}>
</ak-event-rule-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -3,22 +3,25 @@ import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import { first } from "../../utils";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-event-transport-form")
export class TransportForm extends Form<NotificationTransport> {
export class TransportForm extends ModelForm<NotificationTransport, string> {
@property({attribute: false})
transport?: NotificationTransport;
loadInstance(pk: string): Promise<NotificationTransport> {
return new EventsApi(DEFAULT_CONFIG).eventsTransportsRead({
uuid: pk,
});
}
@property({type: Boolean})
showWebhook = false;
getSuccessMessage(): string {
if (this.transport) {
if (this.instance) {
return t`Successfully updated transport.`;
} else {
return t`Successfully created transport.`;
@ -26,9 +29,9 @@ export class TransportForm extends Form<NotificationTransport> {
}
send = (data: NotificationTransport): Promise<NotificationTransport> => {
if (this.transport) {
if (this.instance) {
return new EventsApi(DEFAULT_CONFIG).eventsTransportsUpdate({
uuid: this.transport.pk || "",
uuid: this.instance.pk || "",
data: data
});
} else {
@ -40,21 +43,21 @@ export class TransportForm extends Form<NotificationTransport> {
renderTransportModes(): TemplateResult {
return html`
<option value=${NotificationTransportModeEnum.Email} ?selected=${this.transport?.mode === NotificationTransportModeEnum.Email}>
<option value=${NotificationTransportModeEnum.Email} ?selected=${this.instance?.mode === NotificationTransportModeEnum.Email}>
${t`Email`}
</option>
<option value=${NotificationTransportModeEnum.Webhook} ?selected=${this.transport?.mode === NotificationTransportModeEnum.Webhook}>
<option value=${NotificationTransportModeEnum.Webhook} ?selected=${this.instance?.mode === NotificationTransportModeEnum.Webhook}>
${t`Webhook (generic)`}
</option>
<option value=${NotificationTransportModeEnum.WebhookSlack} ?selected=${this.transport?.mode === NotificationTransportModeEnum.WebhookSlack}>
<option value=${NotificationTransportModeEnum.WebhookSlack} ?selected=${this.instance?.mode === NotificationTransportModeEnum.WebhookSlack}>
${t`Webhook (Slack/Discord)`}
</option>
`;
}
firstUpdated(): void {
if (this.transport) {
this.onModeChange(this.transport.mode);
if (this.instance) {
this.onModeChange(this.instance.mode);
}
}
@ -72,7 +75,7 @@ export class TransportForm extends Form<NotificationTransport> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.transport?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Mode`}
@ -89,11 +92,11 @@ export class TransportForm extends Form<NotificationTransport> {
?hidden=${!this.showWebhook}
label=${t`Webhook URL`}
name="webhookUrl">
<input type="text" value="${ifDefined(this.transport?.webhookUrl)}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.webhookUrl)}" class="pf-c-form-control">
</ak-form-element-horizontal>
<ak-form-element-horizontal name="sendOnce">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.transport?.sendOnce, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.sendOnce, false)}>
<label class="pf-c-check__label">
${t`Send once`}
</label>

View File

@ -68,7 +68,7 @@ export class TransportListPage extends TablePage<NotificationTransport> {
<span slot="header">
${t`Update Notification Transport`}
</span>
<ak-event-transport-form slot="form" .transport=${item}>
<ak-event-transport-form slot="form" .instancePk=${item.pk}>
</ak-event-transport-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -58,7 +58,7 @@ export class BoundStagesList extends Table<FlowStageBinding> {
<ak-proxy-form
slot="form"
.args=${{
"stageUUID": item.stage
"instancePk": item.stage
}}
type=${ifDefined(item.stageObj?.component)}>
</ak-proxy-form>
@ -73,7 +73,7 @@ export class BoundStagesList extends Table<FlowStageBinding> {
<span slot="header">
${t`Update Stage binding`}
</span>
<ak-stage-binding-form slot="form" .fsb=${item}>
<ak-stage-binding-form slot="form" .instancePk=${item.pk}>
</ak-stage-binding-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit Binding`}

View File

@ -1,20 +1,23 @@
import { Flow, FlowDesignationEnum, FlowPolicyEngineModeEnum, FlowsApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-flow-form")
export class FlowForm extends Form<Flow> {
export class FlowForm extends ModelForm<Flow, string> {
@property({attribute: false})
flow?: Flow;
loadInstance(pk: string): Promise<Flow> {
return new FlowsApi(DEFAULT_CONFIG).flowsInstancesRead({
slug: pk,
});
}
getSuccessMessage(): string {
if (this.flow) {
if (this.instance) {
return t`Successfully updated flow.`;
} else {
return t`Successfully created flow.`;
@ -23,9 +26,9 @@ export class FlowForm extends Form<Flow> {
send = (data: Flow): Promise<void | Flow> => {
let writeOp: Promise<Flow>;
if (this.flow) {
if (this.instance) {
writeOp = new FlowsApi(DEFAULT_CONFIG).flowsInstancesUpdate({
slug: this.flow.slug,
slug: this.instance.slug,
data: data
});
} else {
@ -47,25 +50,25 @@ export class FlowForm extends Form<Flow> {
renderDesignations(): TemplateResult {
return html`
<option value=${FlowDesignationEnum.Authentication} ?selected=${this.flow?.designation === FlowDesignationEnum.Authentication}>
<option value=${FlowDesignationEnum.Authentication} ?selected=${this.instance?.designation === FlowDesignationEnum.Authentication}>
${t`Authentication`}
</option>
<option value=${FlowDesignationEnum.Authorization} ?selected=${this.flow?.designation === FlowDesignationEnum.Authorization}>
<option value=${FlowDesignationEnum.Authorization} ?selected=${this.instance?.designation === FlowDesignationEnum.Authorization}>
${t`Authorization`}
</option>
<option value=${FlowDesignationEnum.Enrollment} ?selected=${this.flow?.designation === FlowDesignationEnum.Enrollment}>
<option value=${FlowDesignationEnum.Enrollment} ?selected=${this.instance?.designation === FlowDesignationEnum.Enrollment}>
${t`Enrollment`}
</option>
<option value=${FlowDesignationEnum.Invalidation} ?selected=${this.flow?.designation === FlowDesignationEnum.Invalidation}>
<option value=${FlowDesignationEnum.Invalidation} ?selected=${this.instance?.designation === FlowDesignationEnum.Invalidation}>
${t`Invalidation`}
</option>
<option value=${FlowDesignationEnum.Recovery} ?selected=${this.flow?.designation === FlowDesignationEnum.Recovery}>
<option value=${FlowDesignationEnum.Recovery} ?selected=${this.instance?.designation === FlowDesignationEnum.Recovery}>
${t`Recovery`}
</option>
<option value=${FlowDesignationEnum.StageConfiguration} ?selected=${this.flow?.designation === FlowDesignationEnum.StageConfiguration}>
<option value=${FlowDesignationEnum.StageConfiguration} ?selected=${this.instance?.designation === FlowDesignationEnum.StageConfiguration}>
${t`Stage Configuration`}
</option>
<option value=${FlowDesignationEnum.Unenrollment} ?selected=${this.flow?.designation === FlowDesignationEnum.Unenrollment}>
<option value=${FlowDesignationEnum.Unenrollment} ?selected=${this.instance?.designation === FlowDesignationEnum.Unenrollment}>
${t`Unenrollment`}
</option>
`;
@ -77,20 +80,20 @@ export class FlowForm extends Form<Flow> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.flow?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Title`}
?required=${true}
name="title">
<input type="text" value="${ifDefined(this.flow?.title)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.title)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Shown as the Title in Flow pages.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Slug`}
?required=${true}
name="slug">
<input type="text" value="${ifDefined(this.flow?.slug)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.slug)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Visible in the URL.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
@ -98,10 +101,10 @@ export class FlowForm extends Form<Flow> {
?required=${true}
name="policyEngineMode">
<select class="pf-c-form-control">
<option value=${FlowPolicyEngineModeEnum.Any} ?selected=${this.flow?.policyEngineMode === FlowPolicyEngineModeEnum.Any}>
<option value=${FlowPolicyEngineModeEnum.Any} ?selected=${this.instance?.policyEngineMode === FlowPolicyEngineModeEnum.Any}>
${t`ANY, any policy must match to grant access.`}
</option>
<option value=${FlowPolicyEngineModeEnum.All} ?selected=${this.flow?.policyEngineMode === FlowPolicyEngineModeEnum.All}>
<option value=${FlowPolicyEngineModeEnum.All} ?selected=${this.instance?.policyEngineMode === FlowPolicyEngineModeEnum.All}>
${t`ALL, all policies must match to grant access.`}
</option>
</select>
@ -111,7 +114,7 @@ export class FlowForm extends Form<Flow> {
?required=${true}
name="designation">
<select class="pf-c-form-control">
<option value="" ?selected=${this.flow?.designation === undefined}>---------</option>
<option value="" ?selected=${this.instance?.designation === undefined}>---------</option>
${this.renderDesignations()}
</select>
<p class="pf-c-form__helper-text">${t`Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik.`}</p>
@ -119,7 +122,7 @@ export class FlowForm extends Form<Flow> {
<ak-form-element-horizontal
label=${t`Background`}
name="background">
<input type="file" value="${ifDefined(this.flow?.background)}" class="pf-c-form-control">
<input type="file" value="${ifDefined(this.instance?.background)}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`Background shown during execution.`}</p>
</ak-form-element-horizontal>
</form>`;

View File

@ -68,7 +68,7 @@ export class FlowListPage extends TablePage<Flow> {
<span slot="header">
${t`Update Flow`}
</span>
<ak-flow-form slot="form" .flow=${item}>
<ak-flow-form slot="form" .instancePk=${item.pk}>
</ak-flow-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -3,23 +3,26 @@ import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import { first, groupBy } from "../../utils";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-stage-binding-form")
export class StageBindingForm extends Form<FlowStageBinding> {
export class StageBindingForm extends ModelForm<FlowStageBinding, string> {
@property({attribute: false})
fsb?: FlowStageBinding;
loadInstance(pk: string): Promise<FlowStageBinding> {
return new FlowsApi(DEFAULT_CONFIG).flowsBindingsRead({
fsbUuid: pk,
});
}
@property()
targetPk?: string;
getSuccessMessage(): string {
if (this.fsb) {
if (this.instance) {
return t`Successfully updated binding.`;
} else {
return t`Successfully created binding.`;
@ -27,9 +30,9 @@ export class StageBindingForm extends Form<FlowStageBinding> {
}
send = (data: FlowStageBinding): Promise<FlowStageBinding> => {
if (this.fsb) {
if (this.instance) {
return new FlowsApi(DEFAULT_CONFIG).flowsBindingsUpdate({
fsbUuid: this.fsb.pk || "",
fsbUuid: this.instance.pk || "",
data: data
});
} else {
@ -45,7 +48,7 @@ export class StageBindingForm extends Form<FlowStageBinding> {
${groupBy<Stage>(stages, (s => s.verboseName || "")).map(([group, stages]) => {
return html`<optgroup label=${group}>
${stages.map(stage => {
const selected = (this.fsb?.stage === stage.pk);
const selected = (this.instance?.stage === stage.pk);
return html`<option ?selected=${selected} value=${ifDefined(stage.pk)}>${stage.name}</option>`;
})}
</optgroup>`;
@ -54,8 +57,8 @@ export class StageBindingForm extends Form<FlowStageBinding> {
}
getOrder(): Promise<number> {
if (this.fsb) {
return Promise.resolve(this.fsb.order);
if (this.instance) {
return Promise.resolve(this.instance.order);
}
return new FlowsApi(DEFAULT_CONFIG).flowsBindingsList({
target: this.targetPk || "",
@ -69,9 +72,9 @@ export class StageBindingForm extends Form<FlowStageBinding> {
}
renderTarget(): TemplateResult {
if (this.fsb?.target || this.targetPk) {
if (this.instance?.target || this.targetPk) {
return html`
<input required name="target" type="hidden" value=${ifDefined(this.fsb?.target || this.targetPk)}>
<input required name="target" type="hidden" value=${ifDefined(this.instance?.target || this.targetPk)}>
`;
}
return html`<ak-form-element-horizontal
@ -114,7 +117,7 @@ export class StageBindingForm extends Form<FlowStageBinding> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="evaluateOnPlan">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.fsb?.evaluateOnPlan, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.evaluateOnPlan, true)}>
<label class="pf-c-check__label">
${t`Evaluate on plan`}
</label>
@ -125,7 +128,7 @@ export class StageBindingForm extends Form<FlowStageBinding> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="reEvaluatePolicies">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.fsb?.reEvaluatePolicies, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.reEvaluatePolicies, false)}>
<label class="pf-c-check__label">
${t`Re-evaluate policies`}
</label>
@ -137,10 +140,10 @@ export class StageBindingForm extends Form<FlowStageBinding> {
?required=${true}
name="policyEngineMode">
<select class="pf-c-form-control">
<option value=${FlowStageBindingPolicyEngineModeEnum.Any} ?selected=${this.fsb?.policyEngineMode === FlowStageBindingPolicyEngineModeEnum.Any}>
<option value=${FlowStageBindingPolicyEngineModeEnum.Any} ?selected=${this.instance?.policyEngineMode === FlowStageBindingPolicyEngineModeEnum.Any}>
${t`ANY, any policy must match to include this stage access.`}
</option>
<option value=${FlowStageBindingPolicyEngineModeEnum.All} ?selected=${this.fsb?.policyEngineMode === FlowStageBindingPolicyEngineModeEnum.All}>
<option value=${FlowStageBindingPolicyEngineModeEnum.All} ?selected=${this.instance?.policyEngineMode === FlowStageBindingPolicyEngineModeEnum.All}>
${t`ALL, all policies must match to include this stage access.`}
</option>
</select>

View File

@ -1,9 +1,8 @@
import { CoreApi, Group, User } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
@ -13,15 +12,19 @@ import "../../elements/chips/Chip";
import "./MemberSelectModal";
import YAML from "yaml";
import { first } from "../../utils";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-group-form")
export class GroupForm extends Form<Group> {
export class GroupForm extends ModelForm<Group, string> {
@property({attribute: false})
group?: Group;
loadInstance(pk: string): Promise<Group> {
return new CoreApi(DEFAULT_CONFIG).coreGroupsRead({
groupUuid: pk
});
}
getSuccessMessage(): string {
if (this.group) {
if (this.instance) {
return t`Successfully updated group.`;
} else {
return t`Successfully created group.`;
@ -29,13 +32,13 @@ export class GroupForm extends Form<Group> {
}
send = (data: Group): Promise<Group> => {
if (this.group?.pk) {
if (this.instance?.pk) {
return new CoreApi(DEFAULT_CONFIG).coreGroupsUpdate({
groupUuid: this.group.pk || "",
groupUuid: this.instance.pk || "",
data: data
});
} else {
data.users = Array.from(this.group?.users || []) as unknown as Set<number>;
data.users = Array.from(this.instance?.users || []) as unknown as Set<number>;
return new CoreApi(DEFAULT_CONFIG).coreGroupsCreate({
data: data
});
@ -48,11 +51,11 @@ export class GroupForm extends Form<Group> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.group?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="isSuperuser">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.group?.isSuperuser, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.isSuperuser, false)}>
<label class="pf-c-check__label">
${t`Is superuser`}
</label>
@ -63,10 +66,10 @@ export class GroupForm extends Form<Group> {
label=${t`Parent`}
name="parent">
<select class="pf-c-form-control">
<option value="" ?selected=${this.group?.parent === undefined}>---------</option>
<option value="" ?selected=${this.instance?.parent === undefined}>---------</option>
${until(new CoreApi(DEFAULT_CONFIG).coreGroupsList({}).then(groups => {
return groups.results.map(group => {
return html`<option value=${ifDefined(group.pk)} ?selected=${this.group?.parent === group.pk}>${group.name}</option>`;
return html`<option value=${ifDefined(group.pk)} ?selected=${this.instance?.parent === group.pk}>${group.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -79,8 +82,8 @@ export class GroupForm extends Form<Group> {
.confirm=${(items: User[]) => {
// Because the model only has the IDs, map the user list to IDs
const ids = items.map(u => u.pk || 0);
if (!this.group) this.group = {} as Group;
this.group.users = new Set(Array.from(this.group?.users || []).concat(ids));
if (!this.instance) this.instance = {} as Group;
this.instance.users = new Set(Array.from(this.instance?.users || []).concat(ids));
this.requestUpdate();
return Promise.resolve();
}}>
@ -94,7 +97,7 @@ export class GroupForm extends Form<Group> {
ordering: "username",
}).then(users => {
return users.results.map(user => {
const selected = Array.from(this.group?.users || []).some(su => {
const selected = Array.from(this.instance?.users || []).some(su => {
return su == user.pk;
});
if (!selected) return;
@ -102,11 +105,11 @@ export class GroupForm extends Form<Group> {
.removable=${true}
value=${ifDefined(user.pk)}
@remove=${() => {
if (!this.group) return;
const users = Array.from(this.group?.users || []);
if (!this.instance) return;
const users = Array.from(this.instance?.users || []);
const idx = users.indexOf(user.pk || 0);
users.splice(idx, 1);
this.group.users = new Set(users);
this.instance.users = new Set(users);
this.requestUpdate();
}}>
${user.username}
@ -122,7 +125,7 @@ export class GroupForm extends Form<Group> {
label=${t`Attributes`}
?required=${true}
name="attributes">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.group?.attributes, {}))}">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.instance?.attributes, {}))}">
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Set custom attributes using YAML or JSON.`}</p>
</ak-form-element-horizontal>

View File

@ -63,7 +63,7 @@ export class GroupListPage extends TablePage<Group> {
<span slot="header">
${t`Update Group`}
</span>
<ak-group-form slot="form" .group=${item}>
<ak-group-form slot="form" .instancePk=${item.pk}>
</ak-group-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -1,23 +1,26 @@
import { Outpost, OutpostsApi, OutpostTypeEnum, ProvidersApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/CodeMirror";
import YAML from "yaml";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-outpost-form")
export class OutpostForm extends Form<Outpost> {
export class OutpostForm extends ModelForm<Outpost, string> {
@property({attribute: false})
outpost?: Outpost;
loadInstance(pk: string): Promise<Outpost> {
return new OutpostsApi(DEFAULT_CONFIG).outpostsInstancesRead({
uuid: pk
});
}
getSuccessMessage(): string {
if (this.outpost) {
if (this.instance) {
return t`Successfully updated outpost.`;
} else {
return t`Successfully created outpost.`;
@ -25,9 +28,9 @@ export class OutpostForm extends Form<Outpost> {
}
send = (data: Outpost): Promise<Outpost> => {
if (this.outpost) {
if (this.instance) {
return new OutpostsApi(DEFAULT_CONFIG).outpostsOutpostsUpdate({
uuid: this.outpost.pk || "",
uuid: this.instance.pk || "",
data: data
});
} else {
@ -43,27 +46,27 @@ export class OutpostForm extends Form<Outpost> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.outpost?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Type`}
?required=${true}
name="type">
<select class="pf-c-form-control">
<option value=${OutpostTypeEnum.Proxy} ?selected=${this.outpost?.type === OutpostTypeEnum.Proxy}>${t`Proxy`}</option>
<option value=${OutpostTypeEnum.Ldap} ?selected=${this.outpost?.type === OutpostTypeEnum.Ldap}>${t`LDAP (Technical preview)`}</option>
<option value=${OutpostTypeEnum.Proxy} ?selected=${this.instance?.type === OutpostTypeEnum.Proxy}>${t`Proxy`}</option>
<option value=${OutpostTypeEnum.Ldap} ?selected=${this.instance?.type === OutpostTypeEnum.Ldap}>${t`LDAP (Technical preview)`}</option>
</select>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Service connection`}
name="serviceConnection">
<select class="pf-c-form-control">
<option value="" ?selected=${this.outpost?.serviceConnection === undefined}>---------</option>
<option value="" ?selected=${this.instance?.serviceConnection === undefined}>---------</option>
${until(new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsAllList({
ordering: "pk"
}).then(scs => {
return scs.results.map(sc => {
return html`<option value=${ifDefined(sc.pk)} ?selected=${this.outpost?.serviceConnection === sc.pk}>
return html`<option value=${ifDefined(sc.pk)} ?selected=${this.instance?.serviceConnection === sc.pk}>
${sc.name} (${sc.verboseName})
</option>`;
});
@ -83,7 +86,7 @@ export class OutpostForm extends Form<Outpost> {
ordering: "pk"
}).then(providers => {
return providers.results.map(provider => {
const selected = Array.from(this.outpost?.providers || []).some(sp => {
const selected = Array.from(this.instance?.providers || []).some(sp => {
return sp == provider.pk;
});
return html`<option value=${ifDefined(provider.pk)} ?selected=${selected}>${provider.verboseName} ${provider.name}</option>`;
@ -93,7 +96,7 @@ export class OutpostForm extends Form<Outpost> {
ordering: "pk"
}).then(providers => {
return providers.results.map(provider => {
const selected = Array.from(this.outpost?.providers || []).some(sp => {
const selected = Array.from(this.instance?.providers || []).some(sp => {
return sp == provider.pk;
});
return html`<option value=${ifDefined(provider.pk)} ?selected=${selected}>${provider.verboseName} ${provider.name}</option>`;
@ -107,8 +110,8 @@ export class OutpostForm extends Form<Outpost> {
name="config">
<ak-codemirror mode="yaml" value="${until(new OutpostsApi(DEFAULT_CONFIG).outpostsOutpostsDefaultSettings({}).then(config => {
let fc = config.config;
if (this.outpost) {
fc = this.outpost.config;
if (this.instance) {
fc = this.instance.config;
}
return YAML.stringify(fc);
}))}"></ak-codemirror>

View File

@ -66,7 +66,7 @@ export class OutpostListPage extends TablePage<Outpost> {
<span slot="header">
${t`Update Outpost`}
</span>
<ak-outpost-form slot="form" .outpost=${item}>
<ak-outpost-form slot="form" .instancePk=${item.pk}>
</ak-outpost-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -1,30 +1,25 @@
import { CryptoApi, DockerServiceConnection, OutpostsApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import { first } from "../../utils";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-service-connection-docker-form")
export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnection, string> {
set scUUID(value: string) {
new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsDockerRead({
uuid: value,
}).then(sc => {
this.sc = sc;
loadInstance(pk: string): Promise<DockerServiceConnection> {
return new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsDockerRead({
uuid: pk,
});
}
@property({attribute: false})
sc?: DockerServiceConnection;
getSuccessMessage(): string {
if (this.sc) {
if (this.instance) {
return t`Successfully updated service-connection.`;
} else {
return t`Successfully created service-connection.`;
@ -32,9 +27,9 @@ export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
}
send = (data: DockerServiceConnection): Promise<DockerServiceConnection> => {
if (this.sc) {
if (this.instance) {
return new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsDockerUpdate({
uuid: this.sc.pk || "",
uuid: this.instance.pk || "",
data: data
});
} else {
@ -50,11 +45,11 @@ export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.sc?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="local">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.sc?.local, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.local, false)}>
<label class="pf-c-check__label">
${t`Local`}
</label>
@ -65,19 +60,19 @@ export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
label=${t`Docker URL`}
?required=${true}
name="url">
<input type="text" value="${ifDefined(this.sc?.url)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.url)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Can be in the format of 'unix://' when connecting to a local docker daemon, or 'https://:2376' when connecting to a remote system.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`TLS Verification Certificate`}
name="tlsVerification">
<select class="pf-c-form-control">
<option value="" ?selected=${this.sc?.tlsVerification === undefined}>---------</option>
<option value="" ?selected=${this.instance?.tlsVerification === undefined}>---------</option>
${until(new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsList({
ordering: "pk"
}).then(certs => {
return certs.results.map(cert => {
return html`<option value=${ifDefined(cert.pk)} ?selected=${this.sc?.tlsVerification === cert.pk}>${cert.name}</option>`;
return html`<option value=${ifDefined(cert.pk)} ?selected=${this.instance?.tlsVerification === cert.pk}>${cert.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -87,12 +82,12 @@ export class ServiceConnectionDockerForm extends Form<DockerServiceConnection> {
label=${t`TLS Authentication Certificate`}
name="tlsAuthentication">
<select class="pf-c-form-control">
<option value="" ?selected=${this.sc?.tlsAuthentication === undefined}>---------</option>
<option value="" ?selected=${this.instance?.tlsAuthentication === undefined}>---------</option>
${until(new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsList({
ordering: "pk"
}).then(certs => {
return certs.results.map(cert => {
return html`<option value=${ifDefined(cert.pk)} ?selected=${this.sc?.tlsAuthentication === cert.pk}>${cert.name}</option>`;
return html`<option value=${ifDefined(cert.pk)} ?selected=${this.instance?.tlsAuthentication === cert.pk}>${cert.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>

View File

@ -1,31 +1,26 @@
import { KubernetesServiceConnection, OutpostsApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/CodeMirror";
import YAML from "yaml";
import { first } from "../../utils";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-service-connection-kubernetes-form")
export class ServiceConnectionKubernetesForm extends Form<KubernetesServiceConnection> {
export class ServiceConnectionKubernetesForm extends ModelForm<KubernetesServiceConnection, string> {
set scUUID(value: string) {
new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsKubernetesRead({
uuid: value,
}).then(sc => {
this.sc = sc;
loadInstance(pk: string): Promise<KubernetesServiceConnection> {
return new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsKubernetesRead({
uuid: pk,
});
}
@property({attribute: false})
sc?: KubernetesServiceConnection;
getSuccessMessage(): string {
if (this.sc) {
if (this.instance) {
return t`Successfully updated service-connection.`;
} else {
return t`Successfully created service-connection.`;
@ -33,9 +28,9 @@ export class ServiceConnectionKubernetesForm extends Form<KubernetesServiceConne
}
send = (data: KubernetesServiceConnection): Promise<KubernetesServiceConnection> => {
if (this.sc) {
if (this.instance) {
return new OutpostsApi(DEFAULT_CONFIG).outpostsServiceConnectionsKubernetesUpdate({
uuid: this.sc.pk || "",
uuid: this.instance.pk || "",
data: data
});
} else {
@ -51,11 +46,11 @@ export class ServiceConnectionKubernetesForm extends Form<KubernetesServiceConne
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.sc?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="local">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.sc?.local, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.local, false)}>
<label class="pf-c-check__label">
${t`Local`}
</label>
@ -65,7 +60,7 @@ export class ServiceConnectionKubernetesForm extends Form<KubernetesServiceConne
<ak-form-element-horizontal
label=${t`Kubeconfig`}
name="kubeconfig">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.sc?.kubeconfig, {}))}">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.instance?.kubeconfig, {}))}">
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Set custom attributes using YAML or JSON.`}</p>
</ak-form-element-horizontal>

View File

@ -82,7 +82,7 @@ export class OutpostServiceConnectionListPage extends TablePage<ServiceConnectio
<ak-proxy-form
slot="form"
.args=${{
"scUUID": item.pk
"instancePk": item.pk
}}
type=${ifDefined(item.component)}>
</ak-proxy-form>

View File

@ -88,7 +88,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
<span slot="header">
${t`Update Group`}
</span>
<ak-group-form slot="form" .group=${item.groupObj}>
<ak-group-form slot="form" .instancePk=${item.groupObj?.pk}>
</ak-group-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit Group`}
@ -102,7 +102,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
<span slot="header">
${t`Update User`}
</span>
<ak-user-form slot="form" .user=${item.userObj}>
<ak-user-form slot="form" .instancePk=${item.userObj?.pk}>
</ak-user-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit User`}
@ -128,7 +128,7 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
<span slot="header">
${t`Update Binding`}
</span>
<ak-policy-binding-form slot="form" .binding=${item} targetPk=${ifDefined(this.target)} ?policyOnly=${this.policyOnly}>
<ak-policy-binding-form slot="form" .instancePk=${item.pk} targetPk=${ifDefined(this.target)} ?policyOnly=${this.policyOnly}>
</ak-policy-binding-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit Binding`}

View File

@ -3,41 +3,38 @@ import { t } from "@lingui/macro";
import { css, CSSResult, customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import { first, groupBy } from "../../utils";
import "../../elements/forms/HorizontalFormElement";
import PFToggleGroup from "@patternfly/patternfly/components/ToggleGroup/toggle-group.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import { ModelForm } from "../../elements/forms/ModelForm";
enum target {
policy, group, user
}
@customElement("ak-policy-binding-form")
export class PolicyBindingForm extends Form<PolicyBinding> {
export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
@property({attribute: false})
set binding(value: PolicyBinding | undefined) {
this._binding = value;
if (value?.policyObj) {
loadInstance(pk: string): Promise<PolicyBinding> {
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsRead({
policyBindingUuid: pk
}).then(binding => {
if (binding?.policyObj) {
this.policyGroupUser = target.policy;
}
if (value?.groupObj) {
if (binding?.groupObj) {
this.policyGroupUser = target.group;
}
if (value?.userObj) {
if (binding?.userObj) {
this.policyGroupUser = target.user;
}
return binding;
});
}
get binding(): PolicyBinding | undefined {
return this._binding;
}
_binding?: PolicyBinding;
@property()
targetPk?: string;
@ -48,7 +45,7 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
policyOnly = false;
getSuccessMessage(): string {
if (this.binding) {
if (this.instance) {
return t`Successfully updated binding.`;
} else {
return t`Successfully created binding.`;
@ -64,9 +61,9 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
}
send = (data: PolicyBinding): Promise<PolicyBinding> => {
if (this.binding) {
if (this.instance) {
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsUpdate({
policyBindingUuid: this.binding.pk || "",
policyBindingUuid: this.instance.pk || "",
data: data
});
} else {
@ -81,7 +78,7 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
${groupBy<Policy>(policies, (p => p.verboseName || "")).map(([group, policies]) => {
return html`<optgroup label=${group}>
${policies.map(p => {
const selected = (this.binding?.policy === p.pk);
const selected = (this.instance?.policy === p.pk);
return html`<option ?selected=${selected} value=${ifDefined(p.pk)}>${p.name}</option>`;
})}
</optgroup>`;
@ -90,8 +87,8 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
}
getOrder(): Promise<number> {
if (this.binding) {
return Promise.resolve(this.binding.order);
if (this.instance) {
return Promise.resolve(this.instance.order);
}
return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsList({
target: this.targetPk || "",
@ -154,7 +151,7 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
name="policy"
?hidden=${this.policyGroupUser !== target.policy}>
<select class="pf-c-form-control">
<option value="" ?selected=${this.binding?.policy === undefined}>---------</option>
<option value="" ?selected=${this.instance?.policy === undefined}>---------</option>
${until(new PoliciesApi(DEFAULT_CONFIG).policiesAllList({
ordering: "pk"
}).then(policies => {
@ -167,12 +164,12 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
name="group"
?hidden=${this.policyGroupUser !== target.group}>
<select class="pf-c-form-control">
<option value="" ?selected=${this.binding?.group === undefined}>---------</option>
<option value="" ?selected=${this.instance?.group === undefined}>---------</option>
${until(new CoreApi(DEFAULT_CONFIG).coreGroupsList({
ordering: "pk"
}).then(groups => {
return groups.results.map(group => {
return html`<option value=${ifDefined(group.pk)} ?selected=${group.pk === this.binding?.group}>${group.name}</option>`;
return html`<option value=${ifDefined(group.pk)} ?selected=${group.pk === this.instance?.group}>${group.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -182,22 +179,22 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
name="user"
?hidden=${this.policyGroupUser !== target.user}>
<select class="pf-c-form-control">
<option value="" ?selected=${this.binding?.user === undefined}>---------</option>
<option value="" ?selected=${this.instance?.user === undefined}>---------</option>
${until(new CoreApi(DEFAULT_CONFIG).coreUsersList({
ordering: "pk"
}).then(users => {
return users.results.map(user => {
return html`<option value=${ifDefined(user.pk)} ?selected=${user.pk === this.binding?.user}>${user.name}</option>`;
return html`<option value=${ifDefined(user.pk)} ?selected=${user.pk === this.instance?.user}>${user.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
</ak-form-element-horizontal>
</div>
</div>
<input required name="target" type="hidden" value=${ifDefined(this.binding?.target || this.targetPk)}>
<input required name="target" type="hidden" value=${ifDefined(this.instance?.target || this.targetPk)}>
<ak-form-element-horizontal name="enabled">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.binding?.enabled, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.enabled, true)}>
<label class="pf-c-check__label">
${t`Enabled`}
</label>
@ -213,7 +210,7 @@ export class PolicyBindingForm extends Form<PolicyBinding> {
label=${t`Timeout`}
?required=${true}
name="timeout">
<input type="number" value="${first(this.binding?.timeout, 30)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.timeout, 30)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -82,7 +82,7 @@ export class PolicyListPage extends TablePage<Policy> {
<ak-proxy-form
slot="form"
.args=${{
"policyUUID": item.pk
"instancePk": item.pk
}}
type=${ifDefined(item.component)}>
</ak-proxy-form>

View File

@ -1,30 +1,25 @@
import { DummyPolicy, PoliciesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-policy-dummy-form")
export class DummyPolicyForm extends Form<DummyPolicy> {
export class DummyPolicyForm extends ModelForm<DummyPolicy, string> {
set policyUUID(value: string) {
new PoliciesApi(DEFAULT_CONFIG).policiesDummyRead({
policyUuid: value,
}).then(policy => {
this.policy = policy;
loadInstance(pk: string): Promise<DummyPolicy> {
return new PoliciesApi(DEFAULT_CONFIG).policiesDummyRead({
policyUuid: pk,
});
}
@property({attribute: false})
policy?: DummyPolicy;
getSuccessMessage(): string {
if (this.policy) {
if (this.instance) {
return t`Successfully updated policy.`;
} else {
return t`Successfully created policy.`;
@ -32,9 +27,9 @@ export class DummyPolicyForm extends Form<DummyPolicy> {
}
send = (data: DummyPolicy): Promise<DummyPolicy> => {
if (this.policy) {
if (this.instance) {
return new PoliciesApi(DEFAULT_CONFIG).policiesDummyUpdate({
policyUuid: this.policy.pk || "",
policyUuid: this.instance.pk || "",
data: data
});
} else {
@ -53,11 +48,11 @@ export class DummyPolicyForm extends Form<DummyPolicy> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.policy?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.executionLogging, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, false)}>
<label class="pf-c-check__label">
${t`Execution logging`}
</label>
@ -73,7 +68,7 @@ export class DummyPolicyForm extends Form<DummyPolicy> {
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="result">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.result, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.result, false)}>
<label class="pf-c-check__label">
${t`Pass policy?`}
</label>
@ -83,14 +78,14 @@ export class DummyPolicyForm extends Form<DummyPolicy> {
label=${t`Wait (min)`}
?required=${true}
name="waitMin">
<input type="number" value="${first(this.policy?.waitMin, 1)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.waitMin, 1)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`The policy takes a random time to execute. This controls the minimum time it will take.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Wait (max)`}
?required=${true}
name="waitMax">
<input type="number" value="${first(this.policy?.waitMax, 5)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.waitMax, 5)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</div>
</ak-form-group>

View File

@ -1,31 +1,26 @@
import { AdminApi, EventMatcherPolicy, EventsApi, PoliciesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { until } from "lit-html/directives/until";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-policy-event-matcher-form")
export class EventMatcherPolicyForm extends Form<EventMatcherPolicy> {
export class EventMatcherPolicyForm extends ModelForm<EventMatcherPolicy, string> {
set policyUUID(value: string) {
new PoliciesApi(DEFAULT_CONFIG).policiesEventMatcherRead({
policyUuid: value,
}).then(policy => {
this.policy = policy;
loadInstance(pk: string): Promise<EventMatcherPolicy> {
return new PoliciesApi(DEFAULT_CONFIG).policiesEventMatcherRead({
policyUuid: pk,
});
}
@property({attribute: false})
policy?: EventMatcherPolicy;
getSuccessMessage(): string {
if (this.policy) {
if (this.instance) {
return t`Successfully updated policy.`;
} else {
return t`Successfully created policy.`;
@ -33,9 +28,9 @@ export class EventMatcherPolicyForm extends Form<EventMatcherPolicy> {
}
send = (data: EventMatcherPolicy): Promise<EventMatcherPolicy> => {
if (this.policy) {
if (this.instance) {
return new PoliciesApi(DEFAULT_CONFIG).policiesEventMatcherUpdate({
policyUuid: this.policy.pk || "",
policyUuid: this.instance.pk || "",
data: data
});
} else {
@ -54,11 +49,11 @@ export class EventMatcherPolicyForm extends Form<EventMatcherPolicy> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.policy?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.executionLogging, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, false)}>
<label class="pf-c-check__label">
${t`Execution logging`}
</label>
@ -76,10 +71,10 @@ export class EventMatcherPolicyForm extends Form<EventMatcherPolicy> {
label=${t`Action`}
name="action">
<select class="pf-c-form-control">
<option value="" ?selected=${this.policy?.action === undefined}>---------</option>
<option value="" ?selected=${this.instance?.action === undefined}>---------</option>
${until(new EventsApi(DEFAULT_CONFIG).eventsEventsActions().then(actions => {
return actions.map(action => {
return html`<option value=${action.component} ?selected=${this.policy?.action === action.component}>${action.name}</option>`;
return html`<option value=${action.component} ?selected=${this.instance?.action === action.component}>${action.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -88,17 +83,17 @@ export class EventMatcherPolicyForm extends Form<EventMatcherPolicy> {
<ak-form-element-horizontal
label=${t`Client IP`}
name="clientIp">
<input type="text" value="${ifDefined(this.policy?.clientIp || "")}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.clientIp || "")}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`Matches Event's Client IP (strict matching, for network matching use an Expression Policy.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`App`}
name="app">
<select class="pf-c-form-control">
<option value="" ?selected=${this.policy?.app === undefined}>---------</option>
<option value="" ?selected=${this.instance?.app === undefined}>---------</option>
${until(new AdminApi(DEFAULT_CONFIG).adminAppsList().then(apps => {
return apps.map(app => {
return html`<option value=${app.name} ?selected=${this.policy?.app === app.name}>${app.label}</option>`;
return html`<option value=${app.name} ?selected=${this.instance?.app === app.name}>${app.label}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>

View File

@ -1,30 +1,25 @@
import { PasswordExpiryPolicy, PoliciesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-policy-password-expiry-form")
export class PasswordExpiryPolicyForm extends Form<PasswordExpiryPolicy> {
export class PasswordExpiryPolicyForm extends ModelForm<PasswordExpiryPolicy, string> {
set policyUUID(value: string) {
new PoliciesApi(DEFAULT_CONFIG).policiesPasswordExpiryRead({
policyUuid: value,
}).then(policy => {
this.policy = policy;
loadInstance(pk: string): Promise<PasswordExpiryPolicy> {
return new PoliciesApi(DEFAULT_CONFIG).policiesPasswordExpiryRead({
policyUuid: pk,
});
}
@property({attribute: false})
policy?: PasswordExpiryPolicy;
getSuccessMessage(): string {
if (this.policy) {
if (this.instance) {
return t`Successfully updated policy.`;
} else {
return t`Successfully created policy.`;
@ -32,9 +27,9 @@ export class PasswordExpiryPolicyForm extends Form<PasswordExpiryPolicy> {
}
send = (data: PasswordExpiryPolicy): Promise<PasswordExpiryPolicy> => {
if (this.policy) {
if (this.instance) {
return new PoliciesApi(DEFAULT_CONFIG).policiesPasswordExpiryUpdate({
policyUuid: this.policy.pk || "",
policyUuid: this.instance.pk || "",
data: data
});
} else {
@ -53,11 +48,11 @@ export class PasswordExpiryPolicyForm extends Form<PasswordExpiryPolicy> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.policy?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.executionLogging, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, false)}>
<label class="pf-c-check__label">
${t`Execution logging`}
</label>
@ -75,11 +70,11 @@ export class PasswordExpiryPolicyForm extends Form<PasswordExpiryPolicy> {
label=${t`Maximum age (in days)`}
?required=${true}
name="days">
<input type="number" value="${ifDefined(this.policy?.days || "")}" class="pf-c-form-control" required>
<input type="number" value="${ifDefined(this.instance?.days || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="denyOnly">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.denyOnly, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.denyOnly, false)}>
<label class="pf-c-check__label">
${t`Only fail the policy, don't invalidate user's password.`}
</label>

View File

@ -1,31 +1,26 @@
import { ExpressionPolicy, PoliciesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import "../../../elements/CodeMirror";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-policy-expression-form")
export class ExpressionPolicyForm extends Form<ExpressionPolicy> {
export class ExpressionPolicyForm extends ModelForm<ExpressionPolicy, string> {
set policyUUID(value: string) {
new PoliciesApi(DEFAULT_CONFIG).policiesExpressionRead({
policyUuid: value,
}).then(policy => {
this.policy = policy;
loadInstance(pk: string): Promise<ExpressionPolicy> {
return new PoliciesApi(DEFAULT_CONFIG).policiesExpressionRead({
policyUuid: pk,
});
}
@property({attribute: false})
policy?: ExpressionPolicy;
getSuccessMessage(): string {
if (this.policy) {
if (this.instance) {
return t`Successfully updated policy.`;
} else {
return t`Successfully created policy.`;
@ -33,9 +28,9 @@ export class ExpressionPolicyForm extends Form<ExpressionPolicy> {
}
send = (data: ExpressionPolicy): Promise<ExpressionPolicy> => {
if (this.policy) {
if (this.instance) {
return new PoliciesApi(DEFAULT_CONFIG).policiesExpressionUpdate({
policyUuid: this.policy.pk || "",
policyUuid: this.instance.pk || "",
data: data
});
} else {
@ -54,11 +49,11 @@ export class ExpressionPolicyForm extends Form<ExpressionPolicy> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.policy?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.executionLogging, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, false)}>
<label class="pf-c-check__label">
${t`Execution logging`}
</label>
@ -76,7 +71,7 @@ export class ExpressionPolicyForm extends Form<ExpressionPolicy> {
label=${t`Expression`}
?required=${true}
name="expression">
<ak-codemirror mode="python" value="${ifDefined(this.policy?.expression)}">
<ak-codemirror mode="python" value="${ifDefined(this.instance?.expression)}">
</ak-codemirror>
<p class="pf-c-form__helper-text">
${t`Expression using Python.`}

View File

@ -1,30 +1,25 @@
import { HaveIBeenPwendPolicy, PoliciesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-policy-hibp-form")
export class HaveIBeenPwnedPolicyForm extends Form<HaveIBeenPwendPolicy> {
export class HaveIBeenPwnedPolicyForm extends ModelForm<HaveIBeenPwendPolicy, string> {
set policyUUID(value: string) {
new PoliciesApi(DEFAULT_CONFIG).policiesHaveibeenpwnedRead({
policyUuid: value,
}).then(policy => {
this.policy = policy;
loadInstance(pk: string): Promise<HaveIBeenPwendPolicy> {
return new PoliciesApi(DEFAULT_CONFIG).policiesHaveibeenpwnedRead({
policyUuid: pk,
});
}
@property({attribute: false})
policy?: HaveIBeenPwendPolicy;
getSuccessMessage(): string {
if (this.policy) {
if (this.instance) {
return t`Successfully updated policy.`;
} else {
return t`Successfully created policy.`;
@ -32,9 +27,9 @@ export class HaveIBeenPwnedPolicyForm extends Form<HaveIBeenPwendPolicy> {
}
send = (data: HaveIBeenPwendPolicy): Promise<HaveIBeenPwendPolicy> => {
if (this.policy) {
if (this.instance) {
return new PoliciesApi(DEFAULT_CONFIG).policiesHaveibeenpwnedUpdate({
policyUuid: this.policy.pk || "",
policyUuid: this.instance.pk || "",
data: data
});
} else {
@ -54,11 +49,11 @@ export class HaveIBeenPwnedPolicyForm extends Form<HaveIBeenPwendPolicy> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.policy?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.executionLogging, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, false)}>
<label class="pf-c-check__label">
${t`Execution logging`}
</label>
@ -76,14 +71,14 @@ export class HaveIBeenPwnedPolicyForm extends Form<HaveIBeenPwendPolicy> {
label=${t`Password field`}
?required=${true}
name="passwordField">
<input type="text" value="${ifDefined(this.policy?.passwordField || "password")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.passwordField || "password")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Field key to check, field keys defined in Prompt stages are available.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Allowed count`}
?required=${true}
name="allowedCount">
<input type="number" value="${first(this.policy?.allowedCount, 0)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.allowedCount, 0)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Allow up to N occurrences in the HIBP database.`}</p>
</ak-form-element-horizontal>
</div>

View File

@ -1,30 +1,25 @@
import { PasswordPolicy, PoliciesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-policy-password-form")
export class PasswordPolicyForm extends Form<PasswordPolicy> {
export class PasswordPolicyForm extends ModelForm<PasswordPolicy, string> {
set policyUUID(value: string) {
new PoliciesApi(DEFAULT_CONFIG).policiesPasswordRead({
policyUuid: value,
}).then(policy => {
this.policy = policy;
loadInstance(pk: string): Promise<PasswordPolicy> {
return new PoliciesApi(DEFAULT_CONFIG).policiesPasswordRead({
policyUuid: pk,
});
}
@property({attribute: false})
policy?: PasswordPolicy;
getSuccessMessage(): string {
if (this.policy) {
if (this.instance) {
return t`Successfully updated policy.`;
} else {
return t`Successfully created policy.`;
@ -32,9 +27,9 @@ export class PasswordPolicyForm extends Form<PasswordPolicy> {
}
send = (data: PasswordPolicy): Promise<PasswordPolicy> => {
if (this.policy) {
if (this.instance) {
return new PoliciesApi(DEFAULT_CONFIG).policiesPasswordUpdate({
policyUuid: this.policy.pk || "",
policyUuid: this.instance.pk || "",
data: data
});
} else {
@ -53,11 +48,11 @@ export class PasswordPolicyForm extends Form<PasswordPolicy> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.policy?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.executionLogging, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, false)}>
<label class="pf-c-check__label">
${t`Execution logging`}
</label>
@ -75,7 +70,7 @@ export class PasswordPolicyForm extends Form<PasswordPolicy> {
label=${t`Password field`}
?required=${true}
name="passwordField">
<input type="text" value="${ifDefined(this.policy?.passwordField || "password")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.passwordField || "password")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Field key to check, field keys defined in Prompt stages are available.`}</p>
</ak-form-element-horizontal>
@ -83,31 +78,31 @@ export class PasswordPolicyForm extends Form<PasswordPolicy> {
label=${t`Minimum length`}
?required=${true}
name="lengthMin">
<input type="number" value="${first(this.policy?.lengthMin, 10)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.lengthMin, 10)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Minimum amount of Uppercase Characters`}
?required=${true}
name="amountUppercase">
<input type="number" value="${first(this.policy?.amountUppercase, 2)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.amountUppercase, 2)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Minimum amount of Lowercase Characters`}
?required=${true}
name="amountLowercase">
<input type="number" value="${first(this.policy?.amountLowercase, 2)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.amountLowercase, 2)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Minimum amount of Symbols Characters`}
?required=${true}
name="amountSymbols">
<input type="number" value="${first(this.policy?.amountSymbols, 2)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.amountSymbols, 2)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Error message`}
?required=${true}
name="errorMessage">
<input type="text" value="${ifDefined(this.policy?.errorMessage)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.errorMessage)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</div>
</ak-form-group>
@ -120,7 +115,7 @@ export class PasswordPolicyForm extends Form<PasswordPolicy> {
label=${t`Symbol charset`}
?required=${true}
name="symbolCharset">
<input type="text" value="${ifDefined(this.policy?.symbolCharset || "!\\\"#$%&'()*+,-./:;<=>?@[]^_`{|}~ ")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.symbolCharset || "!\\\"#$%&'()*+,-./:;<=>?@[]^_`{|}~ ")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Characters which are considered as symbols.`}</p>
</ak-form-element-horizontal>
</div>

View File

@ -1,30 +1,25 @@
import { ReputationPolicy, PoliciesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-policy-reputation-form")
export class ReputationPolicyForm extends Form<ReputationPolicy> {
export class ReputationPolicyForm extends ModelForm<ReputationPolicy, string> {
set policyUUID(value: string) {
new PoliciesApi(DEFAULT_CONFIG).policiesReputationRead({
policyUuid: value,
}).then(policy => {
this.policy = policy;
loadInstance(pk: string): Promise<ReputationPolicy> {
return new PoliciesApi(DEFAULT_CONFIG).policiesReputationRead({
policyUuid: pk,
});
}
@property({attribute: false})
policy?: ReputationPolicy;
getSuccessMessage(): string {
if (this.policy) {
if (this.instance) {
return t`Successfully updated policy.`;
} else {
return t`Successfully created policy.`;
@ -32,9 +27,9 @@ export class ReputationPolicyForm extends Form<ReputationPolicy> {
}
send = (data: ReputationPolicy): Promise<ReputationPolicy> => {
if (this.policy) {
if (this.instance) {
return new PoliciesApi(DEFAULT_CONFIG).policiesReputationUpdate({
policyUuid: this.policy.pk || "",
policyUuid: this.instance.pk || "",
data: data
});
} else {
@ -53,11 +48,11 @@ export class ReputationPolicyForm extends Form<ReputationPolicy> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.policy?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="executionLogging">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.executionLogging, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.executionLogging, false)}>
<label class="pf-c-check__label">
${t`Execution logging`}
</label>
@ -73,7 +68,7 @@ export class ReputationPolicyForm extends Form<ReputationPolicy> {
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="checkIp">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.checkIp, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.checkIp, false)}>
<label class="pf-c-check__label">
${t`Check IP`}
</label>
@ -81,7 +76,7 @@ export class ReputationPolicyForm extends Form<ReputationPolicy> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="checkUsername">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.policy?.checkUsername, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.checkUsername, false)}>
<label class="pf-c-check__label">
${t`Check Username`}
</label>
@ -91,7 +86,7 @@ export class ReputationPolicyForm extends Form<ReputationPolicy> {
label=${t`Threshold`}
?required=${true}
name="threshold">
<input type="number" value="${ifDefined(this.policy?.threshold || -5)}" class="pf-c-form-control" required>
<input type="number" value="${ifDefined(this.instance?.threshold || -5)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</div>
</ak-form-group>

View File

@ -1,29 +1,24 @@
import { LDAPPropertyMapping, PropertymappingsApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/CodeMirror";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-property-mapping-ldap-form")
export class PropertyMappingLDAPForm extends Form<LDAPPropertyMapping> {
export class PropertyMappingLDAPForm extends ModelForm<LDAPPropertyMapping, string> {
set mappingUUID(value: string) {
new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsLdapRead({
pmUuid: value,
}).then(mapping => {
this.mapping = mapping;
loadInstance(pk: string): Promise<LDAPPropertyMapping> {
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsLdapRead({
pmUuid: pk,
});
}
@property({attribute: false})
mapping?: LDAPPropertyMapping;
getSuccessMessage(): string {
if (this.mapping) {
if (this.instance) {
return t`Successfully updated mapping.`;
} else {
return t`Successfully created mapping.`;
@ -31,9 +26,9 @@ export class PropertyMappingLDAPForm extends Form<LDAPPropertyMapping> {
}
send = (data: LDAPPropertyMapping): Promise<LDAPPropertyMapping> => {
if (this.mapping) {
if (this.instance) {
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsLdapUpdate({
pmUuid: this.mapping.pk || "",
pmUuid: this.instance.pk || "",
data: data
});
} else {
@ -49,20 +44,20 @@ export class PropertyMappingLDAPForm extends Form<LDAPPropertyMapping> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.mapping?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Object field`}
?required=${true}
name="objectField">
<input type="text" value="${ifDefined(this.mapping?.objectField)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.objectField)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Field of the user object this value is written to.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Expression`}
?required=${true}
name="expression">
<ak-codemirror mode="python" value="${ifDefined(this.mapping?.expression)}">
<ak-codemirror mode="python" value="${ifDefined(this.instance?.expression)}">
</ak-codemirror>
<p class="pf-c-form__helper-text">
${t`Expression using Python.`}

View File

@ -1,29 +1,23 @@
import { SAMLPropertyMapping, PropertymappingsApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/CodeMirror";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-property-mapping-saml-form")
export class PropertyMappingLDAPForm extends Form<SAMLPropertyMapping> {
set mappingUUID(value: string) {
new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsSamlRead({
pmUuid: value,
}).then(mapping => {
this.mapping = mapping;
export class PropertyMappingLDAPForm extends ModelForm<SAMLPropertyMapping, string> {
loadInstance(pk: string): Promise<SAMLPropertyMapping> {
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsSamlRead({
pmUuid: pk,
});
}
@property({attribute: false})
mapping?: SAMLPropertyMapping;
getSuccessMessage(): string {
if (this.mapping) {
if (this.instance) {
return t`Successfully updated mapping.`;
} else {
return t`Successfully created mapping.`;
@ -31,9 +25,9 @@ export class PropertyMappingLDAPForm extends Form<SAMLPropertyMapping> {
}
send = (data: SAMLPropertyMapping): Promise<SAMLPropertyMapping> => {
if (this.mapping) {
if (this.instance) {
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsSamlUpdate({
pmUuid: this.mapping.pk || "",
pmUuid: this.instance.pk || "",
data: data
});
} else {
@ -49,13 +43,13 @@ export class PropertyMappingLDAPForm extends Form<SAMLPropertyMapping> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.mapping?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`SAML Attribute Name`}
?required=${true}
name="samlName">
<input type="text" value="${ifDefined(this.mapping?.samlName)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.samlName)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">
${t`Attribute name used for SAML Assertions. Can be a URN OID, a schema reference, or a any other string. If this property mapping is used for NameID Property, this field is discarded.`}
</p>
@ -63,7 +57,7 @@ export class PropertyMappingLDAPForm extends Form<SAMLPropertyMapping> {
<ak-form-element-horizontal
label=${t`Friendly Name`}
name="friendlyName">
<input type="text" value="${ifDefined(this.mapping?.friendlyName || "")}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.friendlyName || "")}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">
${t`Optionally set the 'FriendlyName' value of the Assertion attribute.`}
</p>
@ -72,7 +66,7 @@ export class PropertyMappingLDAPForm extends Form<SAMLPropertyMapping> {
label=${t`Expression`}
?required=${true}
name="expression">
<ak-codemirror mode="python" value="${ifDefined(this.mapping?.expression)}">
<ak-codemirror mode="python" value="${ifDefined(this.instance?.expression)}">
</ak-codemirror>
<p class="pf-c-form__helper-text">
${t`Expression using Python.`}

View File

@ -1,29 +1,24 @@
import { ScopeMapping, PropertymappingsApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { ModelForm } from "../../elements/forms/ModelForm";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/CodeMirror";
@customElement("ak-property-mapping-scope-form")
export class PropertyMappingScopeForm extends Form<ScopeMapping> {
export class PropertyMappingScopeForm extends ModelForm<ScopeMapping, string> {
set mappingUUID(value: string) {
new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsScopeRead({
pmUuid: value,
}).then(mapping => {
this.mapping = mapping;
loadInstance(pk: string): Promise<ScopeMapping> {
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsScopeRead({
pmUuid: pk,
});
}
@property({attribute: false})
mapping?: ScopeMapping;
getSuccessMessage(): string {
if (this.mapping) {
if (this.instance) {
return t`Successfully updated mapping.`;
} else {
return t`Successfully created mapping.`;
@ -31,9 +26,9 @@ export class PropertyMappingScopeForm extends Form<ScopeMapping> {
}
send = (data: ScopeMapping): Promise<ScopeMapping> => {
if (this.mapping) {
if (this.instance) {
return new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsScopeUpdate({
pmUuid: this.mapping.pk || "",
pmUuid: this.instance.pk || "",
data: data
});
} else {
@ -49,27 +44,27 @@ export class PropertyMappingScopeForm extends Form<ScopeMapping> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.mapping?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Scope name`}
?required=${true}
name="scopeName">
<input type="text" value="${ifDefined(this.mapping?.scopeName)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.scopeName)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Scope which the client can specify to access these properties.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Description`}
?required=${true}
name="description">
<input type="text" value="${ifDefined(this.mapping?.description)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.description)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Description shown to the user when consenting. If left empty, the user won't be informed.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Expression`}
?required=${true}
name="expression">
<ak-codemirror mode="python" value="${ifDefined(this.mapping?.expression)}">
<ak-codemirror mode="python" value="${ifDefined(this.instance?.expression)}">
</ak-codemirror>
<p class="pf-c-form__helper-text">
${t`Expression using Python.`}

View File

@ -79,7 +79,7 @@ export class ProviderListPage extends TablePage<Provider> {
<ak-proxy-form
slot="form"
.args=${{
"providerUUID": item.pk
"instancePk": item.pk
}}
type=${ifDefined(item.component)}>
</ak-proxy-form>

View File

@ -1,9 +1,9 @@
import { FlowDesignationEnum, FlowsApi, ProvidersApi, LDAPProvider, CoreApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ModelForm } from "../../../elements/forms/ModelForm";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
@ -11,21 +11,16 @@ import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
@customElement("ak-provider-ldap-form")
export class LDAPProviderFormPage extends Form<LDAPProvider> {
export class LDAPProviderFormPage extends ModelForm<LDAPProvider, number> {
set providerUUID(value: number) {
new ProvidersApi(DEFAULT_CONFIG).providersLdapRead({
id: value,
}).then(provider => {
this.provider = provider;
loadInstance(pk: number): Promise<LDAPProvider> {
return new ProvidersApi(DEFAULT_CONFIG).providersLdapRead({
id: pk,
});
}
@property({attribute: false})
provider?: LDAPProvider;
getSuccessMessage(): string {
if (this.provider) {
if (this.instance) {
return t`Successfully updated provider.`;
} else {
return t`Successfully created provider.`;
@ -33,9 +28,9 @@ export class LDAPProviderFormPage extends Form<LDAPProvider> {
}
send = (data: LDAPProvider): Promise<LDAPProvider> => {
if (this.provider) {
if (this.instance) {
return new ProvidersApi(DEFAULT_CONFIG).providersLdapUpdate({
id: this.provider.pk || 0,
id: this.instance.pk || 0,
data: data
});
} else {
@ -51,7 +46,7 @@ export class LDAPProviderFormPage extends Form<LDAPProvider> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.provider?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Bind flow`}
@ -63,7 +58,7 @@ export class LDAPProviderFormPage extends Form<LDAPProvider> {
designation: FlowDesignationEnum.Authentication,
}).then(flows => {
return flows.results.map(flow => {
return html`<option value=${ifDefined(flow.pk)} ?selected=${this.provider?.authorizationFlow === flow.pk}>${flow.name} (${flow.slug})</option>`;
return html`<option value=${ifDefined(flow.pk)} ?selected=${this.instance?.authorizationFlow === flow.pk}>${flow.name} (${flow.slug})</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -73,10 +68,10 @@ export class LDAPProviderFormPage extends Form<LDAPProvider> {
label=${t`Group`}
name="searchGroup">
<select class="pf-c-form-control">
<option value="" ?selected=${this.provider?.searchGroup === undefined}>---------</option>
<option value="" ?selected=${this.instance?.searchGroup === undefined}>---------</option>
${until(new CoreApi(DEFAULT_CONFIG).coreGroupsList({}).then(groups => {
return groups.results.map(group => {
return html`<option value=${ifDefined(group.pk)} ?selected=${this.provider?.searchGroup === group.pk}>${group.name}</option>`;
return html`<option value=${ifDefined(group.pk)} ?selected=${this.instance?.searchGroup === group.pk}>${group.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -92,7 +87,7 @@ export class LDAPProviderFormPage extends Form<LDAPProvider> {
label=${t`Base DN`}
?required=${true}
name="baseDn">
<input type="text" value="${first(this.provider?.baseDn, "DC=ldap,DC=goauthentik,DC=io")}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.baseDn, "DC=ldap,DC=goauthentik,DC=io")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`LDAP DN under which bind requests and search requests can be made.`}</p>
</ak-form-element-horizontal>
</div>

View File

@ -102,7 +102,7 @@ export class LDAPProviderViewPage extends LitElement {
</span>
<ak-provider-ldap-form
slot="form"
.providerUUID=${this.provider.pk || 0}>
.instancePk=${this.provider.pk || 0}>
</ak-provider-ldap-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${t`Edit`}

View File

@ -3,7 +3,7 @@ import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ModelForm } from "../../../elements/forms/ModelForm";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
@ -11,25 +11,22 @@ import "../../../elements/forms/FormGroup";
import { first, randomString } from "../../../utils";
@customElement("ak-provider-oauth2-form")
export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
export class OAuth2ProviderFormPage extends ModelForm<OAuth2Provider, number> {
set providerUUID(value: number) {
new ProvidersApi(DEFAULT_CONFIG).providersOauth2Read({
id: value,
loadInstance(pk: number): Promise<OAuth2Provider> {
return new ProvidersApi(DEFAULT_CONFIG).providersOauth2Read({
id: pk,
}).then(provider => {
this.provider = provider;
this.showClientSecret = provider.clientType === OAuth2ProviderClientTypeEnum.Confidential;
return provider;
});
}
@property({attribute: false})
provider?: OAuth2Provider;
@property({type: Boolean})
showClientSecret = true;
getSuccessMessage(): string {
if (this.provider) {
if (this.instance) {
return t`Successfully updated provider.`;
} else {
return t`Successfully created provider.`;
@ -37,9 +34,9 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
}
send = (data: OAuth2Provider): Promise<OAuth2Provider> => {
if (this.provider) {
if (this.instance) {
return new ProvidersApi(DEFAULT_CONFIG).providersOauth2Update({
id: this.provider.pk || 0,
id: this.instance.pk || 0,
data: data
});
} else {
@ -55,7 +52,7 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.provider?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Authorization flow`}
@ -67,7 +64,7 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
designation: FlowDesignationEnum.Authorization,
}).then(flows => {
return flows.results.map(flow => {
return html`<option value=${ifDefined(flow.pk)} ?selected=${this.provider?.authorizationFlow === flow.pk}>${flow.name} (${flow.slug})</option>`;
return html`<option value=${ifDefined(flow.pk)} ?selected=${this.instance?.authorizationFlow === flow.pk}>${flow.name} (${flow.slug})</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -91,10 +88,10 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
this.showClientSecret = true;
}
}}>
<option value=${OAuth2ProviderClientTypeEnum.Confidential} ?selected=${this.provider?.clientType === OAuth2ProviderClientTypeEnum.Confidential}>
<option value=${OAuth2ProviderClientTypeEnum.Confidential} ?selected=${this.instance?.clientType === OAuth2ProviderClientTypeEnum.Confidential}>
${t`Confidential`}
</option>
<option value=${OAuth2ProviderClientTypeEnum.Public} ?selected=${this.provider?.clientType === OAuth2ProviderClientTypeEnum.Public}>
<option value=${OAuth2ProviderClientTypeEnum.Public} ?selected=${this.instance?.clientType === OAuth2ProviderClientTypeEnum.Public}>
${t`Public`}
</option>
</select>
@ -104,19 +101,19 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
label=${t`Client ID`}
?required=${true}
name="clientId">
<input type="text" value="${first(this.provider?.clientId, randomString(40))}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.clientId, randomString(40))}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
?hidden=${!this.showClientSecret}
label=${t`Client Secret`}
name="clientSecret">
<input type="text" value="${first(this.provider?.clientSecret, randomString(128))}" class="pf-c-form-control">
<input type="text" value="${first(this.instance?.clientSecret, randomString(128))}" class="pf-c-form-control">
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Redirect URIs/Origins`}
?required=${true}
name="redirectUris">
<textarea class="pf-c-form-control" required>${this.provider?.redirectUris}</textarea>
<textarea class="pf-c-form-control" required>${this.instance?.redirectUris}</textarea>
<p class="pf-c-form__helper-text">
${t`Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows.`}
</p>
@ -133,7 +130,7 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
label=${t`Access code validity`}
?required=${true}
name="accessCodeValidity">
<input type="text" value="${first(this.provider?.accessCodeValidity, "minutes=1")}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.accessCodeValidity, "minutes=1")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Configure how long access codes are valid for.`}</p>
<p class="pf-c-form__helper-text">${t`(Format: hours=-1;minutes=-2;seconds=-3).`}</p>
</ak-form-element-horizontal>
@ -141,7 +138,7 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
label=${t`Token validity`}
?required=${true}
name="tokenValidity">
<input type="text" value="${first(this.provider?.tokenValidity, "minutes=10")}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.tokenValidity, "minutes=10")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Configure how long refresh tokens and their id_tokens are valid for.`}</p>
<p class="pf-c-form__helper-text">${t`(Format: hours=-1;minutes=-2;seconds=-3).`}</p>
</ak-form-element-horizontal>
@ -150,10 +147,10 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
?required=${true}
name="jwtAlg">
<select class="pf-c-form-control">
<option value=${OAuth2ProviderJwtAlgEnum.Rs256} ?selected=${this.provider?.jwtAlg === OAuth2ProviderJwtAlgEnum.Rs256}>
<option value=${OAuth2ProviderJwtAlgEnum.Rs256} ?selected=${this.instance?.jwtAlg === OAuth2ProviderJwtAlgEnum.Rs256}>
${t`RS256 (Asymmetric Encryption)`}
</option>
<option value=${OAuth2ProviderJwtAlgEnum.Hs256} ?selected=${this.provider?.jwtAlg === OAuth2ProviderJwtAlgEnum.Hs256}>
<option value=${OAuth2ProviderJwtAlgEnum.Hs256} ?selected=${this.instance?.jwtAlg === OAuth2ProviderJwtAlgEnum.Hs256}>
${t`HS256 (Symmetric Encryption)`}
</option>
</select>
@ -168,10 +165,10 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
}).then(scopes => {
return scopes.results.map(scope => {
let selected = false;
if (!this.provider?.propertyMappings) {
if (!this.instance?.propertyMappings) {
selected = scope.managed?.startsWith("goauthentik.io/providers/oauth2/scope-") || false;
} else {
selected = Array.from(this.provider?.propertyMappings).some(su => {
selected = Array.from(this.instance?.propertyMappings).some(su => {
return su == scope.pk;
});
}
@ -186,13 +183,13 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
label=${t`RSA Key`}
name="rsaKey">
<select class="pf-c-form-control">
<option value="" ?selected=${this.provider?.rsaKey === undefined}>---------</option>
<option value="" ?selected=${this.instance?.rsaKey === undefined}>---------</option>
${until(new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsList({
ordering: "pk",
hasKey: "true",
}).then(keys => {
return keys.results.map(key => {
let selected = this.provider?.rsaKey === key.pk;
let selected = this.instance?.rsaKey === key.pk;
if (keys.results.length === 1) {
selected = true;
}
@ -207,16 +204,16 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
?required=${true}
name="subMode">
<select class="pf-c-form-control">
<option value="${OAuth2ProviderSubModeEnum.HashedUserId}" ?selected=${this.provider?.subMode === OAuth2ProviderSubModeEnum.HashedUserId}>
<option value="${OAuth2ProviderSubModeEnum.HashedUserId}" ?selected=${this.instance?.subMode === OAuth2ProviderSubModeEnum.HashedUserId}>
${t`Based on the Hashed User ID`}
</option>
<option value="${OAuth2ProviderSubModeEnum.UserUsername}" ?selected=${this.provider?.subMode === OAuth2ProviderSubModeEnum.UserUsername}>
<option value="${OAuth2ProviderSubModeEnum.UserUsername}" ?selected=${this.instance?.subMode === OAuth2ProviderSubModeEnum.UserUsername}>
${t`Based on the username`}
</option>
<option value="${OAuth2ProviderSubModeEnum.UserEmail}" ?selected=${this.provider?.subMode === OAuth2ProviderSubModeEnum.UserEmail}>
<option value="${OAuth2ProviderSubModeEnum.UserEmail}" ?selected=${this.instance?.subMode === OAuth2ProviderSubModeEnum.UserEmail}>
${t`Based on the User's Email. This is recommended over the UPN method.`}
</option>
<option value="${OAuth2ProviderSubModeEnum.UserUpn}" ?selected=${this.provider?.subMode === OAuth2ProviderSubModeEnum.UserUpn}>
<option value="${OAuth2ProviderSubModeEnum.UserUpn}" ?selected=${this.instance?.subMode === OAuth2ProviderSubModeEnum.UserUpn}>
${t`Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains.`}
</option>
</select>
@ -226,7 +223,7 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="includeClaimsInIdToken">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.provider?.includeClaimsInIdToken, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.includeClaimsInIdToken, true)}>
<label class="pf-c-check__label">
${t`Include claims in id_token`}
</label>
@ -238,10 +235,10 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
?required=${true}
name="issuerMode">
<select class="pf-c-form-control">
<option value="${OAuth2ProviderIssuerModeEnum.PerProvider}" ?selected=${this.provider?.issuerMode === OAuth2ProviderIssuerModeEnum.PerProvider}>
<option value="${OAuth2ProviderIssuerModeEnum.PerProvider}" ?selected=${this.instance?.issuerMode === OAuth2ProviderIssuerModeEnum.PerProvider}>
${t`Each provider has a different issuer, based on the application slug.`}
</option>
<option value="${OAuth2ProviderIssuerModeEnum.Global}" ?selected=${this.provider?.issuerMode === OAuth2ProviderIssuerModeEnum.Global}>
<option value="${OAuth2ProviderIssuerModeEnum.Global}" ?selected=${this.instance?.issuerMode === OAuth2ProviderIssuerModeEnum.Global}>
${t`Same identifier is used for all providers`}
</option>
</select>

View File

@ -127,7 +127,7 @@ export class OAuth2ProviderViewPage extends LitElement {
</span>
<ak-provider-oauth2-form
slot="form"
.providerUUID=${this.provider.pk || 0}>
.instancePk=${this.provider.pk || 0}>
</ak-provider-oauth2-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${t`Edit`}

View File

@ -3,7 +3,7 @@ import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ModelForm } from "../../../elements/forms/ModelForm";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
@ -11,21 +11,18 @@ import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
@customElement("ak-provider-proxy-form")
export class ProxyProviderFormPage extends Form<ProxyProvider> {
export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
set providerUUID(value: number) {
new ProvidersApi(DEFAULT_CONFIG).providersProxyRead({
id: value,
loadInstance(pk: number): Promise<ProxyProvider> {
return new ProvidersApi(DEFAULT_CONFIG).providersProxyRead({
id: pk,
}).then(provider => {
this.provider = provider;
this.showHttpBasic = first(provider.basicAuthEnabled, true);
this.showInternalServer = first(!provider.forwardAuthMode, true);
return provider;
});
}
@property({attribute: false})
provider?: ProxyProvider;
@property({type: Boolean})
showHttpBasic = true;
@ -33,7 +30,7 @@ export class ProxyProviderFormPage extends Form<ProxyProvider> {
showInternalServer = true;
getSuccessMessage(): string {
if (this.provider) {
if (this.instance) {
return t`Successfully updated provider.`;
} else {
return t`Successfully created provider.`;
@ -41,9 +38,9 @@ export class ProxyProviderFormPage extends Form<ProxyProvider> {
}
send = (data: ProxyProvider): Promise<ProxyProvider> => {
if (this.provider) {
if (this.instance) {
return new ProvidersApi(DEFAULT_CONFIG).providersProxyUpdate({
id: this.provider.pk || 0,
id: this.instance.pk || 0,
data: data
});
} else {
@ -60,13 +57,13 @@ export class ProxyProviderFormPage extends Form<ProxyProvider> {
return html`<ak-form-element-horizontal
label=${t`HTTP-Basic Username Key`}
name="basicAuthUserAttribute">
<input type="text" value="${ifDefined(this.provider?.basicAuthUserAttribute)}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.basicAuthUserAttribute)}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`HTTP-Basic Password Key`}
name="basicAuthPasswordAttribute">
<input type="text" value="${ifDefined(this.provider?.basicAuthPasswordAttribute)}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.basicAuthPasswordAttribute)}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`User/Group Attribute used for the password part of the HTTP-Basic Header.`}</p>
</ak-form-element-horizontal>`;
}
@ -79,12 +76,12 @@ export class ProxyProviderFormPage extends Form<ProxyProvider> {
label=${t`Internal host`}
?required=${true}
name="internalHost">
<input type="text" value="${ifDefined(this.provider?.internalHost)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.internalHost)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Upstream host that the requests are forwarded to.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="internalHostSslValidation">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.provider?.internalHostSslValidation, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.internalHostSslValidation, true)}>
<label class="pf-c-check__label">
${t`Internal host SSL Validation`}
</label>
@ -99,7 +96,7 @@ export class ProxyProviderFormPage extends Form<ProxyProvider> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.provider?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Authorization flow`}
@ -111,7 +108,7 @@ export class ProxyProviderFormPage extends Form<ProxyProvider> {
designation: FlowDesignationEnum.Authorization,
}).then(flows => {
return flows.results.map(flow => {
return html`<option value=${ifDefined(flow.pk)} ?selected=${this.provider?.authorizationFlow === flow.pk}>${flow.name} (${flow.slug})</option>`;
return html`<option value=${ifDefined(flow.pk)} ?selected=${this.instance?.authorizationFlow === flow.pk}>${flow.name} (${flow.slug})</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -127,12 +124,12 @@ export class ProxyProviderFormPage extends Form<ProxyProvider> {
label=${t`External host`}
?required=${true}
name="externalHost">
<input type="text" value="${ifDefined(this.provider?.externalHost)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.externalHost)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`The external URL you'll access the outpost at.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="forwardAuthMode">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.provider?.forwardAuthMode, false)} @change=${(ev: Event) => {
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.forwardAuthMode, false)} @change=${(ev: Event) => {
const el = ev.target as HTMLInputElement;
this.showInternalServer = !el.checked;
}}>
@ -162,7 +159,7 @@ export class ProxyProviderFormPage extends Form<ProxyProvider> {
hasKey: "true",
}).then(keys => {
return keys.results.map(key => {
return html`<option value=${ifDefined(key.pk)} ?selected=${this.provider?.certificate === key.pk}>${key.name}</option>`;
return html`<option value=${ifDefined(key.pk)} ?selected=${this.instance?.certificate === key.pk}>${key.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -171,13 +168,13 @@ export class ProxyProviderFormPage extends Form<ProxyProvider> {
<ak-form-element-horizontal
label=${t`Skip path regex`}
name="skipPathRegex">
<textarea class="pf-c-form-control">${this.provider?.skipPathRegex}</textarea>
<textarea class="pf-c-form-control">${this.instance?.skipPathRegex}</textarea>
<p class="pf-c-form__helper-text">${t`Regular expressions for which authentication is not required. Each new line is interpreted as a new Regular Expression.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="basicAuthEnabled">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.provider?.basicAuthEnabled, false)} @change=${(ev: Event) => {
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.basicAuthEnabled, false)} @change=${(ev: Event) => {
const el = ev.target as HTMLInputElement;
this.showHttpBasic = el.checked;
}}>

View File

@ -127,7 +127,7 @@ export class ProxyProviderViewPage extends LitElement {
</span>
<ak-provider-proxy-form
slot="form"
.providerUUID=${this.provider.pk || 0}>
.instancePk=${this.provider.pk || 0}>
</ak-provider-proxy-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${t`Edit`}

View File

@ -1,30 +1,26 @@
import { CryptoApi, FlowDesignationEnum, FlowsApi, SAMLProvider, ProvidersApi, PropertymappingsApi, SAMLProviderSpBindingEnum, SAMLProviderDigestAlgorithmEnum, SAMLProviderSignatureAlgorithmEnum } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ModelForm } from "../../../elements/forms/ModelForm";
import { until } from "lit-html/directives/until";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
@customElement("ak-provider-saml-form")
export class SAMLProviderFormPage extends Form<SAMLProvider> {
export class SAMLProviderFormPage extends ModelForm<SAMLProvider, number> {
set providerUUID(value: number) {
new ProvidersApi(DEFAULT_CONFIG).providersSamlRead({
id: value,
}).then(provider => {
this.provider = provider;
loadInstance(pk: number): Promise<SAMLProvider> {
console.log("reading saml provider");
return new ProvidersApi(DEFAULT_CONFIG).providersSamlRead({
id: pk,
});
}
@property({attribute: false})
provider?: SAMLProvider;
getSuccessMessage(): string {
if (this.provider) {
if (this.instance) {
return t`Successfully updated provider.`;
} else {
return t`Successfully created provider.`;
@ -32,9 +28,9 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
}
send = (data: SAMLProvider): Promise<SAMLProvider> => {
if (this.provider) {
if (this.instance) {
return new ProvidersApi(DEFAULT_CONFIG).providersSamlUpdate({
id: this.provider.pk || 0,
id: this.instance.pk || 0,
data: data
});
} else {
@ -50,7 +46,7 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.provider?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Authorization flow`}
@ -62,7 +58,7 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
designation: FlowDesignationEnum.Authorization,
}).then(flows => {
return flows.results.map(flow => {
return html`<option value=${ifDefined(flow.pk)} ?selected=${this.provider?.authorizationFlow === flow.pk}>${flow.name} (${flow.slug})</option>`;
return html`<option value=${ifDefined(flow.pk)} ?selected=${this.instance?.authorizationFlow === flow.pk}>${flow.name} (${flow.slug})</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -78,23 +74,23 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
label=${t`ACS URL`}
?required=${true}
name="acsUrl">
<input type="text" value="${ifDefined(this.provider?.acsUrl)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.acsUrl)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Issuer`}
?required=${true}
name="issuer">
<input type="text" value="${this.provider?.issuer || "authentik"}" class="pf-c-form-control" required>
<input type="text" value="${this.instance?.issuer || "authentik"}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Service Provider Binding`}
?required=${true}
name="spBinding">
<select class="pf-c-form-control">
<option value=${SAMLProviderSpBindingEnum.Redirect} ?selected=${this.provider?.spBinding === SAMLProviderSpBindingEnum.Redirect}>
<option value=${SAMLProviderSpBindingEnum.Redirect} ?selected=${this.instance?.spBinding === SAMLProviderSpBindingEnum.Redirect}>
${t`Redirect`}
</option>
<option value=${SAMLProviderSpBindingEnum.Post} ?selected=${this.provider?.spBinding === SAMLProviderSpBindingEnum.Post}>
<option value=${SAMLProviderSpBindingEnum.Post} ?selected=${this.instance?.spBinding === SAMLProviderSpBindingEnum.Post}>
${t`Post`}
</option>
</select>
@ -103,7 +99,7 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
<ak-form-element-horizontal
label=${t`Audience`}
name="audience">
<input type="text" value="${ifDefined(this.provider?.audience)}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.audience)}" class="pf-c-form-control">
</ak-form-element-horizontal>
</div>
</ak-form-group>
@ -117,13 +113,13 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
label=${t`Signing Certificate`}
name="signingKp">
<select class="pf-c-form-control">
<option value="" ?selected=${this.provider?.signingKp === undefined}>---------</option>
<option value="" ?selected=${this.instance?.signingKp === undefined}>---------</option>
${until(new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsList({
ordering: "pk",
hasKey: "true",
}).then(keys => {
return keys.results.map(key => {
return html`<option value=${ifDefined(key.pk)} ?selected=${this.provider?.signingKp === key.pk}>${key.name}</option>`;
return html`<option value=${ifDefined(key.pk)} ?selected=${this.instance?.signingKp === key.pk}>${key.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -133,12 +129,12 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
label=${t`Verification Certificate`}
name="verificationKp">
<select class="pf-c-form-control">
<option value="" ?selected=${this.provider?.verificationKp === undefined}>---------</option>
<option value="" ?selected=${this.instance?.verificationKp === undefined}>---------</option>
${until(new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsList({
ordering: "pk",
}).then(keys => {
return keys.results.map(key => {
return html`<option value=${ifDefined(key.pk)} ?selected=${this.provider?.verificationKp === key.pk}>${key.name}</option>`;
return html`<option value=${ifDefined(key.pk)} ?selected=${this.instance?.verificationKp === key.pk}>${key.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -155,10 +151,10 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
}).then(mappings => {
return mappings.results.map(mapping => {
let selected = false;
if (!this.provider?.propertyMappings) {
if (!this.instance?.propertyMappings) {
selected = mapping.managed?.startsWith("goauthentik.io/providers/saml") || false;
} else {
selected = Array.from(this.provider?.propertyMappings).some(su => {
selected = Array.from(this.instance?.propertyMappings).some(su => {
return su == mapping.pk;
});
}
@ -172,12 +168,12 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
label=${t`NameID Property Mapping`}
name="nameIdMapping">
<select class="pf-c-form-control">
<option value="" ?selected=${this.provider?.nameIdMapping === undefined}>---------</option>
<option value="" ?selected=${this.instance?.nameIdMapping === undefined}>---------</option>
${until(new PropertymappingsApi(DEFAULT_CONFIG).propertymappingsSamlList({
ordering: "saml_name"
}).then(mappings => {
return mappings.results.map(mapping => {
return html`<option value=${ifDefined(mapping.pk)} ?selected=${this.provider?.nameIdMapping === mapping.pk}>${mapping.name}</option>`;
return html`<option value=${ifDefined(mapping.pk)} ?selected=${this.instance?.nameIdMapping === mapping.pk}>${mapping.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -188,7 +184,7 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
label=${t`Assertion valid not before`}
?required=${true}
name="assertionValidNotBefore">
<input type="text" value="${this.provider?.assertionValidNotBefore || "minutes=-5"}" class="pf-c-form-control" required>
<input type="text" value="${this.instance?.assertionValidNotBefore || "minutes=-5"}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Configure the maximum allowed time drift for an asseration.`}</p>
<p class="pf-c-form__helper-text">${t`(Format: hours=-1;minutes=-2;seconds=-3).`}</p>
</ak-form-element-horizontal>
@ -196,14 +192,14 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
label=${t`Assertion valid not on or after`}
?required=${true}
name="assertionValidNotOnOrAfter">
<input type="text" value="${this.provider?.assertionValidNotOnOrAfter || "minutes=5"}" class="pf-c-form-control" required>
<input type="text" value="${this.instance?.assertionValidNotOnOrAfter || "minutes=5"}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3).`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Session valid not on or after`}
?required=${true}
name="sessionValidNotOnOrAfter">
<input type="text" value="${this.provider?.sessionValidNotOnOrAfter || "minutes=86400"}" class="pf-c-form-control" required>
<input type="text" value="${this.instance?.sessionValidNotOnOrAfter || "minutes=86400"}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3).`}</p>
</ak-form-element-horizontal>
@ -212,16 +208,16 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
?required=${true}
name="digestAlgorithm">
<select class="pf-c-form-control">
<option value=${SAMLProviderDigestAlgorithmEnum._200009Xmldsigsha1} ?selected=${this.provider?.digestAlgorithm === SAMLProviderDigestAlgorithmEnum._200009Xmldsigsha1}>
<option value=${SAMLProviderDigestAlgorithmEnum._200009Xmldsigsha1} ?selected=${this.instance?.digestAlgorithm === SAMLProviderDigestAlgorithmEnum._200009Xmldsigsha1}>
${t`SHA1`}
</option>
<option value=${SAMLProviderDigestAlgorithmEnum._200104Xmlencsha256} ?selected=${this.provider?.digestAlgorithm === SAMLProviderDigestAlgorithmEnum._200104Xmlencsha256 || this.provider?.digestAlgorithm === undefined}>
<option value=${SAMLProviderDigestAlgorithmEnum._200104Xmlencsha256} ?selected=${this.instance?.digestAlgorithm === SAMLProviderDigestAlgorithmEnum._200104Xmlencsha256 || this.instance?.digestAlgorithm === undefined}>
${t`SHA256`}
</option>
<option value=${SAMLProviderDigestAlgorithmEnum._200104XmldsigMoresha384} ?selected=${this.provider?.digestAlgorithm === SAMLProviderDigestAlgorithmEnum._200104XmldsigMoresha384}>
<option value=${SAMLProviderDigestAlgorithmEnum._200104XmldsigMoresha384} ?selected=${this.instance?.digestAlgorithm === SAMLProviderDigestAlgorithmEnum._200104XmldsigMoresha384}>
${t`SHA384`}
</option>
<option value=${SAMLProviderDigestAlgorithmEnum._200104Xmlencsha512} ?selected=${this.provider?.digestAlgorithm === SAMLProviderDigestAlgorithmEnum._200104Xmlencsha512}>
<option value=${SAMLProviderDigestAlgorithmEnum._200104Xmlencsha512} ?selected=${this.instance?.digestAlgorithm === SAMLProviderDigestAlgorithmEnum._200104Xmlencsha512}>
${t`SHA512`}
</option>
</select>
@ -231,19 +227,19 @@ export class SAMLProviderFormPage extends Form<SAMLProvider> {
?required=${true}
name="signatureAlgorithm">
<select class="pf-c-form-control">
<option value=${SAMLProviderSignatureAlgorithmEnum._200009XmldsigrsaSha1} ?selected=${this.provider?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200009XmldsigrsaSha1}>
<option value=${SAMLProviderSignatureAlgorithmEnum._200009XmldsigrsaSha1} ?selected=${this.instance?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200009XmldsigrsaSha1}>
${t`RSA-SHA1`}
</option>
<option value=${SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha256} ?selected=${this.provider?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha256 || this.provider?.signatureAlgorithm === undefined}>
<option value=${SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha256} ?selected=${this.instance?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha256 || this.instance?.signatureAlgorithm === undefined}>
${t`RSA-SHA256`}
</option>
<option value=${SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha384} ?selected=${this.provider?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha384}>
<option value=${SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha384} ?selected=${this.instance?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha384}>
${t`RSA-SHA384`}
</option>
<option value=${SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha512} ?selected=${this.provider?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha512}>
<option value=${SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha512} ?selected=${this.instance?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200104XmldsigMorersaSha512}>
${t`RSA-SHA512`}
</option>
<option value=${SAMLProviderSignatureAlgorithmEnum._200009XmldsigdsaSha1} ?selected=${this.provider?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200009XmldsigdsaSha1}>
<option value=${SAMLProviderSignatureAlgorithmEnum._200009XmldsigdsaSha1} ?selected=${this.instance?.signatureAlgorithm === SAMLProviderSignatureAlgorithmEnum._200009XmldsigdsaSha1}>
${t`DSA-SHA1`}
</option>
</select>

View File

@ -121,7 +121,7 @@ export class SAMLProviderViewPage extends LitElement {
</span>
<ak-provider-saml-form
slot="form"
.providerUUID=${this.provider.pk || 0}>
.instancePk=${this.provider.pk || 0}>
</ak-provider-saml-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${t`Edit`}

View File

@ -75,7 +75,7 @@ export class SourceListPage extends TablePage<Source> {
<ak-proxy-form
slot="form"
.args=${{
"sourceSlug": item.slug
"instancePk": item.slug
}}
type=${ifDefined(item.component)}>
</ak-proxy-form>

View File

@ -1,31 +1,26 @@
import { LDAPSource, SourcesApi, PropertymappingsApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ifDefined } from "lit-html/directives/if-defined";
import { until } from "lit-html/directives/until";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-source-ldap-form")
export class LDAPSourceForm extends Form<LDAPSource> {
export class LDAPSourceForm extends ModelForm<LDAPSource, string> {
set sourceSlug(value: string) {
new SourcesApi(DEFAULT_CONFIG).sourcesLdapRead({
slug: value,
}).then(source => {
this.source = source;
loadInstance(pk: string): Promise<LDAPSource> {
return new SourcesApi(DEFAULT_CONFIG).sourcesLdapRead({
slug: pk,
});
}
@property({attribute: false})
source?: LDAPSource;
getSuccessMessage(): string {
if (this.source) {
if (this.instance) {
return t`Successfully updated source.`;
} else {
return t`Successfully created source.`;
@ -33,9 +28,9 @@ export class LDAPSourceForm extends Form<LDAPSource> {
}
send = (data: LDAPSource): Promise<LDAPSource> => {
if (this.source) {
if (this.instance) {
return new SourcesApi(DEFAULT_CONFIG).sourcesLdapPartialUpdate({
slug: this.source.slug,
slug: this.instance.slug,
data: data
});
} else {
@ -51,17 +46,17 @@ export class LDAPSourceForm extends Form<LDAPSource> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.source?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Slug`}
?required=${true}
name="slug">
<input type="text" value="${ifDefined(this.source?.slug)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.slug)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.enabled, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.enabled, true)}>
<label class="pf-c-check__label">
${t`Enabled`}
</label>
@ -69,7 +64,7 @@ export class LDAPSourceForm extends Form<LDAPSource> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="syncUsers">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.syncUsers, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.syncUsers, true)}>
<label class="pf-c-check__label">
${t`Sync users`}
</label>
@ -77,7 +72,7 @@ export class LDAPSourceForm extends Form<LDAPSource> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="syncUsersPassword">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.syncUsersPassword, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.syncUsersPassword, true)}>
<label class="pf-c-check__label">
${t`User password writeback`}
</label>
@ -86,7 +81,7 @@ export class LDAPSourceForm extends Form<LDAPSource> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="syncGroups">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.syncGroups, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.syncGroups, true)}>
<label class="pf-c-check__label">
${t`Sync groups`}
</label>
@ -101,11 +96,11 @@ export class LDAPSourceForm extends Form<LDAPSource> {
label=${t`Server URI`}
?required=${true}
name="serverUri">
<input type="text" value="${ifDefined(this.source?.serverUri)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.serverUri)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="startTls">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.startTls, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.startTls, true)}>
<label class="pf-c-check__label">
${t`Enable StartTLS`}
</label>
@ -115,20 +110,20 @@ export class LDAPSourceForm extends Form<LDAPSource> {
label=${t`Bind CN`}
?required=${true}
name="bindCn">
<input type="text" value="${ifDefined(this.source?.bindCn)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.bindCn)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Bind Password`}
?required=${true}
?writeOnly=${this.source !== undefined}
?writeOnly=${this.instance !== undefined}
name="bindPassword">
<input type="text" value="${ifDefined(this.source?.bindPassword)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.bindPassword)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Base DN`}
?required=${true}
name="baseDn">
<input type="text" value="${ifDefined(this.source?.baseDn)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.baseDn)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</div>
</ak-form-group>
@ -147,10 +142,10 @@ export class LDAPSourceForm extends Form<LDAPSource> {
}).then(mappings => {
return mappings.results.map(mapping => {
let selected = false;
if (!this.source?.propertyMappings) {
if (!this.instance?.propertyMappings) {
selected = mapping.managed?.startsWith("goauthentik.io/sources/ldap/default") || mapping.managed?.startsWith("goauthentik.io/sources/ldap/ms") || false;
} else {
selected = Array.from(this.source?.propertyMappings).some(su => {
selected = Array.from(this.instance?.propertyMappings).some(su => {
return su == mapping.pk;
});
}
@ -171,10 +166,10 @@ export class LDAPSourceForm extends Form<LDAPSource> {
}).then(mappings => {
return mappings.results.map(mapping => {
let selected = false;
if (!this.source?.propertyMappingsGroup) {
if (!this.instance?.propertyMappingsGroup) {
selected = mapping.managed === "goauthentik.io/sources/ldap/default-name";
} else {
selected = Array.from(this.source?.propertyMappingsGroup).some(su => {
selected = Array.from(this.instance?.propertyMappingsGroup).some(su => {
return su == mapping.pk;
});
}
@ -188,41 +183,41 @@ export class LDAPSourceForm extends Form<LDAPSource> {
<ak-form-element-horizontal
label=${t`Addition User DN`}
name="additionalUserDn">
<input type="text" value="${ifDefined(this.source?.additionalUserDn)}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.additionalUserDn)}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`Additional user DN, prepended to the Base DN.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Addition Group DN`}
name="additionalGroupDn">
<input type="text" value="${ifDefined(this.source?.additionalGroupDn)}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.additionalGroupDn)}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`Additional group DN, prepended to the Base DN.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`User object filter`}
?required=${true}
name="userObjectFilter">
<input type="text" value="${this.source?.userObjectFilter || "(objectClass=person)"}" class="pf-c-form-control" required>
<input type="text" value="${this.instance?.userObjectFilter || "(objectClass=person)"}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Consider Objects matching this filter to be Users.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Group object filter`}
?required=${true}
name="groupObjectFilter">
<input type="text" value="${this.source?.groupObjectFilter || "(objectClass=group)"}" class="pf-c-form-control" required>
<input type="text" value="${this.instance?.groupObjectFilter || "(objectClass=group)"}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Consider Objects matching this filter to be Groups.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Group membership field`}
?required=${true}
name="groupMembershipField">
<input type="text" value="${this.source?.groupMembershipField || "member"}" class="pf-c-form-control" required>
<input type="text" value="${this.instance?.groupMembershipField || "member"}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Field which contains members of a group.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Object uniqueness field`}
?required=${true}
name="objectUniquenessField">
<input type="text" value="${this.source?.objectUniquenessField || "objectSid"}" class="pf-c-form-control" required>
<input type="text" value="${this.instance?.objectUniquenessField || "objectSid"}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Field which contains a unique Identifier.`}</p>
</ak-form-element-horizontal>
</div>

View File

@ -103,7 +103,7 @@ export class LDAPSourceViewPage extends LitElement {
</span>
<ak-source-ldap-form
slot="form"
.sourceSlug=${this.source.slug}>
.instancePk=${this.source.slug}>
</ak-source-ldap-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${t`Edit`}

View File

@ -3,32 +3,29 @@ import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ifDefined } from "lit-html/directives/if-defined";
import { until } from "lit-html/directives/until";
import { first } from "../../../utils";
import { AppURLManager } from "../../../api/legacy";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-source-oauth-form")
export class OAuthSourceForm extends Form<OAuthSource> {
export class OAuthSourceForm extends ModelForm<OAuthSource, string> {
set sourceSlug(value: string) {
new SourcesApi(DEFAULT_CONFIG).sourcesOauthRead({
slug: value,
loadInstance(pk: string): Promise<OAuthSource> {
return new SourcesApi(DEFAULT_CONFIG).sourcesOauthRead({
slug: pk,
}).then(source => {
this.source = source;
this.showUrlOptions = first(source.type?.urlsCustomizable, false);
return source;
});
}
@property()
modelName?: string;
@property({attribute: false})
source?: OAuthSource;
@property({type: Boolean})
showUrlOptions = false;
@ -36,7 +33,7 @@ export class OAuthSourceForm extends Form<OAuthSource> {
showRequestTokenURL = false;
getSuccessMessage(): string {
if (this.source) {
if (this.instance) {
return t`Successfully updated source.`;
} else {
return t`Successfully created source.`;
@ -44,9 +41,9 @@ export class OAuthSourceForm extends Form<OAuthSource> {
}
send = (data: OAuthSource): Promise<OAuthSource> => {
if (this.source) {
return new SourcesApi(DEFAULT_CONFIG).sourcesOauthUpdate({
slug: this.source.slug,
if (this.instance) {
return new SourcesApi(DEFAULT_CONFIG).sourcesOauthPartialUpdate({
slug: this.instance.slug,
data: data
});
} else {
@ -70,27 +67,27 @@ export class OAuthSourceForm extends Form<OAuthSource> {
label=${t`Authorization URL`}
?required=${true}
name="authorizationUrl">
<input type="text" value="${first(this.source?.authorizationUrl, "")}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.authorizationUrl, "")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`URL the user is redirect to to consent the authorization.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Access token URL`}
?required=${true}
name="accessTokenUrl">
<input type="text" value="${first(this.source?.accessTokenUrl, "")}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.accessTokenUrl, "")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`URL used by authentik to retrieve tokens.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Profile URL`}
?required=${true}
name="profileUrl">
<input type="text" value="${first(this.source?.profileUrl, "")}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.profileUrl, "")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`URL used by authentik to get user information.`}</p>
</ak-form-element-horizontal>
${this.showRequestTokenURL ? html`<ak-form-element-horizontal
label=${t`Request token URL`}
name="requestTokenUrl">
<input type="text" value="${first(this.source?.requestTokenUrl, "")}" class="pf-c-form-control">
<input type="text" value="${first(this.instance?.requestTokenUrl, "")}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`URL used to request the initial token. This URL is only required for OAuth 1.`}</p>
</ak-form-element-horizontal>
` : html``}
@ -112,13 +109,13 @@ export class OAuthSourceForm extends Form<OAuthSource> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.source?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Slug`}
?required=${true}
name="slug">
<input type="text" value="${ifDefined(this.source?.slug)}" class="pf-c-form-control" required @input=${(ev: Event) => {
<input type="text" value="${ifDefined(this.instance?.slug)}" class="pf-c-form-control" required @input=${(ev: Event) => {
const current = (ev.target as HTMLInputElement).value;
const label = this.shadowRoot?.querySelector<HTMLSpanElement>("#callback-url");
if (!label) return;
@ -126,12 +123,12 @@ export class OAuthSourceForm extends Form<OAuthSource> {
}}>
<p class="pf-c-form__helper-text">
${t`Use this redirect URL:`}
<span id="callback-url">${this.getRedirectURI(this.source?.slug)}</span>
<span id="callback-url">${this.getRedirectURI(this.instance?.slug)}</span>
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.enabled, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.enabled, true)}>
<label class="pf-c-check__label">
${t`Enabled`}
</label>
@ -142,19 +139,19 @@ export class OAuthSourceForm extends Form<OAuthSource> {
?required=${true}
name="userMatchingMode">
<select class="pf-c-form-control">
<option value=${OAuthSourceUserMatchingModeEnum.Identifier} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.Identifier}>
<option value=${OAuthSourceUserMatchingModeEnum.Identifier} ?selected=${this.instance?.userMatchingMode === OAuthSourceUserMatchingModeEnum.Identifier}>
${t`Link users on unique identifier`}
</option>
<option value=${OAuthSourceUserMatchingModeEnum.UsernameLink} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.UsernameLink}>
<option value=${OAuthSourceUserMatchingModeEnum.UsernameLink} ?selected=${this.instance?.userMatchingMode === OAuthSourceUserMatchingModeEnum.UsernameLink}>
${t`Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses`}
</option>
<option value=${OAuthSourceUserMatchingModeEnum.UsernameDeny} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.UsernameDeny}>
<option value=${OAuthSourceUserMatchingModeEnum.UsernameDeny} ?selected=${this.instance?.userMatchingMode === OAuthSourceUserMatchingModeEnum.UsernameDeny}>
${t`Use the user's email address, but deny enrollment when the email address already exists.`}
</option>
<option value=${OAuthSourceUserMatchingModeEnum.EmailLink} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.EmailLink}>
<option value=${OAuthSourceUserMatchingModeEnum.EmailLink} ?selected=${this.instance?.userMatchingMode === OAuthSourceUserMatchingModeEnum.EmailLink}>
${t`Link to a user with identical username address. Can have security implications when a username is used with another source.`}
</option>
<option value=${OAuthSourceUserMatchingModeEnum.EmailDeny} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.EmailDeny}>
<option value=${OAuthSourceUserMatchingModeEnum.EmailDeny} ?selected=${this.instance?.userMatchingMode === OAuthSourceUserMatchingModeEnum.EmailDeny}>
${t`Use the user's username, but deny enrollment when the username already exists.`}
</option>
</select>
@ -169,14 +166,14 @@ export class OAuthSourceForm extends Form<OAuthSource> {
label=${t`Consumer key`}
?required=${true}
name="consumerKey">
<input type="text" value="${ifDefined(this.source?.consumerKey)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.consumerKey)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Consumer secret`}
?required=${true}
?writeOnly=${this.source !== undefined}
?writeOnly=${this.instance !== undefined}
name="consumerSecret">
<input type="text" value="${ifDefined(this.source?.consumerSecret)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.consumerSecret)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Provider type`}
@ -194,15 +191,15 @@ export class OAuthSourceForm extends Form<OAuthSource> {
} else {
this.showRequestTokenURL = false;
}
if (!this.source) {
this.source = {} as OAuthSource;
if (!this.instance) {
this.instance = {} as OAuthSource;
}
this.source.providerType = selected.value;
this.instance.providerType = selected.value;
}}>
${until(new SourcesApi(DEFAULT_CONFIG).sourcesOauthSourceTypes().then(types => {
return types.map(type => {
let selected = this.source?.providerType === type.slug;
if (!this.source?.pk) {
let selected = this.instance?.providerType === type.slug;
if (!this.instance?.pk) {
if (this.modelName?.replace("oauthsource", "") === type.slug) {
selected = true;
}
@ -236,8 +233,8 @@ export class OAuthSourceForm extends Form<OAuthSource> {
designation: FlowDesignationEnum.Authentication,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.source?.authenticationFlow === flow.pk;
if (!this.source?.pk && !this.source?.authenticationFlow && flow.slug === "default-source-authentication") {
let selected = this.instance?.authenticationFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.authenticationFlow && flow.slug === "default-source-authentication") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;
@ -256,8 +253,8 @@ export class OAuthSourceForm extends Form<OAuthSource> {
designation: FlowDesignationEnum.Enrollment,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.source?.enrollmentFlow === flow.pk;
if (!this.source?.pk && !this.source?.enrollmentFlow && flow.slug === "default-source-enrollment") {
let selected = this.instance?.enrollmentFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.enrollmentFlow && flow.slug === "default-source-enrollment") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;

View File

@ -122,7 +122,7 @@ export class OAuthSourceViewPage extends LitElement {
</span>
<ak-source-oauth-form
slot="form"
.sourceSlug=${this.source.slug}>
.instancePk=${this.source.slug}>
</ak-source-oauth-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${t`Edit`}

View File

@ -3,41 +3,42 @@ import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ifDefined } from "lit-html/directives/if-defined";
import { until } from "lit-html/directives/until";
import { first, randomString } from "../../../utils";
import { PlexAPIClient, PlexResource, popupCenterScreen} from "../../../flows/sources/plex/API";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-source-plex-form")
export class PlexSourceForm extends Form<PlexSource> {
export class PlexSourceForm extends ModelForm<PlexSource, string> {
set sourceSlug(value: string) {
new SourcesApi(DEFAULT_CONFIG).sourcesPlexRead({
slug: value,
loadInstance(pk: string): Promise<PlexSource> {
return new SourcesApi(DEFAULT_CONFIG).sourcesPlexRead({
slug: pk,
}).then(source => {
this.source = source;
this.plexToken = source.plexToken;
this.loadServers();
return source;
});
}
@property({attribute: false})
source: PlexSource = {
clientId: randomString(40)
} as PlexSource;
@property()
plexToken?: string;
@property({attribute: false})
plexResources?: PlexResource[];
get defaultInstance(): PlexSource | undefined {
return {
clientId: randomString(40)
} as PlexSource;
}
getSuccessMessage(): string {
if (this.source) {
if (this.instance) {
return t`Successfully updated source.`;
} else {
return t`Successfully created source.`;
@ -46,9 +47,9 @@ export class PlexSourceForm extends Form<PlexSource> {
send = (data: PlexSource): Promise<PlexSource> => {
data.plexToken = this.plexToken;
if (this.source.slug) {
if (this.instance?.slug) {
return new SourcesApi(DEFAULT_CONFIG).sourcesPlexUpdate({
slug: this.source.slug,
slug: this.instance.slug,
data: data
});
} else {
@ -59,9 +60,9 @@ export class PlexSourceForm extends Form<PlexSource> {
};
async doAuth(): Promise<void> {
const authInfo = await PlexAPIClient.getPin(this.source?.clientId || "");
const authInfo = await PlexAPIClient.getPin(this.instance?.clientId || "");
const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
PlexAPIClient.pinPoll(this.source?.clientId || "", authInfo.pin.id).then(token => {
PlexAPIClient.pinPoll(this.instance?.clientId || "", authInfo.pin.id).then(token => {
authWindow?.close();
this.plexToken = token;
this.loadServers();
@ -81,17 +82,17 @@ export class PlexSourceForm extends Form<PlexSource> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.source?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Slug`}
?required=${true}
name="slug">
<input type="text" value="${ifDefined(this.source?.slug)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.slug)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.enabled, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.enabled, true)}>
<label class="pf-c-check__label">
${t`Enabled`}
</label>
@ -102,19 +103,19 @@ export class PlexSourceForm extends Form<PlexSource> {
?required=${true}
name="userMatchingMode">
<select class="pf-c-form-control">
<option value=${PlexSourceUserMatchingModeEnum.Identifier} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.Identifier}>
<option value=${PlexSourceUserMatchingModeEnum.Identifier} ?selected=${this.instance?.userMatchingMode === PlexSourceUserMatchingModeEnum.Identifier}>
${t`Link users on unique identifier`}
</option>
<option value=${PlexSourceUserMatchingModeEnum.UsernameLink} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.UsernameLink}>
<option value=${PlexSourceUserMatchingModeEnum.UsernameLink} ?selected=${this.instance?.userMatchingMode === PlexSourceUserMatchingModeEnum.UsernameLink}>
${t`Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses`}
</option>
<option value=${PlexSourceUserMatchingModeEnum.UsernameDeny} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.UsernameDeny}>
<option value=${PlexSourceUserMatchingModeEnum.UsernameDeny} ?selected=${this.instance?.userMatchingMode === PlexSourceUserMatchingModeEnum.UsernameDeny}>
${t`Use the user's email address, but deny enrollment when the email address already exists.`}
</option>
<option value=${PlexSourceUserMatchingModeEnum.EmailLink} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.EmailLink}>
<option value=${PlexSourceUserMatchingModeEnum.EmailLink} ?selected=${this.instance?.userMatchingMode === PlexSourceUserMatchingModeEnum.EmailLink}>
${t`Link to a user with identical username address. Can have security implications when a username is used with another source.`}
</option>
<option value=${PlexSourceUserMatchingModeEnum.EmailDeny} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.EmailDeny}>
<option value=${PlexSourceUserMatchingModeEnum.EmailDeny} ?selected=${this.instance?.userMatchingMode === PlexSourceUserMatchingModeEnum.EmailDeny}>
${t`Use the user's username, but deny enrollment when the username already exists.`}
</option>
</select>
@ -129,11 +130,11 @@ export class PlexSourceForm extends Form<PlexSource> {
label=${t`Client ID`}
?required=${true}
name="clientId">
<input type="text" value="${first(this.source?.clientId)}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.clientId)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="allowFriends">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.allowFriends, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.allowFriends, true)}>
<label class="pf-c-check__label">
${t`Allow friends to authenticate via Plex, even if you don't share any servers`}
</label>
@ -145,7 +146,7 @@ export class PlexSourceForm extends Form<PlexSource> {
name="allowedServers">
<select class="pf-c-form-control" multiple>
${this.plexResources?.map(r => {
const selected = Array.from(this.source?.allowedServers || []).some(server => {
const selected = Array.from(this.instance?.allowedServers || []).some(server => {
return server == r.clientIdentifier;
});
return html`<option value=${r.clientIdentifier} ?selected=${selected}>${r.name}</option>`;
@ -178,8 +179,8 @@ export class PlexSourceForm extends Form<PlexSource> {
designation: FlowDesignationEnum.Authentication,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.source?.authenticationFlow === flow.pk;
if (!this.source?.pk && !this.source?.authenticationFlow && flow.slug === "default-source-authentication") {
let selected = this.instance?.authenticationFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.authenticationFlow && flow.slug === "default-source-authentication") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;
@ -198,8 +199,8 @@ export class PlexSourceForm extends Form<PlexSource> {
designation: FlowDesignationEnum.Enrollment,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.source?.enrollmentFlow === flow.pk;
if (!this.source?.pk && !this.source?.enrollmentFlow && flow.slug === "default-source-enrollment") {
let selected = this.instance?.enrollmentFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.enrollmentFlow && flow.slug === "default-source-enrollment") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;

View File

@ -82,7 +82,7 @@ export class PlexSourceViewPage extends LitElement {
</span>
<ak-source-plex-form
slot="form"
.sourceSlug=${this.source.slug}>
.instancePk=${this.source.slug}>
</ak-source-plex-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${t`Edit`}

View File

@ -1,31 +1,26 @@
import { SAMLSource, SourcesApi, SAMLSourceBindingTypeEnum, SAMLSourceNameIdPolicyEnum, CryptoApi, SAMLSourceDigestAlgorithmEnum, SAMLSourceSignatureAlgorithmEnum, FlowsApi, FlowDesignationEnum } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ifDefined } from "lit-html/directives/if-defined";
import { until } from "lit-html/directives/until";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-source-saml-form")
export class SAMLSourceForm extends Form<SAMLSource> {
export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
set sourceSlug(value: string) {
new SourcesApi(DEFAULT_CONFIG).sourcesSamlRead({
slug: value,
}).then(source => {
this.source = source;
loadInstance(pk: string): Promise<SAMLSource> {
return new SourcesApi(DEFAULT_CONFIG).sourcesSamlRead({
slug: pk,
});
}
@property({attribute: false})
source?: SAMLSource;
getSuccessMessage(): string {
if (this.source) {
if (this.instance) {
return t`Successfully updated source.`;
} else {
return t`Successfully created source.`;
@ -33,9 +28,9 @@ export class SAMLSourceForm extends Form<SAMLSource> {
}
send = (data: SAMLSource): Promise<SAMLSource> => {
if (this.source) {
if (this.instance) {
return new SourcesApi(DEFAULT_CONFIG).sourcesSamlUpdate({
slug: this.source.slug,
slug: this.instance.slug,
data: data
});
} else {
@ -51,17 +46,17 @@ export class SAMLSourceForm extends Form<SAMLSource> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.source?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Slug`}
?required=${true}
name="slug">
<input type="text" value="${ifDefined(this.source?.slug)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.slug)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.enabled, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.enabled, true)}>
<label class="pf-c-check__label">
${t`Enabled`}
</label>
@ -77,19 +72,19 @@ export class SAMLSourceForm extends Form<SAMLSource> {
label=${t`SSO URL`}
?required=${true}
name="ssoUrl">
<input type="text" value="${ifDefined(this.source?.ssoUrl)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.ssoUrl)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`URL that the initial Login request is sent to.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`SLO URL`}
name="sloUrl">
<input type="text" value="${ifDefined(this.source?.sloUrl || "")}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.sloUrl || "")}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`Optional URL if the IDP supports Single-Logout.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Issuer`}
name="issuer">
<input type="text" value="${ifDefined(this.source?.issuer)}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.issuer)}" class="pf-c-form-control">
<p class="pf-c-form__helper-text">${t`Also known as Entity ID. Defaults the Metadata URL.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
@ -97,13 +92,13 @@ export class SAMLSourceForm extends Form<SAMLSource> {
?required=${true}
name="bindingType">
<select class="pf-c-form-control">
<option value=${SAMLSourceBindingTypeEnum.Redirect} ?selected=${this.source?.bindingType === SAMLSourceBindingTypeEnum.Redirect}>
<option value=${SAMLSourceBindingTypeEnum.Redirect} ?selected=${this.instance?.bindingType === SAMLSourceBindingTypeEnum.Redirect}>
${t`Redirect binding`}
</option>
<option value=${SAMLSourceBindingTypeEnum.PostAuto} ?selected=${this.source?.bindingType === SAMLSourceBindingTypeEnum.PostAuto}>
<option value=${SAMLSourceBindingTypeEnum.PostAuto} ?selected=${this.instance?.bindingType === SAMLSourceBindingTypeEnum.PostAuto}>
${t`Post binding (auto-submit)`}
</option>
<option value=${SAMLSourceBindingTypeEnum.Post} ?selected=${this.source?.bindingType === SAMLSourceBindingTypeEnum.Post}>
<option value=${SAMLSourceBindingTypeEnum.Post} ?selected=${this.instance?.bindingType === SAMLSourceBindingTypeEnum.Post}>
${t`Post binding`}
</option>
</select>
@ -112,12 +107,12 @@ export class SAMLSourceForm extends Form<SAMLSource> {
label=${t`Signing keypair`}
name="signingKp">
<select class="pf-c-form-control">
<option value="" ?selected=${this.source?.signingKp === undefined}>---------</option>
<option value="" ?selected=${this.instance?.signingKp === undefined}>---------</option>
${until(new CryptoApi(DEFAULT_CONFIG).cryptoCertificatekeypairsList({
ordering: "pk",
}).then(keys => {
return keys.results.map(key => {
return html`<option value=${ifDefined(key.pk)} ?selected=${this.source?.signingKp === key.pk}>${key.name}</option>`;
return html`<option value=${ifDefined(key.pk)} ?selected=${this.instance?.signingKp === key.pk}>${key.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
@ -132,7 +127,7 @@ export class SAMLSourceForm extends Form<SAMLSource> {
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="allowIdpInitiated">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.allowIdpInitiated, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.allowIdpInitiated, false)}>
<label class="pf-c-check__label">
${t` Allow IDP-initiated logins`}
</label>
@ -144,19 +139,19 @@ export class SAMLSourceForm extends Form<SAMLSource> {
?required=${true}
name="nameIdPolicy">
<select class="pf-c-form-control">
<option value=${SAMLSourceNameIdPolicyEnum._20nameidFormatpersistent} ?selected=${this.source?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._20nameidFormatpersistent}>
<option value=${SAMLSourceNameIdPolicyEnum._20nameidFormatpersistent} ?selected=${this.instance?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._20nameidFormatpersistent}>
${t`Persistent`}
</option>
<option value=${SAMLSourceNameIdPolicyEnum._11nameidFormatemailAddress} ?selected=${this.source?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._11nameidFormatemailAddress}>
<option value=${SAMLSourceNameIdPolicyEnum._11nameidFormatemailAddress} ?selected=${this.instance?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._11nameidFormatemailAddress}>
${t`Email address`}
</option>
<option value=${SAMLSourceNameIdPolicyEnum._20nameidFormatWindowsDomainQualifiedName} ?selected=${this.source?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._20nameidFormatWindowsDomainQualifiedName}>
<option value=${SAMLSourceNameIdPolicyEnum._20nameidFormatWindowsDomainQualifiedName} ?selected=${this.instance?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._20nameidFormatWindowsDomainQualifiedName}>
${t`Windows`}
</option>
<option value=${SAMLSourceNameIdPolicyEnum._20nameidFormatX509SubjectName} ?selected=${this.source?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._20nameidFormatX509SubjectName}>
<option value=${SAMLSourceNameIdPolicyEnum._20nameidFormatX509SubjectName} ?selected=${this.instance?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._20nameidFormatX509SubjectName}>
${t`X509 Subject`}
</option>
<option value=${SAMLSourceNameIdPolicyEnum._20nameidFormattransient} ?selected=${this.source?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._20nameidFormattransient}>
<option value=${SAMLSourceNameIdPolicyEnum._20nameidFormattransient} ?selected=${this.instance?.nameIdPolicy === SAMLSourceNameIdPolicyEnum._20nameidFormattransient}>
${t`Transient`}
</option>
</select>
@ -165,7 +160,7 @@ export class SAMLSourceForm extends Form<SAMLSource> {
label=${t`Delete temporary users after`}
?required=${true}
name="temporaryUserDeleteAfter">
<input type="text" value="${this.source?.temporaryUserDeleteAfter || "days=1"}" class="pf-c-form-control" required>
<input type="text" value="${this.instance?.temporaryUserDeleteAfter || "days=1"}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually. (Format: hours=1;minutes=2;seconds=3).`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
@ -173,16 +168,16 @@ export class SAMLSourceForm extends Form<SAMLSource> {
?required=${true}
name="digestAlgorithm">
<select class="pf-c-form-control">
<option value=${SAMLSourceDigestAlgorithmEnum._200009Xmldsigsha1} ?selected=${this.source?.digestAlgorithm === SAMLSourceDigestAlgorithmEnum._200009Xmldsigsha1}>
<option value=${SAMLSourceDigestAlgorithmEnum._200009Xmldsigsha1} ?selected=${this.instance?.digestAlgorithm === SAMLSourceDigestAlgorithmEnum._200009Xmldsigsha1}>
${t`SHA1`}
</option>
<option value=${SAMLSourceDigestAlgorithmEnum._200104Xmlencsha256} ?selected=${this.source?.digestAlgorithm === SAMLSourceDigestAlgorithmEnum._200104Xmlencsha256 || this.source?.digestAlgorithm === undefined}>
<option value=${SAMLSourceDigestAlgorithmEnum._200104Xmlencsha256} ?selected=${this.instance?.digestAlgorithm === SAMLSourceDigestAlgorithmEnum._200104Xmlencsha256 || this.instance?.digestAlgorithm === undefined}>
${t`SHA256`}
</option>
<option value=${SAMLSourceDigestAlgorithmEnum._200104XmldsigMoresha384} ?selected=${this.source?.digestAlgorithm === SAMLSourceDigestAlgorithmEnum._200104XmldsigMoresha384}>
<option value=${SAMLSourceDigestAlgorithmEnum._200104XmldsigMoresha384} ?selected=${this.instance?.digestAlgorithm === SAMLSourceDigestAlgorithmEnum._200104XmldsigMoresha384}>
${t`SHA384`}
</option>
<option value=${SAMLSourceDigestAlgorithmEnum._200104Xmlencsha512} ?selected=${this.source?.digestAlgorithm === SAMLSourceDigestAlgorithmEnum._200104Xmlencsha512}>
<option value=${SAMLSourceDigestAlgorithmEnum._200104Xmlencsha512} ?selected=${this.instance?.digestAlgorithm === SAMLSourceDigestAlgorithmEnum._200104Xmlencsha512}>
${t`SHA512`}
</option>
</select>
@ -192,19 +187,19 @@ export class SAMLSourceForm extends Form<SAMLSource> {
?required=${true}
name="signatureAlgorithm">
<select class="pf-c-form-control">
<option value=${SAMLSourceSignatureAlgorithmEnum._200009XmldsigrsaSha1} ?selected=${this.source?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200009XmldsigrsaSha1}>
<option value=${SAMLSourceSignatureAlgorithmEnum._200009XmldsigrsaSha1} ?selected=${this.instance?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200009XmldsigrsaSha1}>
${t`RSA-SHA1`}
</option>
<option value=${SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha256} ?selected=${this.source?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha256 || this.source?.signatureAlgorithm === undefined}>
<option value=${SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha256} ?selected=${this.instance?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha256 || this.instance?.signatureAlgorithm === undefined}>
${t`RSA-SHA256`}
</option>
<option value=${SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha384} ?selected=${this.source?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha384}>
<option value=${SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha384} ?selected=${this.instance?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha384}>
${t`RSA-SHA384`}
</option>
<option value=${SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha512} ?selected=${this.source?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha512}>
<option value=${SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha512} ?selected=${this.instance?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200104XmldsigMorersaSha512}>
${t`RSA-SHA512`}
</option>
<option value=${SAMLSourceSignatureAlgorithmEnum._200009XmldsigdsaSha1} ?selected=${this.source?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200009XmldsigdsaSha1}>
<option value=${SAMLSourceSignatureAlgorithmEnum._200009XmldsigdsaSha1} ?selected=${this.instance?.signatureAlgorithm === SAMLSourceSignatureAlgorithmEnum._200009XmldsigdsaSha1}>
${t`DSA-SHA1`}
</option>
</select>
@ -226,8 +221,8 @@ export class SAMLSourceForm extends Form<SAMLSource> {
designation: FlowDesignationEnum.StageConfiguration,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.source?.preAuthenticationFlow === flow.pk;
if (!this.source?.pk && !this.source?.preAuthenticationFlow && flow.slug === "default-source-pre-authentication") {
let selected = this.instance?.preAuthenticationFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.preAuthenticationFlow && flow.slug === "default-source-pre-authentication") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;
@ -246,8 +241,8 @@ export class SAMLSourceForm extends Form<SAMLSource> {
designation: FlowDesignationEnum.Authentication,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.source?.authenticationFlow === flow.pk;
if (!this.source?.pk && !this.source?.authenticationFlow && flow.slug === "default-source-authentication") {
let selected = this.instance?.authenticationFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.authenticationFlow && flow.slug === "default-source-authentication") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;
@ -266,8 +261,8 @@ export class SAMLSourceForm extends Form<SAMLSource> {
designation: FlowDesignationEnum.Enrollment,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.source?.enrollmentFlow === flow.pk;
if (!this.source?.pk && !this.source?.enrollmentFlow && flow.slug === "default-source-enrollment") {
let selected = this.instance?.enrollmentFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.enrollmentFlow && flow.slug === "default-source-enrollment") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;

View File

@ -109,7 +109,7 @@ export class SAMLSourceViewPage extends LitElement {
</span>
<ak-source-saml-form
slot="form"
.sourceSlug=${this.source.slug}>
.instancePk=${this.source.slug}>
</ak-source-saml-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${t`Edit`}

View File

@ -90,7 +90,7 @@ export class StageListPage extends TablePage<Stage> {
<ak-proxy-form
slot="form"
.args=${{
"stageUUID": item.pk
"instancePk": item.pk
}}
type=${ifDefined(item.component)}>
</ak-proxy-form>

View File

@ -1,31 +1,26 @@
import { FlowDesignationEnum, FlowsApi, AuthenticatorStaticStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { until } from "lit-html/directives/until";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-authenticator-static-form")
export class AuthenticatorStaticStageForm extends Form<AuthenticatorStaticStage> {
export class AuthenticatorStaticStageForm extends ModelForm<AuthenticatorStaticStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorStaticRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<AuthenticatorStaticStage> {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorStaticRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: AuthenticatorStaticStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -33,9 +28,9 @@ export class AuthenticatorStaticStageForm extends Form<AuthenticatorStaticStage>
}
send = (data: AuthenticatorStaticStage): Promise<AuthenticatorStaticStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorStaticUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -54,7 +49,7 @@ export class AuthenticatorStaticStageForm extends Form<AuthenticatorStaticStage>
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -65,20 +60,20 @@ export class AuthenticatorStaticStageForm extends Form<AuthenticatorStaticStage>
label=${t`Token count`}
?required=${true}
name="tokenCount">
<input type="text" value="${first(this.stage?.tokenCount, 6)}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.tokenCount, 6)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Configuration flow`}
name="configureFlow">
<select class="pf-c-form-control">
<option value="" ?selected=${this.stage?.configureFlow === undefined}>---------</option>
<option value="" ?selected=${this.instance?.configureFlow === undefined}>---------</option>
${until(new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
ordering: "pk",
designation: FlowDesignationEnum.StageConfiguration,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.stage?.configureFlow === flow.pk;
if (!this.stage?.pk && !this.stage?.configureFlow && flow.slug === "default-otp-time-configure") {
let selected = this.instance?.configureFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.configureFlow && flow.slug === "default-otp-time-configure") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;

View File

@ -1,30 +1,25 @@
import { FlowDesignationEnum, FlowsApi, AuthenticatorTOTPStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { until } from "lit-html/directives/until";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-authenticator-totp-form")
export class AuthenticatorTOTPStageForm extends Form<AuthenticatorTOTPStage> {
export class AuthenticatorTOTPStageForm extends ModelForm<AuthenticatorTOTPStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorTotpRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<AuthenticatorTOTPStage> {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorTotpRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: AuthenticatorTOTPStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -32,9 +27,9 @@ export class AuthenticatorTOTPStageForm extends Form<AuthenticatorTOTPStage> {
}
send = (data: AuthenticatorTOTPStage): Promise<AuthenticatorTOTPStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorTotpUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -53,7 +48,7 @@ export class AuthenticatorTOTPStageForm extends Form<AuthenticatorTOTPStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -65,10 +60,10 @@ export class AuthenticatorTOTPStageForm extends Form<AuthenticatorTOTPStage> {
?required=${true}
name="digits">
<select name="users" class="pf-c-form-control">
<option value="6" ?selected=${this.stage?.digits === 6}>
<option value="6" ?selected=${this.instance?.digits === 6}>
${t`6 digits, widely compatible`}
</option>
<option value="8" ?selected=${this.stage?.digits === 8}>
<option value="8" ?selected=${this.instance?.digits === 8}>
${t`8 digits, not compatible with apps like Google Authenticator`}
</option>
</select>
@ -77,14 +72,14 @@ export class AuthenticatorTOTPStageForm extends Form<AuthenticatorTOTPStage> {
label=${t`Configuration flow`}
name="configureFlow">
<select class="pf-c-form-control">
<option value="" ?selected=${this.stage?.configureFlow === undefined}>---------</option>
<option value="" ?selected=${this.instance?.configureFlow === undefined}>---------</option>
${until(new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
ordering: "pk",
designation: FlowDesignationEnum.StageConfiguration,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.stage?.configureFlow === flow.pk;
if (!this.stage?.pk && !this.stage?.configureFlow && flow.slug === "default-otp-time-configure") {
let selected = this.instance?.configureFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.configureFlow && flow.slug === "default-otp-time-configure") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;

View File

@ -3,32 +3,29 @@ import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { until } from "lit-html/directives/until";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-authenticator-validate-form")
export class AuthenticatorValidateStageForm extends Form<AuthenticatorValidateStage> {
export class AuthenticatorValidateStageForm extends ModelForm<AuthenticatorValidateStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorValidateRead({
stageUuid: value,
loadInstance(pk: string): Promise<AuthenticatorValidateStage> {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorValidateRead({
stageUuid: pk,
}).then(stage => {
this.stage = stage;
this.showConfigureFlow = stage.notConfiguredAction === AuthenticatorValidateStageNotConfiguredActionEnum.Configure;
return stage;
});
}
@property({attribute: false})
stage?: AuthenticatorValidateStage;
@property({ type: Boolean })
showConfigureFlow = false;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -36,9 +33,9 @@ export class AuthenticatorValidateStageForm extends Form<AuthenticatorValidateSt
}
send = (data: AuthenticatorValidateStage): Promise<AuthenticatorValidateStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorValidateUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -49,7 +46,7 @@ export class AuthenticatorValidateStageForm extends Form<AuthenticatorValidateSt
};
isDeviceClassSelected(field: AuthenticatorValidateStageDeviceClassesEnum): boolean {
return (this.stage?.deviceClasses || []).filter(isField => {
return (this.instance?.deviceClasses || []).filter(isField => {
return field === isField;
}).length > 0;
}
@ -63,7 +60,7 @@ export class AuthenticatorValidateStageForm extends Form<AuthenticatorValidateSt
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -82,13 +79,13 @@ export class AuthenticatorValidateStageForm extends Form<AuthenticatorValidateSt
this.showConfigureFlow = false;
}
}}>
<option value=${AuthenticatorValidateStageNotConfiguredActionEnum.Configure} ?selected=${this.stage?.notConfiguredAction === AuthenticatorValidateStageNotConfiguredActionEnum.Configure}>
<option value=${AuthenticatorValidateStageNotConfiguredActionEnum.Configure} ?selected=${this.instance?.notConfiguredAction === AuthenticatorValidateStageNotConfiguredActionEnum.Configure}>
${t`Force the user to configure an authenticator`}
</option>
<option value=${AuthenticatorValidateStageNotConfiguredActionEnum.Deny} ?selected=${this.stage?.notConfiguredAction === AuthenticatorValidateStageNotConfiguredActionEnum.Deny}>
<option value=${AuthenticatorValidateStageNotConfiguredActionEnum.Deny} ?selected=${this.instance?.notConfiguredAction === AuthenticatorValidateStageNotConfiguredActionEnum.Deny}>
${t`Deny the user access`}
</option>
<option value=${AuthenticatorValidateStageNotConfiguredActionEnum.Skip} ?selected=${this.stage?.notConfiguredAction === AuthenticatorValidateStageNotConfiguredActionEnum.Skip}>
<option value=${AuthenticatorValidateStageNotConfiguredActionEnum.Skip} ?selected=${this.instance?.notConfiguredAction === AuthenticatorValidateStageNotConfiguredActionEnum.Skip}>
${t`Continue`}
</option>
</select>
@ -117,12 +114,12 @@ export class AuthenticatorValidateStageForm extends Form<AuthenticatorValidateSt
?required=${true}
name="configureFlow">
<select class="pf-c-form-control">
<option value="" ?selected=${this.stage?.configurationStage === undefined}>---------</option>
<option value="" ?selected=${this.instance?.configurationStage === undefined}>---------</option>
${until(new StagesApi(DEFAULT_CONFIG).stagesAllList({
ordering: "pk",
}).then(stages => {
return stages.results.map(stage => {
const selected = this.stage?.configurationStage === stage.pk;
const selected = this.instance?.configurationStage === stage.pk;
return html`<option value=${ifDefined(stage.pk)} ?selected=${selected}>${stage.name} (${stage.verboseName})</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}

View File

@ -1,28 +1,23 @@
import { AuthenticateWebAuthnStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-authenticator-webauthn-form")
export class AuthenticateWebAuthnStageForm extends Form<AuthenticateWebAuthnStage> {
export class AuthenticateWebAuthnStageForm extends ModelForm<AuthenticateWebAuthnStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorWebauthnRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<AuthenticateWebAuthnStage> {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorWebauthnRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: AuthenticateWebAuthnStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -30,9 +25,9 @@ export class AuthenticateWebAuthnStageForm extends Form<AuthenticateWebAuthnStag
}
send = (data: AuthenticateWebAuthnStage): Promise<AuthenticateWebAuthnStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorWebauthnUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -51,7 +46,7 @@ export class AuthenticateWebAuthnStageForm extends Form<AuthenticateWebAuthnStag
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,29 +1,24 @@
import { CaptchaStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-captcha-form")
export class CaptchaStageForm extends Form<CaptchaStage> {
export class CaptchaStageForm extends ModelForm<CaptchaStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesCaptchaRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<CaptchaStage> {
return new StagesApi(DEFAULT_CONFIG).stagesCaptchaRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: CaptchaStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -31,9 +26,9 @@ export class CaptchaStageForm extends Form<CaptchaStage> {
}
send = (data: CaptchaStage): Promise<CaptchaStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesCaptchaPartialUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -52,7 +47,7 @@ export class CaptchaStageForm extends Form<CaptchaStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -63,15 +58,15 @@ export class CaptchaStageForm extends Form<CaptchaStage> {
label=${t`Public Key`}
?required=${true}
name="publicKey">
<input type="text" value="${ifDefined(this.stage?.publicKey || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.publicKey || "")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Public key, acquired from https://www.google.com/recaptcha/intro/v3.html.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Private Key`}
?required=${true}
?writeOnly=${this.stage !== undefined}
?writeOnly=${this.instance !== undefined}
name="privateKey">
<input type="text" value="${ifDefined(this.stage?.privateKey || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.privateKey || "")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Private key, acquired from https://www.google.com/recaptcha/intro/v3.html.`}</p>
</ak-form-element-horizontal>
</div>

View File

@ -3,31 +3,28 @@ import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-consent-form")
export class ConsentStageForm extends Form<ConsentStage> {
export class ConsentStageForm extends ModelForm<ConsentStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesConsentRead({
stageUuid: value,
loadInstance(pk: string): Promise<ConsentStage> {
return new StagesApi(DEFAULT_CONFIG).stagesConsentRead({
stageUuid: pk,
}).then(stage => {
this.stage = stage;
this.showExpiresIn = stage.name === ConsentStageModeEnum.Expiring;
return stage;
});
}
@property({attribute: false})
stage?: ConsentStage;
@property({type: Boolean})
showExpiresIn = false;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -35,9 +32,9 @@ export class ConsentStageForm extends Form<ConsentStage> {
}
send = (data: ConsentStage): Promise<ConsentStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesConsentUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -56,7 +53,7 @@ export class ConsentStageForm extends Form<ConsentStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -75,13 +72,13 @@ export class ConsentStageForm extends Form<ConsentStage> {
this.showExpiresIn = false;
}
}}>
<option value=${ConsentStageModeEnum.AlwaysRequire} ?selected=${this.stage?.mode === ConsentStageModeEnum.AlwaysRequire}>
<option value=${ConsentStageModeEnum.AlwaysRequire} ?selected=${this.instance?.mode === ConsentStageModeEnum.AlwaysRequire}>
${t`Always require consent`}
</option>
<option value=${ConsentStageModeEnum.Permanent} ?selected=${this.stage?.mode === ConsentStageModeEnum.Permanent}>
<option value=${ConsentStageModeEnum.Permanent} ?selected=${this.instance?.mode === ConsentStageModeEnum.Permanent}>
${t`Consent given last indefinitely`}
</option>
<option value=${ConsentStageModeEnum.Expiring} ?selected=${this.stage?.mode === ConsentStageModeEnum.Expiring}>
<option value=${ConsentStageModeEnum.Expiring} ?selected=${this.instance?.mode === ConsentStageModeEnum.Expiring}>
${t`Consent expires.`}
</option>
</select>
@ -91,7 +88,7 @@ export class ConsentStageForm extends Form<ConsentStage> {
label=${t`Consent expires in`}
?required=${true}
name="consentExpireIn">
<input type="text" value="${ifDefined(this.stage?.consentExpireIn || "weeks=4")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.consentExpireIn || "weeks=4")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3).`}</p>
</ak-form-element-horizontal>
</div>

View File

@ -1,28 +1,23 @@
import { DenyStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-deny-form")
export class DenyStageForm extends Form<DenyStage> {
export class DenyStageForm extends ModelForm<DenyStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesDenyRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<DenyStage> {
return new StagesApi(DEFAULT_CONFIG).stagesDenyRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: DenyStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -30,9 +25,9 @@ export class DenyStageForm extends Form<DenyStage> {
}
send = (data: DenyStage): Promise<DenyStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesDenyUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -51,7 +46,7 @@ export class DenyStageForm extends Form<DenyStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,28 +1,23 @@
import { DummyStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-dummy-form")
export class DummyStageForm extends Form<DummyStage> {
export class DummyStageForm extends ModelForm<DummyStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesDummyRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<DummyStage> {
return new StagesApi(DEFAULT_CONFIG).stagesDummyRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: DummyStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -30,9 +25,9 @@ export class DummyStageForm extends Form<DummyStage> {
}
send = (data: DummyStage): Promise<DummyStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesDummyUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -51,7 +46,7 @@ export class DummyStageForm extends Form<DummyStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -3,32 +3,30 @@ import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
import { until } from "lit-html/directives/until";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-email-form")
export class EmailStageForm extends Form<EmailStage> {
export class EmailStageForm extends ModelForm<EmailStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesEmailRead({
stageUuid: value,
loadInstance(pk: string): Promise<EmailStage> {
return new StagesApi(DEFAULT_CONFIG).stagesEmailRead({
stageUuid: pk,
}).then(stage => {
this.stage = stage;
this.showConnectionSettings = !stage.useGlobalSettings;
return stage;
});
}
@property({attribute: false})
stage?: EmailStage;
@property({type: Boolean})
showConnectionSettings = false;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -36,9 +34,9 @@ export class EmailStageForm extends Form<EmailStage> {
}
send = (data: EmailStage): Promise<EmailStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesEmailPartialUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -61,28 +59,28 @@ export class EmailStageForm extends Form<EmailStage> {
label=${t`SMTP Host`}
?required=${true}
name="host">
<input type="text" value="${ifDefined(this.stage?.host || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.host || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`SMTP Port`}
?required=${true}
name="port">
<input type="number" value="${first(this.stage?.port, 25)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.port, 25)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`SMTP Username`}
name="username">
<input type="text" value="${ifDefined(this.stage?.username || "")}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.username || "")}" class="pf-c-form-control">
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`SMTP Password`}
?writeOnly=${this.stage !== undefined}
?writeOnly=${this.instance !== undefined}
name="password">
<input type="text" value="${ifDefined(this.stage?.password || "")}" class="pf-c-form-control">
<input type="text" value="${ifDefined(this.instance?.password || "")}" class="pf-c-form-control">
</ak-form-element-horizontal>
<ak-form-element-horizontal name="useTls">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.stage?.useTls, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.useTls, true)}>
<label class="pf-c-check__label">
${t`Use TLS`}
</label>
@ -90,7 +88,7 @@ export class EmailStageForm extends Form<EmailStage> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="useSsl">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.stage?.useSsl, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.useSsl, false)}>
<label class="pf-c-check__label">
${t`Use SSL`}
</label>
@ -100,13 +98,13 @@ export class EmailStageForm extends Form<EmailStage> {
label=${t`Timeout`}
?required=${true}
name="timeout">
<input type="number" value="${first(this.stage?.timeout, 30)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.timeout, 30)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`From address`}
?required=${true}
name="fromAddress">
<input type="text" value="${ifDefined(this.stage?.fromAddress || "system@authentik.local")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.fromAddress || "system@authentik.local")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</div>
</ak-form-group>`;
@ -121,7 +119,7 @@ export class EmailStageForm extends Form<EmailStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -130,7 +128,7 @@ export class EmailStageForm extends Form<EmailStage> {
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="useGlobalSettings">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.stage?.useGlobalSettings, true)} @change=${(ev: Event) => {
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.useGlobalSettings, true)} @change=${(ev: Event) => {
const target = ev.target as HTMLInputElement;
this.showConnectionSettings = !target.checked;
}}>
@ -144,14 +142,14 @@ export class EmailStageForm extends Form<EmailStage> {
label=${t`Token expiry`}
?required=${true}
name="tokenExpiry">
<input type="number" value="${first(this.stage?.tokenExpiry, 30)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.tokenExpiry, 30)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Time in minutes the token sent is valid.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Subject`}
?required=${true}
name="subject">
<input type="text" value="${first(this.stage?.subject, "authentik")}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.subject, "authentik")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Template`}
@ -160,7 +158,7 @@ export class EmailStageForm extends Form<EmailStage> {
<select name="users" class="pf-c-form-control">
${until(new StagesApi(DEFAULT_CONFIG).stagesEmailTemplates().then(templates => {
return templates.map(template => {
const selected = this.stage?.template === template.name;
const selected = this.instance?.template === template.name;
return html`<option value=${ifDefined(template.name)} ?selected=${selected}>
${template.description}
</option>`;

View File

@ -1,31 +1,26 @@
import { FlowDesignationEnum, FlowsApi, IdentificationStage, IdentificationStageUserFieldsEnum, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { until } from "lit-html/directives/until";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-identification-form")
export class IdentificationStageForm extends Form<IdentificationStage> {
export class IdentificationStageForm extends ModelForm<IdentificationStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesIdentificationRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<IdentificationStage> {
return new StagesApi(DEFAULT_CONFIG).stagesIdentificationRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: IdentificationStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -33,9 +28,9 @@ export class IdentificationStageForm extends Form<IdentificationStage> {
}
send = (data: IdentificationStage): Promise<IdentificationStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesIdentificationUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -46,7 +41,7 @@ export class IdentificationStageForm extends Form<IdentificationStage> {
};
isUserFieldSelected(field: IdentificationStageUserFieldsEnum): boolean {
return (this.stage?.userFields || []).filter(isField => {
return (this.instance?.userFields || []).filter(isField => {
return field === isField;
}).length > 0;
}
@ -60,7 +55,7 @@ export class IdentificationStageForm extends Form<IdentificationStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -83,7 +78,7 @@ export class IdentificationStageForm extends Form<IdentificationStage> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="caseInsensitiveMatching">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.stage?.caseInsensitiveMatching, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.caseInsensitiveMatching, true)}>
<label class="pf-c-check__label">
${t`Case insensitive matching`}
</label>
@ -92,7 +87,7 @@ export class IdentificationStageForm extends Form<IdentificationStage> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="showMatchedUser">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.stage?.showMatchedUser, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.showMatchedUser, true)}>
<label class="pf-c-check__label">
${t`Show matched user`}
</label>
@ -103,13 +98,13 @@ export class IdentificationStageForm extends Form<IdentificationStage> {
label=${t`Enrollment flow`}
name="enrollmentFlow">
<select class="pf-c-form-control">
<option value="" ?selected=${this.stage?.enrollmentFlow === undefined}>---------</option>
<option value="" ?selected=${this.instance?.enrollmentFlow === undefined}>---------</option>
${until(new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
ordering: "pk",
designation: FlowDesignationEnum.Enrollment,
}).then(flows => {
return flows.results.map(flow => {
const selected = this.stage?.enrollmentFlow === flow.pk;
const selected = this.instance?.enrollmentFlow === flow.pk;
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
@ -120,13 +115,13 @@ export class IdentificationStageForm extends Form<IdentificationStage> {
label=${t`Recovery flow`}
name="recoveryFlow">
<select class="pf-c-form-control">
<option value="" ?selected=${this.stage?.recoveryFlow === undefined}>---------</option>
<option value="" ?selected=${this.instance?.recoveryFlow === undefined}>---------</option>
${until(new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
ordering: "pk",
designation: FlowDesignationEnum.Recovery,
}).then(flows => {
return flows.results.map(flow => {
const selected = this.stage?.recoveryFlow === flow.pk;
const selected = this.instance?.recoveryFlow === flow.pk;
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}

View File

@ -1,22 +1,25 @@
import { Invitation, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/CodeMirror";
import YAML from "yaml";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-invitation-form")
export class InvitationForm extends Form<Invitation> {
export class InvitationForm extends ModelForm<Invitation, string> {
@property({attribute: false})
invitation?: Invitation;
loadInstance(pk: string): Promise<Invitation> {
return new StagesApi(DEFAULT_CONFIG).stagesInvitationInvitationsRead({
inviteUuid: pk,
});
}
getSuccessMessage(): string {
if (this.invitation) {
if (this.instance) {
return t`Successfully updated invitation.`;
} else {
return t`Successfully created invitation.`;
@ -24,9 +27,9 @@ export class InvitationForm extends Form<Invitation> {
}
send = (data: Invitation): Promise<Invitation> => {
if (this.invitation) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesInvitationInvitationsUpdate({
inviteUuid: this.invitation.pk || "",
inviteUuid: this.instance.pk || "",
data: data
});
} else {
@ -47,13 +50,13 @@ export class InvitationForm extends Form<Invitation> {
<ak-form-element-horizontal
label=${t`Attributes`}
name="fixedData">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.invitation?.fixedData, {}))}">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.instance?.fixedData, {}))}">
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Optional data which is loaded into the flow's 'prompt_data' context variable. YAML or JSON.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="singleUse">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.invitation?.singleUse, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.singleUse, true)}>
<label class="pf-c-check__label">
${t`Single use`}
</label>

View File

@ -1,30 +1,25 @@
import { InvitationStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-invitation-form")
export class InvitationStageForm extends Form<InvitationStage> {
export class InvitationStageForm extends ModelForm<InvitationStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesInvitationStagesRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<InvitationStage> {
return new StagesApi(DEFAULT_CONFIG).stagesInvitationStagesRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: InvitationStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -32,9 +27,9 @@ export class InvitationStageForm extends Form<InvitationStage> {
}
send = (data: InvitationStage): Promise<InvitationStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesInvitationStagesUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -53,7 +48,7 @@ export class InvitationStageForm extends Form<InvitationStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -62,7 +57,7 @@ export class InvitationStageForm extends Form<InvitationStage> {
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal name="continueFlowWithoutInvitation">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.stage?.continueFlowWithoutInvitation, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.continueFlowWithoutInvitation, true)}>
<label class="pf-c-check__label">
${t`Continue flow without invitation`}
</label>

View File

@ -1,31 +1,26 @@
import { FlowDesignationEnum, FlowsApi, PasswordStage, PasswordStageBackendsEnum, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { until } from "lit-html/directives/until";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-password-form")
export class PasswordStageForm extends Form<PasswordStage> {
export class PasswordStageForm extends ModelForm<PasswordStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesPasswordRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<PasswordStage> {
return new StagesApi(DEFAULT_CONFIG).stagesPasswordRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: PasswordStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -33,9 +28,9 @@ export class PasswordStageForm extends Form<PasswordStage> {
}
send = (data: PasswordStage): Promise<PasswordStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesPasswordUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -46,7 +41,7 @@ export class PasswordStageForm extends Form<PasswordStage> {
};
isBackendSelected(field: PasswordStageBackendsEnum): boolean {
return (this.stage?.backends || []).filter(isField => {
return (this.instance?.backends || []).filter(isField => {
return field === isField;
}).length > 0;
}
@ -60,7 +55,7 @@ export class PasswordStageForm extends Form<PasswordStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -87,14 +82,14 @@ export class PasswordStageForm extends Form<PasswordStage> {
?required=${true}
name="configureFlow">
<select class="pf-c-form-control">
<option value="" ?selected=${this.stage?.configureFlow === undefined}>---------</option>
<option value="" ?selected=${this.instance?.configureFlow === undefined}>---------</option>
${until(new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
ordering: "pk",
designation: FlowDesignationEnum.StageConfiguration,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.stage?.configureFlow === flow.pk;
if (!this.stage?.pk && !this.stage?.configureFlow && flow.slug === "default-password-change") {
let selected = this.instance?.configureFlow === flow.pk;
if (!this.instance?.pk && !this.instance?.configureFlow && flow.slug === "default-password-change") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;
@ -107,7 +102,7 @@ export class PasswordStageForm extends Form<PasswordStage> {
label=${t`Failed attempts before cancel`}
?required=${true}
name="failedAttemptsBeforeCancel">
<input type="number" value="${first(this.stage?.failedAttemptsBeforeCancel, 5)}" class="pf-c-form-control" required>
<input type="number" value="${first(this.instance?.failedAttemptsBeforeCancel, 5)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`How many attempts a user has before the flow is canceled. To lock the user out, use a reputation policy and a user_write stage.`}</p>
</ak-form-element-horizontal>
</div>

View File

@ -1,21 +1,24 @@
import { Prompt, PromptTypeEnum, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-prompt-form")
export class PromptForm extends Form<Prompt> {
export class PromptForm extends ModelForm<Prompt, string> {
@property({attribute: false})
prompt?: Prompt;
loadInstance(pk: string): Promise<Prompt> {
return new StagesApi(DEFAULT_CONFIG).stagesPromptPromptsRead({
promptUuid: pk
});
}
getSuccessMessage(): string {
if (this.prompt) {
if (this.instance) {
return t`Successfully updated prompt.`;
} else {
return t`Successfully created prompt.`;
@ -23,9 +26,9 @@ export class PromptForm extends Form<Prompt> {
}
send = (data: Prompt): Promise<Prompt> => {
if (this.prompt) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesPromptPromptsUpdate({
promptUuid: this.prompt.pk || "",
promptUuid: this.instance.pk || "",
data: data
});
} else {
@ -37,37 +40,37 @@ export class PromptForm extends Form<Prompt> {
renderTypes(): TemplateResult {
return html`
<option value=${PromptTypeEnum.Text} ?selected=${this.prompt?.type === PromptTypeEnum.Text}>
<option value=${PromptTypeEnum.Text} ?selected=${this.instance?.type === PromptTypeEnum.Text}>
${t`Text: Simple Text input`}
</option>
<option value=${PromptTypeEnum.Username} ?selected=${this.prompt?.type === PromptTypeEnum.Username}>
<option value=${PromptTypeEnum.Username} ?selected=${this.instance?.type === PromptTypeEnum.Username}>
${t`Username: Same as Text input, but checks for and prevents duplicate usernames.`}
</option>
<option value=${PromptTypeEnum.Email} ?selected=${this.prompt?.type === PromptTypeEnum.Email}>
<option value=${PromptTypeEnum.Email} ?selected=${this.instance?.type === PromptTypeEnum.Email}>
${t`Email: Text field with Email type.`}
</option>
<option value=${PromptTypeEnum.Password} ?selected=${this.prompt?.type === PromptTypeEnum.Password}>
<option value=${PromptTypeEnum.Password} ?selected=${this.instance?.type === PromptTypeEnum.Password}>
${t`Password: Masked input, password is validated against sources. Policies still have to be applied to this Stage. If two of these are used in the same stage, they are ensured to be identical.`}
</option>
<option value=${PromptTypeEnum.Number} ?selected=${this.prompt?.type === PromptTypeEnum.Number}>
<option value=${PromptTypeEnum.Number} ?selected=${this.instance?.type === PromptTypeEnum.Number}>
${t`Number`}
</option>
<option value=${PromptTypeEnum.Checkbox} ?selected=${this.prompt?.type === PromptTypeEnum.Checkbox}>
<option value=${PromptTypeEnum.Checkbox} ?selected=${this.instance?.type === PromptTypeEnum.Checkbox}>
${t`Checkbox`}
</option>
<option value=${PromptTypeEnum.Date} ?selected=${this.prompt?.type === PromptTypeEnum.Date}>
<option value=${PromptTypeEnum.Date} ?selected=${this.instance?.type === PromptTypeEnum.Date}>
${t`Date`}
</option>
<option value=${PromptTypeEnum.DateTime} ?selected=${this.prompt?.type === PromptTypeEnum.DateTime}>
<option value=${PromptTypeEnum.DateTime} ?selected=${this.instance?.type === PromptTypeEnum.DateTime}>
${t`Date Time`}
</option>
<option value=${PromptTypeEnum.Separator} ?selected=${this.prompt?.type === PromptTypeEnum.Separator}>
<option value=${PromptTypeEnum.Separator} ?selected=${this.instance?.type === PromptTypeEnum.Separator}>
${t`Separator: Static Separator Line`}
</option>
<option value=${PromptTypeEnum.Hidden} ?selected=${this.prompt?.type === PromptTypeEnum.Hidden}>
<option value=${PromptTypeEnum.Hidden} ?selected=${this.instance?.type === PromptTypeEnum.Hidden}>
${t`Hidden: Hidden field, can be used to insert data into form.`}
</option>
<option value=${PromptTypeEnum.Static} ?selected=${this.prompt?.type === PromptTypeEnum.Static}>
<option value=${PromptTypeEnum.Static} ?selected=${this.instance?.type === PromptTypeEnum.Static}>
${t`Static: Static value, displayed as-is.`}
</option>
`;
@ -79,14 +82,14 @@ export class PromptForm extends Form<Prompt> {
label=${t`Field Key`}
?required=${true}
name="fieldKey">
<input type="text" value="${ifDefined(this.prompt?.fieldKey)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.fieldKey)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Name of the form field, also used to store the value.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Label`}
?required=${true}
name="label">
<input type="text" value="${ifDefined(this.prompt?.label)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.label)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Label shown next to/above the prompt.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
@ -99,7 +102,7 @@ export class PromptForm extends Form<Prompt> {
</ak-form-element-horizontal>
<ak-form-element-horizontal name="required">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.prompt?.required, false)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.required, false)}>
<label class="pf-c-check__label">
${t`Required`}
</label>
@ -108,14 +111,14 @@ export class PromptForm extends Form<Prompt> {
<ak-form-element-horizontal
label=${t`Placeholder`}
name="placeholder">
<input type="text" value="${ifDefined(this.prompt?.placeholder)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.placeholder)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Optionally pre-fill the input value`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Order`}
?required=${true}
name="order">
<input type="number" value="${ifDefined(this.prompt?.order)}" class="pf-c-form-control" required>
<input type="number" value="${ifDefined(this.instance?.order)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -68,7 +68,7 @@ export class PromptListPage extends TablePage<Prompt> {
<span slot="header">
${t`Update Prompt`}
</span>
<ak-prompt-form slot="form" .prompt=${item}>
<ak-prompt-form slot="form" .instancePk=${item.pk}>
</ak-prompt-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -1,32 +1,27 @@
import { PoliciesApi, PromptStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/ModalForm";
import "./PromptForm";
import { until } from "lit-html/directives/until";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-prompt-form")
export class PromptStageForm extends Form<PromptStage> {
export class PromptStageForm extends ModelForm<PromptStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesPromptStagesRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<PromptStage> {
return new StagesApi(DEFAULT_CONFIG).stagesPromptStagesRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: PromptStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -34,9 +29,9 @@ export class PromptStageForm extends Form<PromptStage> {
}
send = (data: PromptStage): Promise<PromptStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesPromptStagesUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -55,7 +50,7 @@ export class PromptStageForm extends Form<PromptStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -71,7 +66,7 @@ export class PromptStageForm extends Form<PromptStage> {
ordering: "field_name"
}).then(prompts => {
return prompts.results.map(prompt => {
const selected = Array.from(this.stage?.fields || []).some(su => {
const selected = Array.from(this.instance?.fields || []).some(su => {
return su == prompt.pk;
});
return html`<option value=${ifDefined(prompt.pk)} ?selected=${selected}>
@ -103,7 +98,7 @@ export class PromptStageForm extends Form<PromptStage> {
ordering: "name"
}).then(policies => {
return policies.results.map(policy => {
const selected = Array.from(this.stage?.validationPolicies || []).some(su => {
const selected = Array.from(this.instance?.validationPolicies || []).some(su => {
return su == policy.pk;
});
return html`<option value=${ifDefined(policy.pk)} ?selected=${selected}>

View File

@ -1,28 +1,23 @@
import { UserDeleteStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-user-delete-form")
export class UserDeleteStageForm extends Form<UserDeleteStage> {
export class UserDeleteStageForm extends ModelForm<UserDeleteStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesUserDeleteRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<UserDeleteStage> {
return new StagesApi(DEFAULT_CONFIG).stagesUserDeleteRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: UserDeleteStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -30,9 +25,9 @@ export class UserDeleteStageForm extends Form<UserDeleteStage> {
}
send = (data: UserDeleteStage): Promise<UserDeleteStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesUserDeleteUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -52,7 +47,7 @@ export class UserDeleteStageForm extends Form<UserDeleteStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,29 +1,24 @@
import { UserLoginStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import "../../../elements/forms/HorizontalFormElement";
import "../../../elements/forms/FormGroup";
import { first } from "../../../utils";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-user-login-form")
export class UserLoginStageForm extends Form<UserLoginStage> {
export class UserLoginStageForm extends ModelForm<UserLoginStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesUserLoginRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<UserLoginStage> {
return new StagesApi(DEFAULT_CONFIG).stagesUserLoginRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: UserLoginStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -31,9 +26,9 @@ export class UserLoginStageForm extends Form<UserLoginStage> {
}
send = (data: UserLoginStage): Promise<UserLoginStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesUserLoginUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -52,7 +47,7 @@ export class UserLoginStageForm extends Form<UserLoginStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${first(this.stage?.name, "")}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.name, "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
@ -63,7 +58,7 @@ export class UserLoginStageForm extends Form<UserLoginStage> {
label=${t`Session duration`}
?required=${true}
name="sessionDuration">
<input type="text" value="${first(this.stage?.sessionDuration, "seconds=0")}" class="pf-c-form-control" required>
<input type="text" value="${first(this.instance?.sessionDuration, "seconds=0")}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Determines how long a session lasts. Default of 0 seconds means that the sessions lasts until the browser is closed.`}</p>
<p class="pf-c-form__helper-text">${t`(Format: hours=-1;minutes=-2;seconds=-3).`}</p>
</ak-form-element-horizontal>

View File

@ -1,28 +1,23 @@
import { UserLogoutStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-user-logout-form")
export class UserLogoutStageForm extends Form<UserLogoutStage> {
export class UserLogoutStageForm extends ModelForm<UserLogoutStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesUserLogoutRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<UserLogoutStage> {
return new StagesApi(DEFAULT_CONFIG).stagesUserLogoutRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: UserLogoutStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -30,9 +25,9 @@ export class UserLogoutStageForm extends Form<UserLogoutStage> {
}
send = (data: UserLogoutStage): Promise<UserLogoutStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesUserLogoutUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -51,7 +46,7 @@ export class UserLogoutStageForm extends Form<UserLogoutStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,28 +1,23 @@
import { UserWriteStage, StagesApi } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-stage-user-write-form")
export class UserWriteStageForm extends Form<UserWriteStage> {
export class UserWriteStageForm extends ModelForm<UserWriteStage, string> {
set stageUUID(value: string) {
new StagesApi(DEFAULT_CONFIG).stagesUserWriteRead({
stageUuid: value,
}).then(stage => {
this.stage = stage;
loadInstance(pk: string): Promise<UserWriteStage> {
return new StagesApi(DEFAULT_CONFIG).stagesUserWriteRead({
stageUuid: pk,
});
}
@property({attribute: false})
stage?: UserWriteStage;
getSuccessMessage(): string {
if (this.stage) {
if (this.instance) {
return t`Successfully updated stage.`;
} else {
return t`Successfully created stage.`;
@ -30,9 +25,9 @@ export class UserWriteStageForm extends Form<UserWriteStage> {
}
send = (data: UserWriteStage): Promise<UserWriteStage> => {
if (this.stage) {
if (this.instance) {
return new StagesApi(DEFAULT_CONFIG).stagesUserWriteUpdate({
stageUuid: this.stage.pk || "",
stageUuid: this.instance.pk || "",
data: data
});
} else {
@ -52,7 +47,7 @@ export class UserWriteStageForm extends Form<UserWriteStage> {
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.stage?.name || "")}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name || "")}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -1,20 +1,23 @@
import { CoreApi, Token } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../../elements/forms/HorizontalFormElement";
import { ModelForm } from "../../../elements/forms/ModelForm";
@customElement("ak-user-token-form")
export class UserTokenForm extends Form<Token> {
export class UserTokenForm extends ModelForm<Token, string> {
@property({attribute: false})
token?: Token;
loadInstance(pk: string): Promise<Token> {
return new CoreApi(DEFAULT_CONFIG).coreTokensRead({
identifier: pk
});
}
getSuccessMessage(): string {
if (this.token) {
if (this.instance) {
return t`Successfully updated token.`;
} else {
return t`Successfully created token.`;
@ -22,9 +25,9 @@ export class UserTokenForm extends Form<Token> {
}
send = (data: Token): Promise<Token> => {
if (this.token) {
if (this.instance) {
return new CoreApi(DEFAULT_CONFIG).coreTokensUpdate({
identifier: this.token.identifier,
identifier: this.instance.identifier,
data: data
});
} else {
@ -40,13 +43,13 @@ export class UserTokenForm extends Form<Token> {
label=${t`Identifier`}
?required=${true}
name="identifier">
<input type="text" value="${ifDefined(this.token?.identifier)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.identifier)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Description`}
?required=${true}
name="description">
<input type="text" value="${ifDefined(this.token?.description)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.description)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -110,7 +110,7 @@ export class UserTokenList extends Table<Token> {
<span slot="header">
${t`Update Token`}
</span>
<ak-user-token-form slot="form" .token=${item}>
<ak-user-token-form slot="form" .instancePk=${item.identifier}>
</ak-user-token-form>
<button slot="trigger" class="pf-c-button pf-m-secondary">
${t`Edit`}

View File

@ -1,23 +1,26 @@
import { CoreApi, User } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { customElement } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../api/Config";
import { Form } from "../../elements/forms/Form";
import { ifDefined } from "lit-html/directives/if-defined";
import "../../elements/forms/HorizontalFormElement";
import "../../elements/CodeMirror";
import YAML from "yaml";
import { first } from "../../utils";
import { ModelForm } from "../../elements/forms/ModelForm";
@customElement("ak-user-form")
export class UserForm extends Form<User> {
export class UserForm extends ModelForm<User, number> {
@property({ attribute: false })
user?: User;
loadInstance(pk: number): Promise<User> {
return new CoreApi(DEFAULT_CONFIG).coreUsersRead({
id: pk
});
}
getSuccessMessage(): string {
if (this.user) {
if (this.instance) {
return t`Successfully updated user.`;
} else {
return t`Successfully created user.`;
@ -25,9 +28,9 @@ export class UserForm extends Form<User> {
}
send = (data: User): Promise<User> => {
if (this.user) {
if (this.instance) {
return new CoreApi(DEFAULT_CONFIG).coreUsersUpdate({
id: this.user.pk || 0,
id: this.instance.pk || 0,
data: data
});
} else {
@ -43,26 +46,26 @@ export class UserForm extends Form<User> {
label=${t`Username`}
?required=${true}
name="username">
<input type="text" value="${ifDefined(this.user?.username)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.username)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.user?.name)}" class="pf-c-form-control" required>
<input type="text" value="${ifDefined(this.instance?.name)}" class="pf-c-form-control" required>
<p class="pf-c-form__helper-text">${t`User's display name.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Email`}
?required=${true}
name="email">
<input type="email" autocomplete="off" value="${ifDefined(this.user?.email)}" class="pf-c-form-control" required>
<input type="email" autocomplete="off" value="${ifDefined(this.instance?.email)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
name="isActive">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.user?.isActive, true)}>
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.instance?.isActive, true)}>
<label class="pf-c-check__label">
${t`Is active`}
</label>
@ -73,7 +76,7 @@ export class UserForm extends Form<User> {
label=${t`Attributes`}
?required=${true}
name="attributes">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.user?.attributes, {}))}">
<ak-codemirror mode="yaml" value="${YAML.stringify(first(this.instance?.attributes, {}))}">
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Set custom attributes using YAML or JSON.`}</p>
</ak-form-element-horizontal>

View File

@ -75,7 +75,7 @@ export class UserListPage extends TablePage<User> {
<span slot="header">
${t`Update User`}
</span>
<ak-user-form slot="form" .user=${item}>
<ak-user-form slot="form" .instancePk=${item.pk}>
</ak-user-form>
<button slot="trigger" class="pf-m-secondary pf-c-button">
${t`Edit`}

View File

@ -144,7 +144,7 @@ export class UserViewPage extends LitElement {
<span slot="header">
${t`Update User`}
</span>
<ak-user-form slot="form" .user=${this.user}>
<ak-user-form slot="form" .instancePk=${this.user.pk}>
</ak-user-form>
<button slot="trigger" class="pf-m-primary pf-c-button">
${t`Edit`}