Merge branch 'ak-select-crypto-certificate' into application-wizard-2

* ak-select-crypto-certificate:
  web: display tests for CryptoCertificateKeypair search
  web: Replace ad-hoc search for CryptoCertificateKeyPairs with ak-crypto-certeficate-search
This commit is contained in:
Ken Sternberg 2023-08-07 09:58:49 -07:00
commit eed32b0235
12 changed files with 173 additions and 370 deletions

View File

@ -1,6 +1,7 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { AKElement } from "@goauthentik/elements/Base";
import { SearchSelect } from "@goauthentik/elements/forms/SearchSelect";
import "@goauthentik/elements/forms/SearchSelect";
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
import { html } from "lit";
@ -29,7 +30,7 @@ const renderValue = (item: CertificateKeyPair | undefined): string | undefined =
*/
@customElement("ak-crypto-certificate-search")
export class CryptoCertificateSearch extends CustomListenerElement(AKElement) {
export class AkCryptoCertificateSearch extends CustomListenerElement(AKElement) {
@property({ type: String, reflect: true })
certificate?: string;
@ -126,4 +127,4 @@ export class CryptoCertificateSearch extends CustomListenerElement(AKElement) {
}
}
export default CryptoCertificateSearch;
export default AkCryptoCertificateSearch;

View File

@ -2,6 +2,7 @@ import { RenderFlowOption } from "@goauthentik/admin/flows/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { AKElement } from "@goauthentik/elements/Base";
import { SearchSelect } from "@goauthentik/elements/forms/SearchSelect";
import "@goauthentik/elements/forms/SearchSelect";
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
import { html } from "lit";

View File

@ -0,0 +1,91 @@
import "@goauthentik/elements/forms/HorizontalFormElement";
import "@goauthentik/elements/messages/MessageContainer";
import { Meta } from "@storybook/web-components";
import { TemplateResult, html } from "lit";
import "../ak-crypto-certificate-search";
import AkCryptoCertificateSearch from "../ak-crypto-certificate-search";
import { dummyCryptoCertsSearch } from "./samples";
const metadata: Meta<AkCryptoCertificateSearch> = {
title: "Components / Searches / CryptoCertificateKeyPair",
component: "ak-crypto-certificate-search",
parameters: {
docs: {
description: {
component: "A search function for cryptographic certificates in Authentik",
},
},
mockData: [
{
url: "/api/v3/crypto/certificatekeypairs/?has_key=true&include_details=false&ordering=name",
method: "GET",
status: 200,
response: dummyCryptoCertsSearch,
},
],
},
argTypes: {
// Typescript is unaware that arguments for components are treated as properties, and
// properties are typically renamed to lower case, even if the variable is not.
// @ts-expect-error
nokey: {
control: "boolean",
description:
"When true, certificates without valid keys will be included in the search",
},
singleton: {
control: "boolean",
description:
"Supports the SAML Source search: when true, if there is no certificate in the current form and there is one and only one certificate in the Authentik database, use that certificate by default.",
},
},
};
export default metadata;
const LIGHT = "pf-t-light";
function injectTheme() {
setTimeout(() => {
if (!document.body.classList.contains(LIGHT)) {
document.body.classList.add(LIGHT);
}
});
}
const container = (testItem: TemplateResult) => {
injectTheme();
return html` <div style="background: #fff; padding: 2em">
<style>
li {
display: block;
}
p {
margin-top: 1em;
}
</style>
<ak-message-container></ak-message-container>
${testItem}
<pre id="message-pad" style="margin-top: 1em"></pre>
</div>`;
};
export const CryptoCertificateSearch = () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const showMessage = (ev: CustomEvent<any>) => {
const detail = ev.detail;
delete detail["target"];
document.getElementById("message-pad")!.innerText = `Event: ${JSON.stringify(
detail,
null,
2,
)}`;
};
return container(
html` <ak-form-element-horizontal name="test-crypto-certificate-search">
<ak-crypto-certificate-search @ak-change=${showMessage}></ak-crypto-certificate-search
></ak-form-element-horizontal>`,
);
};

View File

@ -0,0 +1,29 @@
export const dummyCryptoCertsSearch = {
pagination: {
next: 0,
previous: 0,
count: 1,
current: 1,
total_pages: 1,
start_index: 1,
end_index: 1,
},
results: [
{
pk: "63efd1b8-6c39-4f65-8157-9a406cb37447",
name: "authentik Self-signed Certificate",
fingerprint_sha256: null,
fingerprint_sha1: null,
cert_expiry: null,
cert_subject: null,
private_key_available: true,
private_key_type: null,
certificate_download_url:
"/api/v3/crypto/certificatekeypairs/63efd1b8-6c39-4f65-8157-9a406cb37447/view_certificate/?download",
private_key_download_url:
"/api/v3/crypto/certificatekeypairs/63efd1b8-6c39-4f65-8157-9a406cb37447/view_private_key/?download",
managed: null,
},
],
};

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/elements/forms/HorizontalFormElement";
@ -9,13 +10,7 @@ import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
CertificateKeyPair,
CryptoApi,
CryptoCertificatekeypairsListRequest,
DockerServiceConnection,
OutpostsApi,
} from "@goauthentik/api";
import { DockerServiceConnection, OutpostsApi } from "@goauthentik/api";
@customElement("ak-service-connection-docker-form")
export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnection, string> {
@ -93,33 +88,9 @@ export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnecti
label=${msg("TLS Verification Certificate")}
name="tlsVerification"
>
<ak-search-select
.fetchObjects=${async (query?: string): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return this.instance?.tlsVerification === item.pk;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.tlsVerification}
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">
${msg(
"CA which the endpoint's Certificate is verified against. Can be left empty for no validation.",
@ -130,33 +101,9 @@ export class ServiceConnectionDockerForm extends ModelForm<DockerServiceConnecti
label=${msg("TLS Authentication Certificate/SSH Keypair")}
name="tlsAuthentication"
>
<ak-search-select
.fetchObjects=${async (query?: string): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return this.instance?.tlsAuthentication === item.pk;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.tlsAuthentication}
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">
${msg(
"Certificate/Key used for authentication. Can be left empty for no authentication.",

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
@ -14,11 +15,8 @@ import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
CertificateKeyPair,
CoreApi,
CoreGroupsListRequest,
CryptoApi,
CryptoCertificatekeypairsListRequest,
FlowsInstancesListDesignationEnum,
Group,
LDAPAPIAccessMode,
@ -208,35 +206,9 @@ export class LDAPProviderFormPage extends ModelForm<LDAPProvider, number> {
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Certificate")} name="certificate">
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.certificate;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.certificate}
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">
${msg(
"The certificate for the above configured Base DN. As a fallback, the provider uses a self-signed certificate.",

View File

@ -247,11 +247,10 @@ export class OAuth2ProviderFormPage extends ModelForm<OAuth2Provider, number> {
<ak-form-element-horizontal label=${msg("Signing Key")} name="signingKey">
<ak-crypto-certificate-search
certificate=${ifDefined(provider?.signingKey ?? nothing)}
name="certificate"
certificate=${ifDefined(this.instance?.signingKey ?? undefined)}
singleton
>
</ak-crypto-certificate-search>
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">${msg("Key used to sign the tokens.")}</p>
</ak-form-element-horizontal>
</div>

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
@ -18,9 +19,6 @@ import PFList from "@patternfly/patternfly/components/List/list.css";
import PFSpacing from "@patternfly/patternfly/utilities/Spacing/spacing.css";
import {
CertificateKeyPair,
CryptoApi,
CryptoCertificatekeypairsListRequest,
FlowsInstancesListDesignationEnum,
PaginatedOAuthSourceList,
PaginatedScopeMappingList,
@ -103,7 +101,6 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
>
</ak-text-input>
<<<<<<< HEAD
<ak-text-input
name="basicAuthPasswordAttribute"
label=${msg("HTTP-Basic Password Key")}
@ -112,7 +109,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
"User/Group Attribute used for the password part of the HTTP-Basic Header.",
)}
>
</ak-text-input>`;
</ak-text-input>`;
}
renderModeSelector(): TemplateResult {
@ -308,26 +305,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
</ak-form-element-horizontal>
<div class="pf-c-card pf-m-selectable pf-m-selected">
<<<<<<< HEAD
<div class="pf-c-card__body">
<ak-toggle-group
value=${this.mode}
@ak-toggle=${(ev: CustomEvent<{ value: ProxyMode }>) => {
this.mode = ev.detail.value;
}}
>
<option value=${ProxyMode.Proxy}>${msg("Proxy")}</option>
<option value=${ProxyMode.ForwardSingle}>
${msg("Forward auth (single application)")}
</option>
<option value=${ProxyMode.ForwardDomain}>
${msg("Forward auth (domain level)")}
</option>
</ak-toggle-group>
</div>
=======
<div class="pf-c-card__body">${this.renderModeSelector()}</div>
>>>>>>> ak-toggle-group
<div class="pf-c-card__footer">${this.renderSettings()}</div>
</div>
<ak-form-element-horizontal label=${msg("Token validity")} name="accessTokenValidity">
@ -346,35 +324,9 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
<span slot="header">${msg("Advanced protocol settings")}</span>
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal label=${msg("Certificate")} name="certificate">
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.certificate;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.certificate}
></ak-crypto-certificate-search>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Additional scopes")}

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import "@goauthentik/elements/forms/FormGroup";
@ -13,9 +14,6 @@ import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
CertificateKeyPair,
CryptoApi,
CryptoCertificatekeypairsListRequest,
DigestAlgorithmEnum,
FlowsInstancesListDesignationEnum,
PaginatedSAMLPropertyMappingList,
@ -177,35 +175,9 @@ export class SAMLProviderFormPage extends ModelForm<SAMLProvider, number> {
label=${msg("Signing Certificate")}
name="signingKp"
>
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.signingKp;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.signingKp}
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">
${msg(
"Certificate used to sign outgoing Responses going to the Service Provider.",
@ -216,41 +188,16 @@ export class SAMLProviderFormPage extends ModelForm<SAMLProvider, number> {
label=${msg("Verification Certificate")}
name="verificationKp"
>
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.verificationKp;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.verificationKp}
nokey
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">
${msg(
"When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.",
)}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Property mappings")}
?required=${true}

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import { placeholderHelperText } from "@goauthentik/admin/helperText";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
@ -12,11 +13,8 @@ import { customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import {
CertificateKeyPair,
CoreApi,
CoreGroupsListRequest,
CryptoApi,
CryptoCertificatekeypairsListRequest,
Group,
LDAPSource,
LDAPSourceRequest,
@ -208,34 +206,10 @@ export class LDAPSourceForm extends ModelForm<LDAPSource, string> {
label=${msg("TLS Verification Certificate")}
name="peerCertificate"
>
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.peerCertificate;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.peerCertificate}
nokey
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">
${msg(
"When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate.",
@ -246,35 +220,9 @@ export class LDAPSourceForm extends ModelForm<LDAPSource, string> {
label=${msg("TLS Client authentication certificate")}
name="clientCertificate"
>
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.clientCertificate;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.clientCertificate}
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">
${msg(
"Client certificate keypair to authenticate against the LDAP Server's Certificate.",

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-source-flow-search";
import { iconHelperText, placeholderHelperText } from "@goauthentik/admin/helperText";
import { UserMatchingModeToLabel } from "@goauthentik/admin/sources/oauth/utils";
@ -18,9 +19,6 @@ import { ifDefined } from "lit/directives/if-defined.js";
import {
BindingTypeEnum,
CapabilitiesEnum,
CertificateKeyPair,
CryptoApi,
CryptoCertificatekeypairsListRequest,
DigestAlgorithmEnum,
FlowsInstancesListDesignationEnum,
NameIdPolicyEnum,
@ -274,35 +272,9 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
</ak-radio>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Signing keypair")} name="signingKp">
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.signingKp;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.signingKp}
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">
${msg(
"Keypair which is used to sign outgoing requests. Leave empty to disable signing.",
@ -313,34 +285,10 @@ export class SAMLSourceForm extends ModelForm<SAMLSource, string> {
label=${msg("Verification Certificate")}
name="verificationKp"
>
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.verificationKp;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.verificationKp}
nokey
></ak-crypto-certificate-search>
<p class="pf-c-form__helper-text">
${msg(
"When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.",

View File

@ -1,3 +1,4 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
@ -13,14 +14,7 @@ import { msg } from "@lit/localize";
import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js";
import {
CertificateKeyPair,
CoreApi,
CryptoApi,
CryptoCertificatekeypairsListRequest,
FlowsInstancesListDesignationEnum,
Tenant,
} from "@goauthentik/api";
import { CoreApi, FlowsInstancesListDesignationEnum, Tenant } from "@goauthentik/api";
@customElement("ak-tenant-form")
export class TenantForm extends ModelForm<Tenant, string> {
@ -236,35 +230,9 @@ export class TenantForm extends ModelForm<Tenant, string> {
label=${msg("Web Certificate")}
name="webCertificate"
>
<ak-search-select
.fetchObjects=${async (
query?: string,
): Promise<CertificateKeyPair[]> => {
const args: CryptoCertificatekeypairsListRequest = {
ordering: "name",
hasKey: true,
includeDetails: false,
};
if (query !== undefined) {
args.search = query;
}
const certificates = await new CryptoApi(
DEFAULT_CONFIG,
).cryptoCertificatekeypairsList(args);
return certificates.results;
}}
.renderElement=${(item: CertificateKeyPair): string => {
return item.name;
}}
.value=${(item: CertificateKeyPair | undefined): string | undefined => {
return item?.pk;
}}
.selected=${(item: CertificateKeyPair): boolean => {
return item.pk === this.instance?.webCertificate;
}}
?blankable=${true}
>
</ak-search-select>
<ak-crypto-certificate-search
certificate=${this.instance?.webCertificate}
></ak-crypto-certificate-search>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Event retention")}