root: Multi-tenancy (#7590)

* tenants -> brands, init new tenant model, migrate some config to tenants

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* setup logging for tenants

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* configure celery and cache

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* small fixes, runs

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* task fixes, creation of tenant now works by cloning a template schema, some other small stuff

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix-tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* upstream fixes

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix-pylint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix avatar tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* migrate config reputation_expiry as well

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix web rebase

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix migrations for template schema

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix migrations for template schema

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix migrations for template schema 3

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* revert reputation expiry migration

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix type

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix some more tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* website: tenants -> brands

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* try fixing e2e tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* start frontend :help:

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* add ability to disable tenants api

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* delete embedded outpost if it is disabled

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* make sure embedded outpost is disabled when tenants are enabled

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* management commands: add --schema option where relevant

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* store files per-tenant

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix embedded outpost deletion

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix files migration

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* add tenant api tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* add domain tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* add settings tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* make --schema-name default to public in mgmt commands

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* sources/ldap: make sure lock is per-tenant

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix stuff I broke

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix remaining failing tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* try fixing e2e tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* much better frontend, but save does not refresh form properly

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* update django-tenants with latest fixes

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* i18n-extract

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* review comments

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* move event_retention from brands to tenants

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* wip

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* root: add support for storing media files in S3

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* use permissions for settings api

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* blueprints: disable tenants management

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix embedded outpost create/delete logic

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* make gen

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* make sure prometheus metrics are correctly served

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* makefile: don't delete the go api client when not regenerating it

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* tenants api: add recovery group and token creation endpoints

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix startup

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix prometheus metrics

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix web stuff

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

* fix migrations from stable

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix oauth source type import

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

* Revert "fix oauth source type import"

This reverts commit d015fd0244.

* try with setting_changed signal

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* try with connection_created signal

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix scim tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix web after merge

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix enterprise settings

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* Revert "try with connection_created signal"

This reverts commit 764a999db8.

* Revert "try with setting_changed signal"

This reverts commit 32b40a3bbb.

* lib/expression: refactor expression compilation

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix django version

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix web after merge

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* relock poetry

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix reconcile

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* try running tenant save in a transaction

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* black

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* test: export postgres logs for debugging and use failfast

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

* test: fix container name for logs

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

* do not copy tenant data

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* Revert "try running tenant save in a transaction"

This reverts commit da6dec5a61.

* Revert "do not copy tenant data"

This reverts commit d07ae9423672f068b0bd8be409ff9b58452a80f2.

* Revert "Revert "do not copy tenant data""

This reverts commit 4bffb19704.

* fix clone with nodata

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* why not

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* remove failfast

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

* remove postgres query logging

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

* update reconcile logic to clearly differentiate between tenant and global

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix

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

* fix reconcile app decorator

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* enable django checks

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* actually nodata was unnecessary as we're cloning from template and not from public

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* pylint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* update django-tenants with sequence fix

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* actually update

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix e2e tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* add tests for settings api

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* add tests for recovery api

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* recovery tests: do them on a new tenant

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* web: fix system status being degraded when embedded outpost is disabled

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix recovery tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix tenants tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint-fix

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint-fix

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* update UI

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

* add management command to create a tenant

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

* add docs

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* release notes

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* more docs

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* checklist

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* self review

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* spelling

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* make web after upgrading

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* remove extra xlif file

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* prettier

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* Revert "add management command to create a tenant"

This reverts commit 39d13c0447.

* split api into smaller files, only import urls when tenants is enabled

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

* rewite some things on the release notes

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

* root: make sure install_id comes from public schema

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* require a license to use tenants

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* lint

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix tenants tests

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* fix files migration

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* release notes: add warning about user sessions being invalidated

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* remove api disabled test, we can't test for it

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

---------

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Marc 'risson' Schmitt
2024-01-23 14:28:06 +01:00
committed by GitHub
parent 73ddaf48be
commit abc0c2d2a2
227 changed files with 6554 additions and 2481 deletions

View File

@ -139,9 +139,10 @@ export class AkAdminSidebar extends WithCapabilitiesConfig(AKElement) {
["/core/tokens", msg("Tokens and App passwords")],
["/flow/stages/invitations", msg("Invitations")]]],
[null, msg("System"), null, [
["/core/tenants", msg("Tenants")],
["/core/brands", msg("Brands")],
["/crypto/certificates", msg("Certificates")],
["/outpost/integrations", msg("Outpost Integrations")]]]
["/outpost/integrations", msg("Outpost Integrations")],
["/admin/settings", msg("Settings")]]],
];
// Typescript requires the type here to correctly type the recursive path

View File

@ -52,9 +52,9 @@ export const ROUTES: Route[] = [
await import("@goauthentik/admin/tokens/TokenListPage");
return html`<ak-token-list></ak-token-list>`;
}),
new Route(new RegExp("^/core/tenants$"), async () => {
await import("@goauthentik/admin/tenants/TenantListPage");
return html`<ak-tenant-list></ak-tenant-list>`;
new Route(new RegExp("^/core/brands"), async () => {
await import("@goauthentik/admin/brands/BrandListPage");
return html`<ak-brand-list></ak-brand-list>`;
}),
new Route(new RegExp("^/policy/policies$"), async () => {
await import("@goauthentik/admin/policies/PolicyListPage");
@ -136,6 +136,10 @@ export const ROUTES: Route[] = [
await import("@goauthentik/admin/crypto/CertificateKeyPairListPage");
return html`<ak-crypto-certificate-list></ak-crypto-certificate-list>`;
}),
new Route(new RegExp("^/admin/settings$"), async () => {
await import("@goauthentik/admin/admin-settings/AdminSettingsPage");
return html`<ak-admin-settings></ak-admin-settings>`;
}),
new Route(new RegExp("^/blueprints/instances$"), async () => {
await import("@goauthentik/admin/blueprints/BlueprintListPage");
return html`<ak-blueprint-list></ak-blueprint-list>`;

View File

@ -57,7 +57,7 @@ export class RecentEventsCard extends Table<Event> {
new TableColumn(msg("User"), "user"),
new TableColumn(msg("Creation Date"), "created"),
new TableColumn(msg("Client IP"), "client_ip"),
new TableColumn(msg("Tenant"), "tenant_name"),
new TableColumn(msg("Brand"), "brand_name"),
];
}
@ -88,7 +88,7 @@ export class RecentEventsCard extends Table<Event> {
html`<span>${item.created?.toLocaleString()}</span>`,
html` <div>${item.clientIp || msg("-")}</div>
<small>${EventGeo(item)}</small>`,
html`<span>${item.tenant?.name || msg("-")}</span>`,
html`<span>${item.brand?.name || msg("-")}</span>`,
];
}

View File

@ -22,7 +22,10 @@ export class SystemStatusCard extends AdminStatusCard<SystemInfo> {
async getPrimaryValue(): Promise<SystemInfo> {
this.now = new Date();
let status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
if (status.embeddedOutpostHost === "" || !status.embeddedOutpostHost.includes("http")) {
if (
!status.embeddedOutpostDisabled &&
(status.embeddedOutpostHost === "" || !status.embeddedOutpostHost.includes("http"))
) {
// First install, ensure the embedded outpost host is set
// also run when outpost host does not contain http
// (yes it's called host and requires a URL, i know)
@ -51,7 +54,7 @@ export class SystemStatusCard extends AdminStatusCard<SystemInfo> {
}
getStatus(value: SystemInfo): Promise<AdminStatus> {
if (value.embeddedOutpostHost === "") {
if (!value.embeddedOutpostDisabled && value.embeddedOutpostHost === "") {
this.statusSummary = msg("Warning");
return Promise.resolve<AdminStatus>({
icon: "fa fa-exclamation-triangle pf-m-warning",

View File

@ -0,0 +1,187 @@
import { first } from "@goauthentik/app/common/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import "@goauthentik/components/ak-switch-input";
import "@goauthentik/components/ak-text-input";
import "@goauthentik/elements/CodeMirror";
import { CodeMirrorMode } from "@goauthentik/elements/CodeMirror";
import { Form } from "@goauthentik/elements/forms/Form";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
import "@goauthentik/elements/forms/Radio";
import "@goauthentik/elements/forms/SearchSelect";
import "@goauthentik/elements/utils/TimeDeltaHelp";
import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import PFList from "@patternfly/patternfly/components/List/list.css";
import { AdminApi, Settings, SettingsRequest } from "@goauthentik/api";
@customElement("ak-admin-settings-form")
export class AdminSettingsForm extends Form<SettingsRequest> {
@property({ attribute: false })
set settings(value: Settings) {
this._settings = value;
}
private _settings?: Settings;
getSuccessMessage(): string {
return msg("Successfully updated settings.");
}
async send(data: SettingsRequest): Promise<Settings> {
return new AdminApi(DEFAULT_CONFIG).adminSettingsUpdate({
settingsRequest: data,
});
}
static get styles(): CSSResult[] {
return super.styles.concat(PFList);
}
renderForm(): TemplateResult {
return html`
<ak-text-input
name="avatars"
label=${msg("Avatars")}
value="${ifDefined(this._settings?.avatars)}"
.bighelp=${html`
<p class="pf-c-form__helper-text">
${msg(
"Configure how authentik should show avatars for users. The following values can be set:",
)}
</p>
<ul class="pf-c-list">
<li class="pf-c-form__helper-text">
<code>none</code>:
${msg(
"Disables per-user avatars and just shows a 1x1 pixel transparent picture",
)}
</li>
<li class="pf-c-form__helper-text">
<code>gravatar</code>:
${msg("Uses gravatar with the user's email address")}
</li>
<li class="pf-c-form__helper-text">
<code>initials</code>:
${msg("Generated avatars based on the user's name")}
</li>
<li class="pf-c-form__helper-text">
${msg(
"Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:",
)}
<ul class="pf-c-list">
<li class="pf-c-form__helper-text">
<code>%(username)s</code>: ${msg("The user's username")}
</li>
<li class="pf-c-form__helper-text">
<code>%(mail_hash)s</code>:
${msg("The email address, md5 hashed")}
</li>
<li class="pf-c-form__helper-text">
<code>%(upn)s</code>:
${msg("The user's UPN, if set (otherwise an empty string)")}
</li>
</ul>
</li>
<li class="pf-c-form__helper-text">
${msg(
html`An attribute path like
<code>attributes.something.avatar</code>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.`,
)}
</li>
</ul>
<p class="pf-c-form__helper-text">
${msg(
"Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.",
)}
${msg(
html`For example, setting this to <code>gravatar,initials</code> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.`,
)}
</p>
`}
required
>
</ak-text-input>
<ak-switch-input
name="defaultUserChangeName"
label=${msg("Allow users to change name")}
?checked="${this._settings?.defaultUserChangeName}"
help=${msg("Enable the ability for users to change their name.")}
>
</ak-switch-input>
<ak-switch-input
name="defaultUserChangeEmail"
label=${msg("Allow users to change email")}
?checked="${this._settings?.defaultUserChangeEmail}"
help=${msg("Enable the ability for users to change their email.")}
>
</ak-switch-input>
<ak-switch-input
name="defaultUserChangeUsername"
label=${msg("Allow users to change username")}
?checked="${this._settings?.defaultUserChangeUsername}"
help=${msg("Enable the ability for users to change their username.")}
>
</ak-switch-input>
<ak-text-input
name="eventRetention"
label=${msg("Event retention")}
required
value="${ifDefined(this._settings?.eventRetention)}"
.bighelp=${html`<p class="pf-c-form__helper-text">
${msg("Duration after which events will be deleted from the database.")}
</p>
<p class="pf-c-form__helper-text">
${msg(
'When using an external logging solution for archiving, this can be set to "minutes=5".',
)}
</p>
<p class="pf-c-form__helper-text">
${msg(
"This setting only affects new Events, as the expiration is saved per-event.",
)}
</p>
<ak-utils-time-delta-help></ak-utils-time-delta-help>`}
>
</ak-text-input>
<ak-form-element-horizontal label=${msg("Footer links")} name="footerLinks">
<ak-codemirror
mode=${CodeMirrorMode.YAML}
.parseValue=${false}
value="${first(this._settings?.footerLinks, [])}"
></ak-codemirror>
<p class="pf-c-form__helper-text">
${msg(
"This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:",
)}
<code>[{"name": "Link Name","href":"https://goauthentik.io"}]</code>
</p>
</ak-form-element-horizontal>
<ak-switch-input
name="gdprCompliance"
label=${msg("GDPR compliance")}
?checked="${this._settings?.gdprCompliance}"
help=${msg(
"When enabled, all the events caused by a user will be deleted upon the user's deletion.",
)}
>
</ak-switch-input>
<ak-switch-input
name="impersonation"
label=${msg("Impersonation")}
?checked="${this._settings?.impersonation}"
help=${msg("Globally enable/disable impersonation.")}
>
</ak-switch-input>
`;
}
}

View File

@ -0,0 +1,115 @@
import "@goauthentik/admin/admin-settings/AdminSettingsForm";
import { AdminSettingsForm } from "@goauthentik/admin/admin-settings/AdminSettingsForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import "@goauthentik/components/events/ObjectChangelog";
import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/CodeMirror";
import "@goauthentik/elements/EmptyState";
import "@goauthentik/elements/Markdown";
import "@goauthentik/elements/PageHeader";
import "@goauthentik/elements/Tabs";
import "@goauthentik/elements/buttons/ModalButton";
import "@goauthentik/elements/buttons/SpinnerButton";
import "@goauthentik/elements/buttons/SpinnerButton";
import "@goauthentik/elements/forms/ModalForm";
import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import PFBanner from "@patternfly/patternfly/components/Banner/banner.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFCard from "@patternfly/patternfly/components/Card/card.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { AdminApi, Settings } from "@goauthentik/api";
@customElement("ak-admin-settings")
export class AdminSettingsPage extends AKElement {
static get styles(): CSSResult[] {
return [
PFBase,
PFButton,
PFPage,
PFGrid,
PFContent,
PFCard,
PFDescriptionList,
PFForm,
PFFormControl,
PFBanner,
];
}
@property({ attribute: false })
settings?: Settings;
loadSettings(): void {
new AdminApi(DEFAULT_CONFIG).adminSettingsRetrieve().then((settings) => {
this.settings = settings;
});
}
firstUpdated(): void {
this.loadSettings();
}
async save(): Promise<void> {
const form = this.shadowRoot?.querySelector<AdminSettingsForm>("ak-admin-settings-form");
if (!form) {
return;
}
await form.submit(new Event("submit"));
this.resetForm();
}
resetForm(): void {
const form = this.shadowRoot?.querySelector<AdminSettingsForm>("ak-admin-settings-form");
if (!form) {
return;
}
this.loadSettings();
form.settings = this.settings!;
form.resetForm();
}
render(): TemplateResult {
if (!this.settings) {
return html``;
}
return html`
<ak-page-header icon="fa fa-cog" header="" description="">
<span slot="header"> ${msg("System settings")} </span>
</ak-page-header>
<section class="pf-c-page__main-section pf-m-no-padding-mobile pf-l-grid pf-m-gutter">
<div class="pf-c-card">
<div class="pf-c-card__body">
<ak-admin-settings-form id="form" .settings=${this.settings}>
</ak-admin-settings-form>
</div>
<div class="pf-c-card__footer">
<ak-spinner-button
.callAction=${async () => {
await this.save();
}}
class="pf-m-primary"
>${msg("Save")}</ak-spinner-button
>
<ak-spinner-button
.callAction=${() => {
this.resetForm();
}}
class="pf-m-secondary"
>${msg("Cancel")}</ak-spinner-button
>
</div>
</div>
</section>
`;
}
}

View File

@ -1,13 +1,13 @@
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
import "@goauthentik/admin/common/ak-core-group-search";
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-number-input";
import "@goauthentik/components/ak-radio-input";
import "@goauthentik/components/ak-switch-input";
import "@goauthentik/components/ak-text-input";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
@ -32,7 +32,7 @@ import {
} from "./LDAPOptionsAndHelp";
@customElement("ak-application-wizard-authentication-by-ldap")
export class ApplicationWizardApplicationDetails extends WithTenantConfig(BaseProviderPanel) {
export class ApplicationWizardApplicationDetails extends WithBrandConfig(BaseProviderPanel) {
render() {
const provider = this.wizard.provider as LDAPProvider | undefined;
const errors = this.wizard.errors.provider;
@ -54,12 +54,12 @@ export class ApplicationWizardApplicationDetails extends WithTenantConfig(BasePr
name="authorizationFlow"
.errorMessages=${errors?.authorizationFlow ?? []}
>
<ak-tenanted-flow-search
<ak-branded-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${provider?.authorizationFlow}
.tenantFlow=${this.tenant.flowAuthentication}
.brandFlow=${this.brand.flowAuthentication}
required
></ak-tenanted-flow-search>
></ak-branded-flow-search>
<p class="pf-c-form__helper-text">
${msg("Flow used for users to authenticate.")}
</p>

View File

@ -1,6 +1,6 @@
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
import {
clientTypeOptions,
issuerModeOptions,

View File

@ -1,9 +1,9 @@
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-text-input";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
@ -17,7 +17,7 @@ import { FlowsInstancesListDesignationEnum, RadiusProvider } from "@goauthentik/
import BaseProviderPanel from "../BaseProviderPanel";
@customElement("ak-application-wizard-authentication-by-radius")
export class ApplicationWizardAuthenticationByRadius extends WithTenantConfig(BaseProviderPanel) {
export class ApplicationWizardAuthenticationByRadius extends WithBrandConfig(BaseProviderPanel) {
render() {
const provider = this.wizard.provider as RadiusProvider | undefined;
const errors = this.wizard.errors.provider;
@ -39,12 +39,12 @@ export class ApplicationWizardAuthenticationByRadius extends WithTenantConfig(Ba
name="authorizationFlow"
.errorMessages=${errors?.authorizationFlow ?? []}
>
<ak-tenanted-flow-search
<ak-branded-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${provider?.authorizationFlow}
.tenantFlow=${this.tenant.flowAuthentication}
.brandFlow=${this.brand.flowAuthentication}
required
></ak-tenanted-flow-search>
></ak-branded-flow-search>
<p class="pf-c-form__helper-text">
${msg("Flow used for users to authenticate.")}
</p>

View File

@ -2,7 +2,7 @@ import "@goauthentik/admin/applications/wizard/ak-wizard-title";
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
import "@goauthentik/admin/common/ak-core-group-search";
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import "@goauthentik/components/ak-multi-select";
import "@goauthentik/components/ak-number-input";

View File

@ -1,7 +1,7 @@
import "@goauthentik/admin/applications/wizard/ak-wizard-title";
import "@goauthentik/admin/common/ak-core-group-search";
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-multi-select";

View File

@ -8,38 +8,38 @@ import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
import "@goauthentik/elements/forms/SearchSelect";
import { DefaultTenant } from "@goauthentik/elements/sidebar/SidebarBrand";
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
import YAML from "yaml";
import { msg } from "@lit/localize";
import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js";
import { CoreApi, FlowsInstancesListDesignationEnum, Tenant } from "@goauthentik/api";
import { Brand, CoreApi, FlowsInstancesListDesignationEnum } from "@goauthentik/api";
@customElement("ak-tenant-form")
export class TenantForm extends ModelForm<Tenant, string> {
loadInstance(pk: string): Promise<Tenant> {
return new CoreApi(DEFAULT_CONFIG).coreTenantsRetrieve({
tenantUuid: pk,
@customElement("ak-brand-form")
export class BrandForm extends ModelForm<Brand, string> {
loadInstance(pk: string): Promise<Brand> {
return new CoreApi(DEFAULT_CONFIG).coreBrandsRetrieve({
brandUuid: pk,
});
}
getSuccessMessage(): string {
return this.instance
? msg("Successfully updated tenant.")
: msg("Successfully created tenant.");
? msg("Successfully updated brand.")
: msg("Successfully created brand.");
}
async send(data: Tenant): Promise<Tenant> {
if (this.instance?.tenantUuid) {
return new CoreApi(DEFAULT_CONFIG).coreTenantsUpdate({
tenantUuid: this.instance.tenantUuid,
tenantRequest: data,
async send(data: Brand): Promise<Brand> {
if (this.instance?.brandUuid) {
return new CoreApi(DEFAULT_CONFIG).coreBrandsUpdate({
brandUuid: this.instance.brandUuid,
brandRequest: data,
});
} else {
return new CoreApi(DEFAULT_CONFIG).coreTenantsCreate({
tenantRequest: data,
return new CoreApi(DEFAULT_CONFIG).coreBrandsCreate({
brandRequest: data,
});
}
}
@ -77,7 +77,7 @@ export class TenantForm extends ModelForm<Tenant, string> {
<span class="pf-c-switch__label">${msg("Default")}</span>
</label>
<p class="pf-c-form__helper-text">
${msg("Use this tenant for each domain that doesn't have a dedicated tenant.")}
${msg("Use this brand for each domain that doesn't have a dedicated brand.")}
</p>
</ak-form-element-horizontal>
@ -93,7 +93,7 @@ export class TenantForm extends ModelForm<Tenant, string> {
type="text"
value="${first(
this.instance?.brandingTitle,
DefaultTenant.brandingTitle,
DefaultBrand.brandingTitle,
)}"
class="pf-c-form-control"
required
@ -109,10 +109,7 @@ export class TenantForm extends ModelForm<Tenant, string> {
>
<input
type="text"
value="${first(
this.instance?.brandingLogo,
DefaultTenant.brandingLogo,
)}"
value="${first(this.instance?.brandingLogo, DefaultBrand.brandingLogo)}"
class="pf-c-form-control"
required
/>
@ -129,7 +126,7 @@ export class TenantForm extends ModelForm<Tenant, string> {
type="text"
value="${first(
this.instance?.brandingFavicon,
DefaultTenant.brandingFavicon,
DefaultBrand.brandingFavicon,
)}"
class="pf-c-form-control"
required
@ -236,34 +233,6 @@ export class TenantForm extends ModelForm<Tenant, string> {
.certificate=${this.instance?.webCertificate}
></ak-crypto-certificate-search>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${msg("Event retention")}
?required=${true}
name="eventRetention"
>
<input
type="text"
value="${first(this.instance?.eventRetention, "days=365")}"
class="pf-c-form-control"
required
/>
<p class="pf-c-form__helper-text">
${msg("Duration after which events will be deleted from the database.")}
</p>
<p class="pf-c-form__helper-text">
${msg(
'When using an external logging solution for archiving, this can be set to "minutes=5".',
)}
</p>
<p class="pf-c-form__helper-text">
${msg(
"This setting only affects new Events, as the expiration is saved per-event.",
)}
</p>
<p class="pf-c-form__helper-text">
${msg('Format: "weeks=3;days=2;hours=3,seconds=2".')}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Attributes")} name="attributes">
<ak-codemirror
mode=${CodeMirrorMode.YAML}
@ -272,7 +241,7 @@ export class TenantForm extends ModelForm<Tenant, string> {
</ak-codemirror>
<p class="pf-c-form__helper-text">
${msg(
"Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.",
"Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.",
)}
</p>
</ak-form-element-horizontal>

View File

@ -1,4 +1,4 @@
import "@goauthentik/admin/tenants/TenantForm";
import "@goauthentik/admin/brands/BrandForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { uiConfig } from "@goauthentik/common/ui/config";
import "@goauthentik/components/ak-status-label";
@ -16,21 +16,21 @@ import { msg } from "@lit/localize";
import { TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { CoreApi, RbacPermissionsAssignedByUsersListModelEnum, Tenant } from "@goauthentik/api";
import { Brand, CoreApi, RbacPermissionsAssignedByUsersListModelEnum } from "@goauthentik/api";
@customElement("ak-tenant-list")
export class TenantListPage extends TablePage<Tenant> {
@customElement("ak-brand-list")
export class BrandListPage extends TablePage<Brand> {
searchEnabled(): boolean {
return true;
}
pageTitle(): string {
return msg("Tenants");
return msg("Brands");
}
pageDescription(): string {
return msg("Configure visual settings and defaults for different domains.");
}
pageIcon(): string {
return "pf-icon pf-icon-tenant";
return "pf-icon pf-icon-brand";
}
checkbox = true;
@ -38,8 +38,8 @@ export class TenantListPage extends TablePage<Tenant> {
@property()
order = "domain";
async apiEndpoint(page: number): Promise<PaginatedResponse<Tenant>> {
return new CoreApi(DEFAULT_CONFIG).coreTenantsList({
async apiEndpoint(page: number): Promise<PaginatedResponse<Brand>> {
return new CoreApi(DEFAULT_CONFIG).coreBrandsList({
ordering: this.order,
page: page,
pageSize: (await uiConfig()).pagination.perPage,
@ -58,19 +58,19 @@ export class TenantListPage extends TablePage<Tenant> {
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html`<ak-forms-delete-bulk
objectLabel=${msg("Tenant(s)")}
objectLabel=${msg("Brand(s)")}
.objects=${this.selectedElements}
.metadata=${(item: Tenant) => {
.metadata=${(item: Brand) => {
return [{ key: msg("Domain"), value: item.domain }];
}}
.usedBy=${(item: Tenant) => {
return new CoreApi(DEFAULT_CONFIG).coreTenantsUsedByList({
tenantUuid: item.tenantUuid,
.usedBy=${(item: Brand) => {
return new CoreApi(DEFAULT_CONFIG).coreBrandsUsedByList({
brandUuid: item.brandUuid,
});
}}
.delete=${(item: Tenant) => {
return new CoreApi(DEFAULT_CONFIG).coreTenantsDestroy({
tenantUuid: item.tenantUuid,
.delete=${(item: Brand) => {
return new CoreApi(DEFAULT_CONFIG).coreBrandsDestroy({
brandUuid: item.brandUuid,
});
}}
>
@ -80,14 +80,14 @@ export class TenantListPage extends TablePage<Tenant> {
</ak-forms-delete-bulk>`;
}
row(item: Tenant): TemplateResult[] {
row(item: Brand): TemplateResult[] {
return [
html`${item.domain}`,
html`<ak-status-label ?good=${item._default}></ak-status-label>`,
html`<ak-forms-modal>
<span slot="submit"> ${msg("Update")} </span>
<span slot="header"> ${msg("Update Tenant")} </span>
<ak-tenant-form slot="form" .instancePk=${item.tenantUuid}> </ak-tenant-form>
<span slot="header"> ${msg("Update Brand")} </span>
<ak-brand-form slot="form" .instancePk=${item.brandUuid}> </ak-brand-form>
<button slot="trigger" class="pf-c-button pf-m-plain">
<pf-tooltip position="top" content=${msg("Edit")}>
<i class="fas fa-edit"></i>
@ -96,8 +96,8 @@ export class TenantListPage extends TablePage<Tenant> {
</ak-forms-modal>
<ak-rbac-object-permission-modal
model=${RbacPermissionsAssignedByUsersListModelEnum.TenantsTenant}
objectPk=${item.tenantUuid}
model=${RbacPermissionsAssignedByUsersListModelEnum.BrandsBrand}
objectPk=${item.brandUuid}
>
</ak-rbac-object-permission-modal>`,
];
@ -107,8 +107,8 @@ export class TenantListPage extends TablePage<Tenant> {
return html`
<ak-forms-modal>
<span slot="submit"> ${msg("Create")} </span>
<span slot="header"> ${msg("Create Tenant")} </span>
<ak-tenant-form slot="form"> </ak-tenant-form>
<span slot="header"> ${msg("Create Brand")} </span>
<ak-brand-form slot="form"> </ak-brand-form>
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
</ak-forms-modal>
`;

View File

@ -28,7 +28,7 @@ export function getFlowValue(flow: Flow | undefined): string | undefined {
*
* A wrapper around SearchSelect that understands the basic semantics of querying about Flows. This
* code eliminates the long blocks of unreadable invocation that were embedded in every provider, as well as in
* sources, tenants, and applications.
* sources, brands, and applications.
*
*/
@ -93,7 +93,7 @@ export class FlowSearch<T extends Flow> extends CustomListenerElement(AKElement)
}
/* This is the most commonly overridden method of this class. About half of the Flow Searches
* use this method, but several have more complex needs, such as relating to the tenant, or just
* use this method, but several have more complex needs, such as relating to the brand, or just
* returning false.
*/

View File

@ -0,0 +1,34 @@
import { customElement, property } from "lit/decorators.js";
import type { Flow } from "@goauthentik/api";
import FlowSearch from "./FlowSearch";
/**
* Search for flows that may have a fallback specified by the brand settings
*
* @element ak-branded-flow-search
*
*/
@customElement("ak-branded-flow-search")
export class AkBrandedFlowSearch<T extends Flow> extends FlowSearch<T> {
/**
* The Associated ID of the flow the brand has, to compare if possible
*
* @attr
*/
@property({ attribute: false, type: String })
brandFlow?: string;
constructor() {
super();
this.selected = this.selected.bind(this);
}
selected(flow: Flow): boolean {
return super.selected(flow) || flow.pk === this.brandFlow;
}
}
export default AkBrandedFlowSearch;

View File

@ -1,34 +0,0 @@
import { customElement, property } from "lit/decorators.js";
import type { Flow } from "@goauthentik/api";
import FlowSearch from "./FlowSearch";
/**
* Search for flows that may have a fallback specified by the tenant settings
*
* @element ak-tenanted-flow-search
*
*/
@customElement("ak-tenanted-flow-search")
export class AkTenantedFlowSearch<T extends Flow> extends FlowSearch<T> {
/**
* The Associated ID of the flow the tenant has, to compare if possible
*
* @attr
*/
@property({ attribute: false, type: String })
tenantFlow?: string;
constructor() {
super();
this.selected = this.selected.bind(this);
}
selected(flow: Flow): boolean {
return super.selected(flow) || flow.pk === this.tenantFlow;
}
}
export default AkTenantedFlowSearch;

View File

@ -59,7 +59,7 @@ export class EventListPage extends TablePage<Event> {
new TableColumn(msg("User"), "user"),
new TableColumn(msg("Creation Date"), "created"),
new TableColumn(msg("Client IP"), "client_ip"),
new TableColumn(msg("Tenant"), "tenant_name"),
new TableColumn(msg("Brand"), "brand_name"),
new TableColumn(msg("Actions")),
];
}
@ -97,7 +97,7 @@ export class EventListPage extends TablePage<Event> {
html`<div>${item.clientIp || msg("-")}</div>
<small>${EventGeo(item)}</small>`,
html`<span>${item.tenant?.name || msg("-")}</span>`,
html`<span>${item.brand?.name || msg("-")}</span>`,
html`<a href="#/events/log/${item.pk}">
<pf-tooltip position="top" content=${msg("Show details")}>
<i class="fas fa-share-square"></i>

View File

@ -139,12 +139,12 @@ export class EventViewPage extends AKElement {
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text"
>${msg("Tenant")}</span
>${msg("Brand")}</span
>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
${this.event.tenant?.name || msg("-")}
${this.event.brand?.name || msg("-")}
</div>
</dd>
</div>

View File

@ -9,11 +9,11 @@ import { MessageLevel } from "@goauthentik/common/messages";
import { uiConfig } from "@goauthentik/common/ui/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-status-label";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import {
CapabilitiesEnum,
WithCapabilitiesConfig,
} from "@goauthentik/elements/Interface/capabilitiesProvider";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import "@goauthentik/elements/buttons/ActionButton";
import "@goauthentik/elements/buttons/Dropdown";
import "@goauthentik/elements/forms/DeleteBulkForm";
@ -110,7 +110,7 @@ export class RelatedUserAdd extends Form<{ users: number[] }> {
}
@customElement("ak-user-related-list")
export class RelatedUserList extends WithTenantConfig(WithCapabilitiesConfig(Table<User>)) {
export class RelatedUserList extends WithBrandConfig(WithCapabilitiesConfig(Table<User>)) {
expandable = true;
checkbox = true;
@ -295,7 +295,7 @@ export class RelatedUserList extends WithTenantConfig(WithCapabilitiesConfig(Tab
${msg("Set password")}
</button>
</ak-forms-modal>
${this.tenant?.flowRecovery
${this.brand?.flowRecovery
? html`
<ak-action-button
class="pf-m-secondary"
@ -357,7 +357,7 @@ export class RelatedUserList extends WithTenantConfig(WithCapabilitiesConfig(Tab
`
: html` <p>
${msg(
"To let a user directly reset a their password, configure a recovery flow on the currently active tenant.",
"To let a user directly reset a their password, configure a recovery flow on the currently active brand.",
)}
</p>`}
</div>

View File

@ -1,9 +1,9 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
import { BaseProviderForm } from "@goauthentik/admin/providers/BaseProviderForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { first } from "@goauthentik/common/utils";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
import "@goauthentik/elements/forms/Radio";
@ -25,7 +25,7 @@ import {
} from "@goauthentik/api";
@customElement("ak-provider-ldap-form")
export class LDAPProviderFormPage extends WithTenantConfig(BaseProviderForm<LDAPProvider>) {
export class LDAPProviderFormPage extends WithBrandConfig(BaseProviderForm<LDAPProvider>) {
async loadInstance(pk: number): Promise<LDAPProvider> {
return new ProvidersApi(DEFAULT_CONFIG).providersLdapRetrieve({
id: pk,
@ -48,7 +48,7 @@ export class LDAPProviderFormPage extends WithTenantConfig(BaseProviderForm<LDAP
// All Provider objects have an Authorization flow, but not all providers have an Authentication
// flow. LDAP needs only one field, but it is not an Authorization field, it is an
// Authentication field. So, yeah, we're using the authorization field to store the
// authentication information, which is why the ak-tenanted-flow-search call down there looks so
// authentication information, which is why the ak-branded-flow-search call down there looks so
// weird-- we're looking up Authentication flows, but we're storing them in the Authorization
// field of the target Provider.
renderForm(): TemplateResult {
@ -65,12 +65,12 @@ export class LDAPProviderFormPage extends WithTenantConfig(BaseProviderForm<LDAP
?required=${true}
name="authorizationFlow"
>
<ak-tenanted-flow-search
<ak-branded-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${this.instance?.authorizationFlow}
.tenantFlow=${this.tenant?.flowAuthentication}
.brandFlow=${this.brand?.flowAuthentication}
required
></ak-tenanted-flow-search>
></ak-branded-flow-search>
<p class="pf-c-form__helper-text">${msg("Flow used for users to authenticate.")}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${msg("Search group")} name="searchGroup">

View File

@ -1,5 +1,5 @@
import "@goauthentik/admin/common/ak-crypto-certificate-search";
import "@goauthentik/admin/common/ak-flow-search/ak-tenanted-flow-search";
import "@goauthentik/admin/common/ak-flow-search/ak-branded-flow-search";
import { first } from "@goauthentik/app/common/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import "@goauthentik/elements/CodeMirror";

View File

@ -1,7 +1,7 @@
import { BaseProviderForm } from "@goauthentik/admin/providers/BaseProviderForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { ascii_letters, digits, first, randomString } from "@goauthentik/common/utils";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
import "@goauthentik/elements/forms/SearchSelect";
@ -14,7 +14,7 @@ import { customElement } from "lit/decorators.js";
import { FlowsInstancesListDesignationEnum, ProvidersApi, RadiusProvider } from "@goauthentik/api";
@customElement("ak-provider-radius-form")
export class RadiusProviderFormPage extends WithTenantConfig(BaseProviderForm<RadiusProvider>) {
export class RadiusProviderFormPage extends WithBrandConfig(BaseProviderForm<RadiusProvider>) {
loadInstance(pk: number): Promise<RadiusProvider> {
return new ProvidersApi(DEFAULT_CONFIG).providersRadiusRetrieve({
id: pk,
@ -37,7 +37,7 @@ export class RadiusProviderFormPage extends WithTenantConfig(BaseProviderForm<Ra
// All Provider objects have an Authorization flow, but not all providers have an Authentication
// flow. Radius needs only one field, but it is not the Authorization field, it is an
// Authentication field. So, yeah, we're using the authorization field to store the
// authentication information, which is why the ak-tenanted-flow-search call down there looks so
// authentication information, which is why the ak-branded-flow-search call down there looks so
// weird-- we're looking up Authentication flows, but we're storing them in the Authorization
// field of the target Provider.
renderForm(): TemplateResult {
@ -54,12 +54,12 @@ export class RadiusProviderFormPage extends WithTenantConfig(BaseProviderForm<Ra
?required=${true}
name="authorizationFlow"
>
<ak-tenanted-flow-search
<ak-branded-flow-search
flowType=${FlowsInstancesListDesignationEnum.Authentication}
.currentFlow=${this.instance?.authorizationFlow}
.tenantFlow=${this.tenant?.flowAuthentication}
.brandFlow=${this.brand?.flowAuthentication}
required
></ak-tenanted-flow-search>
></ak-branded-flow-search>
<p class="pf-c-form__helper-text">${msg("Flow used for users to authenticate.")}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="mfaSupport">

View File

@ -28,7 +28,7 @@ class PreviewStageHost implements StageHost {
challenge = undefined;
flowSlug = undefined;
loading = false;
tenant = undefined;
brand = undefined;
async submit(payload: unknown): Promise<boolean> {
this.promptForm.previewResult = payload;
return false;

View File

@ -12,11 +12,11 @@ import { DefaultUIConfig, uiConfig } from "@goauthentik/common/ui/config";
import { first } from "@goauthentik/common/utils";
import "@goauthentik/components/ak-status-label";
import { rootInterface } from "@goauthentik/elements/Base";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import {
CapabilitiesEnum,
WithCapabilitiesConfig,
} from "@goauthentik/elements/Interface/capabilitiesProvider";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { PFSize } from "@goauthentik/elements/Spinner";
import "@goauthentik/elements/TreeView";
import "@goauthentik/elements/buttons/ActionButton";
@ -61,7 +61,7 @@ export const requestRecoveryLink = (user: User) =>
showMessage({
level: MessageLevel.error,
message: msg(
"The current tenant must have a recovery flow configured to use a recovery link",
"The current brand must have a recovery flow configured to use a recovery link",
),
}),
),
@ -91,7 +91,7 @@ const recoveryButtonStyles = css`
`;
@customElement("ak-user-list")
export class UserListPage extends WithTenantConfig(WithCapabilitiesConfig(TablePage<User>)) {
export class UserListPage extends WithBrandConfig(WithCapabilitiesConfig(TablePage<User>)) {
expandable = true;
checkbox = true;
@ -352,7 +352,7 @@ export class UserListPage extends WithTenantConfig(WithCapabilitiesConfig(TableP
${msg("Set password")}
</button>
</ak-forms-modal>
${this.tenant.flowRecovery
${this.brand.flowRecovery
? html`
<ak-action-button
class="pf-m-secondary"
@ -370,7 +370,7 @@ export class UserListPage extends WithTenantConfig(WithCapabilitiesConfig(TableP
`
: html` <p>
${msg(
"To let a user directly reset a their password, configure a recovery flow on the currently active tenant.",
"To let a user directly reset a their password, configure a recovery flow on the currently active brand.",
)}
</p>`}
</div>

View File

@ -6,7 +6,7 @@ import {
import { EVENT_LOCALE_REQUEST, EVENT_REFRESH, VERSION } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global";
import { Config, Configuration, CoreApi, CurrentTenant, RootApi } from "@goauthentik/api";
import { Config, Configuration, CoreApi, CurrentBrand, RootApi } from "@goauthentik/api";
let globalConfigPromise: Promise<Config> | undefined = Promise.resolve(globalAK().config);
export function config(): Promise<Config> {
@ -16,7 +16,7 @@ export function config(): Promise<Config> {
return globalConfigPromise;
}
export function tenantSetFavicon(tenant: CurrentTenant) {
export function brandSetFavicon(brand: CurrentBrand) {
/**
* <link rel="icon" href="/static/dist/assets/icons/icon.png">
* <link rel="shortcut icon" href="/static/dist/assets/icons/icon.png">
@ -29,36 +29,36 @@ export function tenantSetFavicon(tenant: CurrentTenant) {
relIcon.rel = rel;
document.getElementsByTagName("head")[0].appendChild(relIcon);
}
relIcon.href = tenant.brandingFavicon;
relIcon.href = brand.brandingFavicon;
});
}
export function tenantSetLocale(tenant: CurrentTenant) {
if (tenant.defaultLocale === "") {
export function brandSetLocale(brand: CurrentBrand) {
if (brand.defaultLocale === "") {
return;
}
console.debug("authentik/locale: setting locale from tenant default");
console.debug("authentik/locale: setting locale from brand default");
window.dispatchEvent(
new CustomEvent(EVENT_LOCALE_REQUEST, {
composed: true,
bubbles: true,
detail: { locale: tenant.defaultLocale },
detail: { locale: brand.defaultLocale },
}),
);
}
let globalTenantPromise: Promise<CurrentTenant> | undefined = Promise.resolve(globalAK().tenant);
export function tenant(): Promise<CurrentTenant> {
if (!globalTenantPromise) {
globalTenantPromise = new CoreApi(DEFAULT_CONFIG)
.coreTenantsCurrentRetrieve()
.then((tenant) => {
tenantSetFavicon(tenant);
tenantSetLocale(tenant);
return tenant;
let globalBrandPromise: Promise<CurrentBrand> | undefined = Promise.resolve(globalAK().brand);
export function brand(): Promise<CurrentBrand> {
if (!globalBrandPromise) {
globalBrandPromise = new CoreApi(DEFAULT_CONFIG)
.coreBrandsCurrentRetrieve()
.then((brand) => {
brandSetFavicon(brand);
brandSetLocale(brand);
return brand;
});
}
return globalTenantPromise;
return globalBrandPromise;
}
export function getMetaContent(key: string): string {
@ -75,7 +75,7 @@ export const DEFAULT_CONFIG = new Configuration({
middleware: [
new CSRFMiddleware(),
new EventMiddleware(),
new LoggingMiddleware(globalAK().tenant),
new LoggingMiddleware(globalAK().brand),
],
});
@ -90,9 +90,9 @@ window.addEventListener(EVENT_REFRESH, () => {
// Upon global refresh, disregard whatever was pre-hydrated and
// actually load info from API
globalConfigPromise = undefined;
globalTenantPromise = undefined;
globalBrandPromise = undefined;
config();
tenant();
brand();
});
console.debug(`authentik(early): version ${VERSION}, apiBase ${DEFAULT_CONFIG.basePath}`);

View File

@ -2,7 +2,7 @@ import { EVENT_REQUEST_POST } from "@goauthentik/common/constants";
import { getCookie } from "@goauthentik/common/utils";
import {
CurrentTenant,
CurrentBrand,
FetchParams,
Middleware,
RequestContext,
@ -18,13 +18,13 @@ export interface RequestInfo {
}
export class LoggingMiddleware implements Middleware {
tenant: CurrentTenant;
constructor(tenant: CurrentTenant) {
this.tenant = tenant;
brand: CurrentBrand;
constructor(brand: CurrentBrand) {
this.brand = brand;
}
post(context: ResponseContext): Promise<Response | void> {
let msg = `authentik/api[${this.tenant.matchedDomain}]: `;
let msg = `authentik/api[${this.brand.matchedDomain}]: `;
// https://developer.mozilla.org/en-US/docs/Web/API/console#styling_console_output
msg += `%c${context.response.status}%c ${context.init.method} ${context.url}`;
let style = "";

View File

@ -1,4 +1,4 @@
import { Config, ConfigFromJSON, CurrentTenant, CurrentTenantFromJSON } from "@goauthentik/api";
import { Config, ConfigFromJSON, CurrentBrand, CurrentBrandFromJSON } from "@goauthentik/api";
export interface GlobalAuthentik {
_converted?: boolean;
@ -7,7 +7,7 @@ export interface GlobalAuthentik {
layout: string;
};
config: Config;
tenant: CurrentTenant;
brand: CurrentBrand;
versionFamily: string;
versionSubdomain: string;
build: string;
@ -21,7 +21,7 @@ export function globalAK(): GlobalAuthentik {
const ak = (window as unknown as AuthentikWindow).authentik;
if (ak && !ak._converted) {
ak._converted = true;
ak.tenant = CurrentTenantFromJSON(ak.tenant);
ak.brand = CurrentBrandFromJSON(ak.brand);
ak.config = ConfigFromJSON(ak.config);
}
if (!ak) {
@ -29,7 +29,7 @@ export function globalAK(): GlobalAuthentik {
config: ConfigFromJSON({
capabilities: [],
}),
tenant: CurrentTenantFromJSON({
brand: CurrentBrandFromJSON({
ui_footer_links: [],
}),
versionFamily: "",

View File

@ -1,11 +1,9 @@
import { createContext } from "@lit-labs/context";
import type { Config, CurrentTenant } from "@goauthentik/api";
import type { Config, CurrentBrand } from "@goauthentik/api";
export const authentikConfigContext = createContext<Config>(Symbol("authentik-config-context"));
export const authentikTenantContext = createContext<CurrentTenant>(
Symbol("authentik-tenant-context"),
);
export const authentikBrandContext = createContext<CurrentBrand>(Symbol("authentik-brand-context"));
export default authentikConfigContext;

View File

@ -9,13 +9,13 @@ import { LitElement } from "lit";
import AKGlobal from "@goauthentik/common/styles/authentik.css";
import ThemeDark from "@goauthentik/common/styles/theme-dark.css";
import { Config, CurrentTenant, UiThemeEnum } from "@goauthentik/api";
import { Config, CurrentBrand, UiThemeEnum } from "@goauthentik/api";
import { AdoptedStyleSheetsElement } from "./types";
type AkInterface = HTMLElement & {
getTheme: () => Promise<UiThemeEnum>;
tenant?: CurrentTenant;
brand?: CurrentBrand;
uiConfig?: UIConfig;
config?: Config;
};

View File

@ -1,8 +1,8 @@
import { config, tenant } from "@goauthentik/common/api/config";
import { brand, config } from "@goauthentik/common/api/config";
import { UIConfig, uiConfig } from "@goauthentik/common/ui/config";
import {
authentikBrandContext,
authentikConfigContext,
authentikTenantContext,
} from "@goauthentik/elements/AuthentikContexts";
import type { AdoptedStyleSheetsElement } from "@goauthentik/elements/types";
import { ensureCSSStyleSheet } from "@goauthentik/elements/utils/ensureCSSStyleSheet";
@ -12,13 +12,13 @@ import { state } from "lit/decorators.js";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { Config, CurrentTenant, UiThemeEnum } from "@goauthentik/api";
import { Config, CurrentBrand, UiThemeEnum } from "@goauthentik/api";
import { AKElement } from "../Base";
type AkInterface = HTMLElement & {
getTheme: () => Promise<UiThemeEnum>;
tenant?: CurrentTenant;
brand?: CurrentBrand;
uiConfig?: UIConfig;
config?: Config;
};
@ -45,28 +45,28 @@ export class Interface extends AKElement implements AkInterface {
return this._config;
}
_tenantContext = new ContextProvider(this, {
context: authentikTenantContext,
_brandContext = new ContextProvider(this, {
context: authentikBrandContext,
initialValue: undefined,
});
_tenant?: CurrentTenant;
_brand?: CurrentBrand;
@state()
set tenant(c: CurrentTenant) {
this._tenant = c;
this._tenantContext.setValue(c);
set brand(c: CurrentBrand) {
this._brand = c;
this._brandContext.setValue(c);
this.requestUpdate();
}
get tenant(): CurrentTenant | undefined {
return this._tenant;
get brand(): CurrentBrand | undefined {
return this._brand;
}
constructor() {
super();
document.adoptedStyleSheets = [...document.adoptedStyleSheets, ensureCSSStyleSheet(PFBase)];
tenant().then((tenant) => (this.tenant = tenant));
brand().then((brand) => (this.brand = brand));
config().then((config) => (this.config = config));
this.dataset.akInterfaceRoot = "true";
}

View File

@ -0,0 +1,20 @@
import { authentikBrandContext } from "@goauthentik/elements/AuthentikContexts";
import { consume } from "@lit-labs/context";
import type { LitElement } from "lit";
import type { CurrentBrand } from "@goauthentik/api";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Constructor<T = object> = abstract new (...args: any[]) => T;
export function WithBrandConfig<T extends Constructor<LitElement>>(
superclass: T,
subscribe = true,
) {
abstract class WithBrandProvider extends superclass {
@consume({ context: authentikBrandContext, subscribe })
public brand!: CurrentBrand;
}
return WithBrandProvider;
}

View File

@ -1,20 +0,0 @@
import { authentikTenantContext } from "@goauthentik/elements/AuthentikContexts";
import { consume } from "@lit-labs/context";
import type { LitElement } from "lit";
import type { CurrentTenant } from "@goauthentik/api";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type Constructor<T = object> = abstract new (...args: any[]) => T;
export function WithTenantConfig<T extends Constructor<LitElement>>(
superclass: T,
subscribe = true,
) {
abstract class WithTenantProvider extends superclass {
@consume({ context: authentikTenantContext, subscribe })
public tenant!: CurrentTenant;
}
return WithTenantProvider;
}

View File

@ -9,7 +9,7 @@ import {
import { currentInterface } from "@goauthentik/common/sentry";
import { me } from "@goauthentik/common/users";
import { AKElement } from "@goauthentik/elements/Base";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
import { msg } from "@lit/localize";
@ -24,7 +24,7 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { EventsApi } from "@goauthentik/api";
@customElement("ak-page-header")
export class PageHeader extends WithTenantConfig(AKElement) {
export class PageHeader extends WithBrandConfig(AKElement) {
@property()
icon?: string;
@ -37,7 +37,7 @@ export class PageHeader extends WithTenantConfig(AKElement) {
@property()
set header(value: string) {
const currentIf = currentInterface();
let title = this.tenant?.brandingTitle || TITLE_DEFAULT;
let title = this.brand?.brandingTitle || TITLE_DEFAULT;
if (currentIf === "admin") {
title = `${msg("Admin")} - ${title}`;
}

View File

@ -1,6 +1,6 @@
import { EVENT_SIDEBAR_TOGGLE } from "@goauthentik/common/constants";
import { AKElement } from "@goauthentik/elements/Base";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js";
@ -10,13 +10,13 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGlobal from "@patternfly/patternfly/patternfly-base.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { CurrentTenant, UiThemeEnum } from "@goauthentik/api";
import { CurrentBrand, UiThemeEnum } from "@goauthentik/api";
// If the viewport is wider than MIN_WIDTH, the sidebar
// is shown besides the content, and not overlaid.
export const MIN_WIDTH = 1200;
export const DefaultTenant: CurrentTenant = {
export const DefaultBrand: CurrentBrand = {
brandingLogo: "/static/dist/assets/icons/icon_left_brand.svg",
brandingFavicon: "/static/dist/assets/icons/icon.png",
brandingTitle: "authentik",
@ -27,7 +27,7 @@ export const DefaultTenant: CurrentTenant = {
};
@customElement("ak-sidebar-brand")
export class SidebarBrand extends WithTenantConfig(AKElement) {
export class SidebarBrand extends WithBrandConfig(AKElement) {
static get styles(): CSSResult[] {
return [
PFBase,
@ -84,7 +84,7 @@ export class SidebarBrand extends WithTenantConfig(AKElement) {
<a href="#/" class="pf-c-page__header-brand-link">
<div class="pf-c-brand ak-brand">
<img
src=${this.tenant?.brandingLogo ?? DefaultTenant.brandingLogo}
src=${this.brand?.brandingLogo ?? DefaultBrand.brandingLogo}
alt="authentik Logo"
loading="lazy"
/>

View File

@ -209,7 +209,7 @@ export class RacInterface extends Interface {
}
updateTitle(): void {
let title = this.tenant?.brandingTitle || TITLE_DEFAULT;
let title = this.brand?.brandingTitle || TITLE_DEFAULT;
if (this.endpointName) {
title = `${this.endpointName} - ${title}`;
}

View File

@ -55,9 +55,9 @@ export class FlowExecutor extends Interface implements StageHost {
set challenge(value: ChallengeTypes | undefined) {
this._challenge = value;
if (value?.flowInfo?.title) {
document.title = `${value.flowInfo?.title} - ${this.tenant?.brandingTitle}`;
document.title = `${value.flowInfo?.title} - ${this.brand?.brandingTitle}`;
} else {
document.title = this.tenant?.brandingTitle || TITLE_DEFAULT;
document.title = this.brand?.brandingTitle || TITLE_DEFAULT;
}
this.requestUpdate();
}
@ -186,7 +186,7 @@ export class FlowExecutor extends Interface implements StageHost {
}
async getTheme(): Promise<UiThemeEnum> {
return globalAK()?.tenant.uiTheme || UiThemeEnum.Automatic;
return globalAK()?.brand.uiTheme || UiThemeEnum.Automatic;
}
async submit(payload?: FlowChallengeResponseRequest): Promise<boolean> {
@ -430,7 +430,7 @@ export class FlowExecutor extends Interface implements StageHost {
renderChallengeWrapper(): TemplateResult {
const logo = html`<div class="pf-c-login__main-header pf-c-brand ak-brand">
<img src="${first(this.tenant?.brandingLogo, "")}" alt="authentik Logo" />
<img src="${first(this.brand?.brandingLogo, "")}" alt="authentik Logo" />
</div>`;
if (!this.challenge) {
return html`${logo}<ak-empty-state ?loading=${true} header=${msg("Loading")}>
@ -488,7 +488,7 @@ export class FlowExecutor extends Interface implements StageHost {
</div>
<footer class="pf-c-login__footer">
<ul class="pf-c-list pf-m-inline">
${this.tenant?.uiFooterLinks?.map((link) => {
${this.brand?.uiFooterLinks?.map((link) => {
return html`<li>
<a href="${link.href || ""}"
>${link.name}</a

View File

@ -20,7 +20,7 @@ import PFBase from "@patternfly/patternfly/patternfly-base.css";
import {
AuthenticatorValidationChallenge,
AuthenticatorValidationChallengeResponseRequest,
CurrentTenant,
CurrentBrand,
DeviceChallenge,
DeviceClassesEnum,
FlowsApi,
@ -44,8 +44,8 @@ export class AuthenticatorValidateStage
return this.host.loading;
}
get tenant(): CurrentTenant | undefined {
return this.host.tenant;
get brand(): CurrentBrand | undefined {
return this.host.brand;
}
@state()

View File

@ -4,7 +4,7 @@ import { KeyUnknown } from "@goauthentik/elements/forms/Form";
import { TemplateResult, html } from "lit";
import { property } from "lit/decorators.js";
import { CurrentTenant, ErrorDetail } from "@goauthentik/api";
import { CurrentBrand, ErrorDetail } from "@goauthentik/api";
export interface StageHost {
challenge?: unknown;
@ -12,7 +12,7 @@ export interface StageHost {
loading: boolean;
submit(payload: unknown): Promise<boolean>;
readonly tenant?: CurrentTenant;
readonly brand?: CurrentBrand;
}
export function readFileAsync(file: Blob) {

View File

@ -4,7 +4,7 @@ import { globalAK } from "@goauthentik/common/global";
import { first, getCookie } from "@goauthentik/common/utils";
import { Interface } from "@goauthentik/elements/Interface";
import "@goauthentik/elements/ak-locale-context";
import { DefaultTenant } from "@goauthentik/elements/sidebar/SidebarBrand";
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
import "rapidoc";
import { CSSResult, TemplateResult, css, html } from "lit";
@ -59,7 +59,7 @@ export class APIBrowser extends Interface {
}
async getTheme(): Promise<UiThemeEnum> {
return globalAK()?.tenant.uiTheme || UiThemeEnum.Automatic;
return globalAK()?.brand.uiTheme || UiThemeEnum.Automatic;
}
render(): TemplateResult {
@ -103,7 +103,7 @@ export class APIBrowser extends Interface {
<img
alt="authentik Logo"
class="logo"
src="${first(this.tenant?.brandingLogo, DefaultTenant.brandingLogo)}"
src="${first(this.brand?.brandingLogo, DefaultBrand.brandingLogo)}"
/>
</div>
</rapi-doc>

View File

@ -29,7 +29,7 @@ export class Loading extends Interface {
}
async getTheme(): Promise<UiThemeEnum> {
return globalAK()?.tenant.uiTheme || UiThemeEnum.Automatic;
return globalAK()?.brand.uiTheme || UiThemeEnum.Automatic;
}
render(): TemplateResult {

View File

@ -19,7 +19,7 @@ import "@goauthentik/elements/notifications/NotificationDrawer";
import { getURLParam, updateURLParams } from "@goauthentik/elements/router/RouteMatch";
import "@goauthentik/elements/router/RouterOutlet";
import "@goauthentik/elements/sidebar/Sidebar";
import { DefaultTenant } from "@goauthentik/elements/sidebar/SidebarBrand";
import { DefaultBrand } from "@goauthentik/elements/sidebar/SidebarBrand";
import "@goauthentik/elements/sidebar/SidebarItem";
import { ROUTES } from "@goauthentik/user/Routes";
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
@ -192,11 +192,8 @@ export class UserInterface extends Interface {
<a href="#/" class="pf-c-page__header-brand-link">
<img
class="pf-c-brand"
src="${first(
this.tenant?.brandingLogo,
DefaultTenant.brandingLogo,
)}"
alt="${(this.tenant?.brandingTitle, DefaultTenant.brandingTitle)}"
src="${first(this.brand?.brandingLogo, DefaultBrand.brandingLogo)}"
alt="${(this.brand?.brandingTitle, DefaultBrand.brandingTitle)}"
/>
</a>
</div>

View File

@ -3,7 +3,7 @@ import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { MessageLevel } from "@goauthentik/common/messages";
import { refreshMe } from "@goauthentik/common/users";
import { AKElement } from "@goauthentik/elements/Base";
import { WithTenantConfig } from "@goauthentik/elements/Interface/tenantProvider";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import { showMessage } from "@goauthentik/elements/messages/MessageContainer";
import { StageHost } from "@goauthentik/flow/stages/base";
import "@goauthentik/user/user-settings/details/stages/prompt/PromptStage";
@ -32,7 +32,7 @@ import {
@customElement("ak-user-settings-flow-executor")
export class UserSettingsFlowExecutor
extends WithTenantConfig(AKElement, true)
extends WithBrandConfig(AKElement, true)
implements StageHost
{
@property()
@ -87,7 +87,7 @@ export class UserSettingsFlowExecutor
}
firstUpdated(): void {
this.flowSlug = this.tenant?.flowUserSettings;
this.flowSlug = this.brand?.flowUserSettings;
if (!this.flowSlug) {
return;
}

View File

@ -51,10 +51,10 @@ export class UserSettingsPromptStage extends PromptStage {
<div class="pf-c-form__horizontal-group">
<div class="pf-c-form__actions">
<button type="submit" class="pf-c-button pf-m-primary">${msg("Save")}</button>
${this.host.tenant?.flowUnenrollment
${this.host.brand?.flowUnenrollment
? html` <a
class="pf-c-button pf-m-danger"
href="/if/flow/${this.host.tenant.flowUnenrollment}/"
href="/if/flow/${this.host.brand.flowUnenrollment}/"
>
${msg("Delete account")}
</a>`

View File

@ -355,10 +355,6 @@
<source>Client IP</source>
<target>Client-IP</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>Mandant</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
</trans-unit>
@ -2776,14 +2772,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>Token aktualisieren</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>Umgebung erfolgreich aktualisiert.</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>Umgebung erfolgreich erstellt.</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
<target>Domain</target>
@ -2796,10 +2784,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>Standard</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>Nutze diese Umgebung für jede Domain, die keine eigene Umgebung hat.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
<target>Branding-Einstellungen</target>
@ -2898,17 +2882,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>Diese Einstellung betrifft nur neue Ereignisse, da die Ablaufzeit für jedes Ereignis gespeichert wird.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Format: "Wochen=3;Tage=2;Stunden=3,Sekunden=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>Mandanten</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
<target>Konfiguriere visuelle Einstellungen und Standards für verschiedene Domains.</target>
@ -2917,18 +2890,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>Standard?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>Umgebung(en)</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>Umgebung aktualisieren</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>Umgebung erstellen</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
<target>Richtlinien</target>
@ -3144,10 +3105,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>Der Wiederherstellungslink kann nicht per E-Mail gesendet werden, der Benutzer hat keine E-Mail-Adresse gespeichert.</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>Damit Benutzer ihr Passwort selbst zurücksetzen können, muss ein Wiederherstellungsablauf für die aktuell aktive Umgebung konfiguriert werden.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
<target>Benutzer hinzufügen</target>
@ -5974,9 +5931,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="saf6097bfa25205b8">
<source>A copy of this recovery link has been placed in your clipboard</source>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
</trans-unit>
@ -6258,6 +6212,122 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>

View File

@ -358,10 +358,6 @@
<source>Client IP</source>
<target>Client IP</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>Tenant</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
<target>Recent events</target>
@ -2908,14 +2904,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>Update Token</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>Successfully updated tenant.</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>Successfully created tenant.</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
<target>Domain</target>
@ -2928,10 +2916,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>Default</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>Use this tenant for each domain that doesn't have a dedicated tenant.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
<target>Branding settings</target>
@ -3032,18 +3016,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>This setting only affects new Events, as the expiration is saved per-event.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Format: "weeks=3;days=2;hours=3,seconds=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
<target>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</target>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>Tenants</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
<target>Configure visual settings and defaults for different domains.</target>
@ -3052,18 +3024,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>Default?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>Tenant(s)</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>Update Tenant</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>Create Tenant</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
<target>Policies</target>
@ -3285,10 +3245,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>Recovery link cannot be emailed, user has no email address saved.</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
<target>Add User</target>
@ -6250,9 +6206,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="saf6097bfa25205b8">
<source>A copy of this recovery link has been placed in your clipboard</source>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
</trans-unit>
@ -6534,6 +6487,122 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>

View File

@ -348,10 +348,6 @@
<source>Client IP</source>
<target>IP del cliente</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>inquilino</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
</trans-unit>
@ -2732,14 +2728,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>Token de actualización</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>Se actualizó correctamente el inquilino</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>El inquilino se creó correctamente.</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
<target>Dominio</target>
@ -2752,10 +2740,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>Predeterminado</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>Use este inquilino para cada dominio que no tenga un inquilino dedicado.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
<target>Configuración de marca</target>
@ -2852,17 +2836,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>Esta configuración solo afecta a los eventos nuevos, ya que la caducidad se guarda por evento.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Formato: «semanas = 3; días = 2; horas = 3, segundos = 2».</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>Inquilinos</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
<target>Configure los ajustes visuales y los valores predeterminados para los diferentes dominios.</target>
@ -2871,18 +2844,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>¿Por defecto?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>Inquilino (s)</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>Actualizar inquilino</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>Crear inquilino</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
<target>Políticas</target>
@ -3098,10 +3059,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>El enlace de recuperación no se puede enviar por correo electrónico, el usuario no tiene ninguna dirección de correo electrónico</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>Para permitir que un usuario restablezca directamente su contraseña, configure un flujo de recuperación en el inquilino activo actualmente.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
</trans-unit>
@ -5890,9 +5847,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="saf6097bfa25205b8">
<source>A copy of this recovery link has been placed in your clipboard</source>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
</trans-unit>
@ -6174,6 +6128,122 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>

View File

@ -444,11 +444,6 @@
<source>Client IP</source>
<target>Adresse IP client</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>Tenant</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
@ -3627,16 +3622,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>Mettre à jour le jeton</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>Tenant mis à jour avec succès</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>Tenant créé avec succès</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
@ -3652,11 +3637,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>Par défaut</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>Utilisez ce locataire pour chaque domaine qui ne dispose pas d'un locataire dédié.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
@ -3782,21 +3762,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>Ce paramètre n'affecte que les nouveaux événements, l'expiration étant enregistrée pour chaque événement.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Format : "weeks=3;days=2;hours=3,seconds=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
<target>Définir des attributs personnalisés en utilisant YAML ou JSON. Tous les attributs définis ici seront hérités par les utilisateurs, si la demande est traitée par ce tenant.</target>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>Tenants</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
@ -3807,21 +3772,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>Par défaut ?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>Tenant(s)</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>Mettre à jour le tenant</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>Créer un tenant</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
@ -4097,11 +4047,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>Le lien de récupération ne peut pas être envoyé par courriel, l'utilisateur n'a aucune adresse courriel enregistrée.</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>Pour laisser les utilisateurs réinitialiser leur mot de passe, configurez un flux de récupération sur le locataire actuel.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
@ -7850,10 +7795,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
<source>A copy of this recovery link has been placed in your clipboard</source>
<target>Une copie de ce lien de récupération a été placée dans le presse-papier</target>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
<target>Le tenant actuel doit avoir un flux de récupération configuré pour utiliser un lien de récupération</target>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
<target>Créer un lien de récupération</target>
@ -8228,6 +8169,122 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>

View File

@ -443,11 +443,6 @@
<source>Client IP</source>
<target>클라이언트 IP</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>테넌트</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
@ -3617,16 +3612,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>토큰 업데이트</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>테넌트를 성공적으로 업데이트했습니다.</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>테넌트를 성공적으로 만들었습니다.</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
@ -3642,11 +3627,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>기본</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>전용 테넌트가 없는 각 도메인에 이 테넌트를 사용하세요.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
@ -3772,21 +3752,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>T만료는 이벤트별로 저장되므로 설정은 새 이벤트에만 영향을 줍니다.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>서식: "weeks=3;days=2;hours=3,seconds=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
<target>YAML 또는 JSON을 사용하여 사용자 지정 속성을 설정합니다. 이 테넌트가 요청을 처리하는 경우 여기에서 설정한 모든 속성은 사용자가 상속받게 됩니다.</target>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>테넌트</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
@ -3797,21 +3762,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>기본값?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>테넌트</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>테넌트 업데이트</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>테넌트 생성</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
@ -4081,11 +4031,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>복구 링크를 이메일로 보낼 수 없습니다. 사용자가 저장한 이메일 주소가 없습니다.</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>사용자가 직접 비밀번호를 재설정할 수 있도록 하려면 현재 활성 상태인 테넌트에서 복구 플로우를 구성하세요.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
@ -7813,10 +7758,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>A copy of this recovery link has been placed in your clipboard</source>
<target>이 복구 링크의 사본이 클립보드에 저장되었습니다.</target>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
<target>현재 테넌트에 복구 링크를 사용하도록 구성된 복구 플로우가 있어야 합니다.</target>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
<target>복구 링크 생성</target>
@ -8145,6 +8086,122 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>

View File

@ -440,11 +440,6 @@
<source>Client IP</source>
<target>Client-IP</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>Tenant</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
@ -3604,16 +3599,6 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
<source>Update Token</source>
<target>Token bijwerken</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>Succesvol bijgewerkte tenant.</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>Succesvol aangemaakte tenant.</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
@ -3629,11 +3614,6 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
<source>Default</source>
<target>Standaard</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>Gebruik deze tenant voor elk domein dat geen toegewijde tenant heeft.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
@ -3759,21 +3739,6 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>Deze instelling heeft alleen invloed op nieuwe gebeurtenissen, omdat de vervaldatum per gebeurtenis wordt opgeslagen.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Indeling: "weeks=3;days=2;hours=3,seconds=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
<target>Stel aangepaste eigenschappen in met behulp van YAML of JSON. Alle hier ingestelde eigenschappen worden overgenomen door gebruikers als het verzoek wordt afgehandeld door deze tenant.</target>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>Tenants</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
@ -3784,21 +3749,6 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
<source>Default?</source>
<target>Standaard?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>Tenants</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>Tenant bijwerken</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>Tenant aanmaken</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
@ -4067,11 +4017,6 @@ slaagt niet wanneer een of beide geselecteerde opties gelijk zijn aan of boven d
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>Herstelkoppeling kan niet per e-mail worden verzonden, gebruiker heeft geen opgeslagen e-mailadres.</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>Om een gebruiker rechtstreeks zijn/haar wachtwoord te laten resetten, configureer een herstelflow op de momenteel actieve tenant.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
@ -7793,9 +7738,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
<trans-unit id="saf6097bfa25205b8">
<source>A copy of this recovery link has been placed in your clipboard</source>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s0924f51b028233a3">
<source>&lt;No name set&gt;</source>
</trans-unit>
@ -7984,6 +7926,122 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>

View File

@ -357,10 +357,6 @@
<source>Client IP</source>
<target>IP klienta</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>Najemca</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
</trans-unit>
@ -2825,14 +2821,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>Aktualizuj token</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>Pomyślnie zaktualizowano najemcę.</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>Pomyślnie utworzony najemce.</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
<target>Domena</target>
@ -2845,10 +2833,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>Domyślny</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>Użyj tego najemcy dla każdej domeny, która nie ma dedykowanej najmecy.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
<target>Ustawienia brandingowe</target>
@ -2948,18 +2932,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>To ustawienie ma wpływ tylko na nowe zdarzenia, ponieważ data wygaśnięcia jest zapisywana dla każdego zdarzenia.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Format: "weeks=3;days=2;hours=3,seconds=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
<target>Ustaw atrybuty niestandardowe za pomocą YAML lub JSON. Wszystkie ustawione tutaj atrybuty będą dziedziczone przez użytkowników, jeśli żądanie jest obsługiwane przez tego najemcę.</target>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>Najemcy</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
<target>Skonfiguruj ustawienia wizualne i domyślne dla różnych domen.</target>
@ -2968,18 +2940,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>Domyślny?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>Najemca(y)</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>Zaktualizuj najemcę</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>Utwórz najemcę</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
<target>Zasady</target>
@ -3201,10 +3161,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>Nie można wysłać linku odzyskiwania, użytkownik nie ma zapisanego adresu e-mail.</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>Aby umożliwić użytkownikowi bezpośrednie zresetowanie hasła, skonfiguruj przepływ odzyskiwania w aktualnie aktywnym najemcy.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
<target>Dodaj użytkownika</target>
@ -6098,9 +6054,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="saf6097bfa25205b8">
<source>A copy of this recovery link has been placed in your clipboard</source>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
</trans-unit>
@ -6382,6 +6335,122 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>

View File

@ -441,11 +441,6 @@
<source>Client IP</source>
<target>Ćĺĩēńţ ĨƤ</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>Ţēńàńţ</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
@ -3604,16 +3599,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>Ũƥďàţē Ţōķēń</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>Śũććēśśƒũĺĺŷ ũƥďàţēď ţēńàńţ.</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>Śũććēśśƒũĺĺŷ ćŕēàţēď ţēńàńţ.</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
@ -3629,11 +3614,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>Ďēƒàũĺţ</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>Ũśē ţĥĩś ţēńàńţ ƒōŕ ēàćĥ ďōmàĩń ţĥàţ ďōēśń'ţ ĥàvē à ďēďĩćàţēď ţēńàńţ.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
@ -3759,21 +3739,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>Ţĥĩś śēţţĩńĝ ōńĺŷ àƒƒēćţś ńēŵ Ēvēńţś, àś ţĥē ēxƥĩŕàţĩōń ĩś śàvēď ƥēŕ-ēvēńţ.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Ƒōŕmàţ: "ŵēēķś=3;ďàŷś=2;ĥōũŕś=3,śēćōńďś=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
<target>Śēţ ćũśţōm àţţŕĩƀũţēś ũśĩńĝ ŶÀMĹ ōŕ ĵŚŌŃ. Àńŷ àţţŕĩƀũţēś śēţ ĥēŕē ŵĩĺĺ ƀē ĩńĥēŕĩţēď ƀŷ ũśēŕś, ĩƒ ţĥē ŕēǫũēśţ ĩś ĥàńďĺēď ƀŷ ţĥĩś ţēńàńţ.</target>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>Ţēńàńţś</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
@ -3784,21 +3749,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>Ďēƒàũĺţ?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>Ţēńàńţ(ś)</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>Ũƥďàţē Ţēńàńţ</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>Ćŕēàţē Ţēńàńţ</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
@ -4067,11 +4017,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>Ŕēćōvēŕŷ ĺĩńķ ćàńńōţ ƀē ēmàĩĺēď, ũśēŕ ĥàś ńō ēmàĩĺ àďďŕēśś śàvēď.</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>Ţō ĺēţ à ũśēŕ ďĩŕēćţĺŷ ŕēśēţ à ţĥēĩŕ ƥàśśŵōŕď, ćōńƒĩĝũŕē à ŕēćōvēŕŷ ƒĺōŵ ōń ţĥē ćũŕŕēńţĺŷ àćţĩvē ţēńàńţ.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
@ -7789,10 +7734,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>A copy of this recovery link has been placed in your clipboard</source>
<target>À ćōƥŷ ōƒ ţĥĩś ŕēćōvēŕŷ ĺĩńķ ĥàś ƀēēń ƥĺàćēď ĩń ŷōũŕ ćĺĩƥƀōàŕď</target>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
<target>Ţĥē ćũŕŕēńţ ţēńàńţ mũśţ ĥàvē à ŕēćōvēŕŷ ƒĺōŵ ćōńƒĩĝũŕēď ţō ũśē à ŕēćōvēŕŷ ĺĩńķ</target>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
<target>Ćŕēàţē ŕēćōvēŕŷ ĺĩńķ</target>
@ -8120,4 +8061,120 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body></file></xliff>

View File

@ -348,10 +348,6 @@
<source>Client IP</source>
<target>İstemci IP</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>Sakin</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
</trans-unit>
@ -2731,14 +2727,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>Belirteç Güncelle</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>Sakin başarıyla güncellendi.</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>Sakin başarıyla oluşturuldu.</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
<target>Alan Adı</target>
@ -2751,10 +2739,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>Varsayılan</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>Bu sakini, ayrılmış bir sakine sahip olmayan her etki alanı için kullanın.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
<target>Markalama ayarları</target>
@ -2851,17 +2835,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>Bu ayar, süre sonu olay başına kaydedildiğinden, yalnızca yeni Olayları etkiler.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Biçim: “hafta=3; gün = 2; saat=3, ikincil=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>Sakinler</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
<target>Farklı etki alanları için görsel ayarları ve varsayılanları yapılandırın.</target>
@ -2870,18 +2843,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>Varsayılan?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>Sakin(ler)</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>Sakini Güncelle</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>Sakin Oluştur</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
<target>İlkeler</target>
@ -3097,10 +3058,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>Kurtarma bağlantısı e-posta ile gönderilemez, kullanıcının e-posta adresi kaydedilmez.</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>Kullanıcının parolasını doğrudan sıfırlamasına izin vermek için, etkin olan sakin üzerinde bir kurtarma akışı yapılandırın.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
</trans-unit>
@ -5883,9 +5840,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="saf6097bfa25205b8">
<source>A copy of this recovery link has been placed in your clipboard</source>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
</trans-unit>
@ -6167,6 +6121,122 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>

View File

@ -290,9 +290,6 @@
<trans-unit id="s4d00f1de1c82281b">
<source>Client IP</source>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
</trans-unit>
@ -2608,12 +2605,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="scc3487e74c5a3e89">
<source>Copy token</source>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
</trans-unit>
@ -2623,9 +2614,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s11326fd2590f4e5e">
<source>Default</source>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
</trans-unit>
@ -2701,30 +2689,12 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="s44536d20bb5c8257">
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
</trans-unit>
<trans-unit id="s4802636d55022ed3">
<source>Default?</source>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
</trans-unit>
@ -2896,9 +2866,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="sd7fa99e4d82b374a">
<source>Recovery link cannot be emailed, user has no email address saved.</source>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
</trans-unit>
@ -3073,9 +3040,6 @@ doesn't pass when either or both of the selected options are equal or above the
<trans-unit id="saf6097bfa25205b8">
<source>A copy of this recovery link has been placed in your clipboard</source>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s3616cc78631f5893">
<source>Warning: You're about to delete the user you're logged in as (<x id="0" equiv-text="${shouldShowWarning.username}"/>). Proceed at your own risk.</source>
</trans-unit>
@ -5066,6 +5030,122 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>
</xliff>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<?xml version="1.0"?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
<file target-language="zh-Hans" source-language="en" original="lit-localize-inputs" datatype="plaintext">
<body>
<trans-unit id="s4caed5b7a7e5d89b">
@ -444,11 +444,6 @@
<source>Client IP</source>
<target>客户端 IP</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>租户</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
@ -613,9 +608,9 @@
</trans-unit>
<trans-unit id="saa0e2675da69651b">
<source>The URL &quot;<x id="0" equiv-text="${this.url}"/>&quot; was not found.</source>
<target>未找到 URL &quot;
<x id="0" equiv-text="${this.url}"/>&quot;。</target>
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
<target>未找到 URL "
<x id="0" equiv-text="${this.url}"/>"。</target>
</trans-unit>
<trans-unit id="s58cd9c2fe836d9c6">
@ -1057,8 +1052,8 @@
</trans-unit>
<trans-unit id="sa8384c9c26731f83">
<source>To allow any redirect URI, set this value to &quot;.*&quot;. Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 &quot;.*&quot;。请注意这可能带来的安全影响。</target>
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
<target>要允许任何重定向 URI请将此值设置为 ".*"。请注意这可能带来的安全影响。</target>
</trans-unit>
<trans-unit id="s55787f4dfcdce52b">
@ -1799,8 +1794,8 @@
</trans-unit>
<trans-unit id="sa90b7809586c35ce">
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon &quot;fa-test&quot;.</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 &quot;fa-test&quot;。</target>
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
<target>输入完整 URL、相对路径或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。</target>
</trans-unit>
<trans-unit id="s0410779cb47de312">
@ -2983,8 +2978,8 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s76768bebabb7d543">
<source>Field which contains members of a group. Note that if using the &quot;memberUid&quot; field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 &quot;memberUid&quot; 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
</trans-unit>
<trans-unit id="s026555347e589f0e">
@ -3629,16 +3624,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>更新令牌</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>已成功更新租户。</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>已成功创建租户。</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
@ -3654,11 +3639,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>默认</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>所有未设置专用租户的域名都将使用此租户。</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
@ -3776,29 +3756,14 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s7b1fba26d245cb1c">
<source>When using an external logging solution for archiving, this can be set to &quot;minutes=5&quot;.</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 &quot;minutes=5&quot;。</target>
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。</target>
</trans-unit>
<trans-unit id="s44536d20bb5c8257">
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>此设置仅影响新事件,因为过期时间是分事件保存的。</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: &quot;weeks=3;days=2;hours=3,seconds=2&quot;.</source>
<target>格式:&quot;weeks=3;days=2;hours=3,seconds=2&quot;。</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
<target>使用 YAML 或 JSON 格式设置自定义属性。如果请求由此租户处理,则用户会继承此处设置的任何自定义属性。</target>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>租户</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
@ -3809,21 +3774,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>默认?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>租户</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>更新租户</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>创建租户</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
@ -3983,10 +3933,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sa95a538bfbb86111">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> &quot;<x id="1" equiv-text="${this.obj?.name}"/>&quot;?</source>
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
<target>您确定要更新
<x id="0" equiv-text="${this.objectLabel}"/>&quot;
<x id="1" equiv-text="${this.obj?.name}"/>&quot; 吗?</target>
<x id="0" equiv-text="${this.objectLabel}"/>"
<x id="1" equiv-text="${this.obj?.name}"/>" 吗?</target>
</trans-unit>
<trans-unit id="sc92d7cfb6ee1fec6">
@ -4099,11 +4049,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>无法通过电子邮件发送恢复链接,用户没有保存电子邮件地址。</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>要让用户直接重置密码,请在当前活动的租户上配置恢复流程。</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
@ -5072,7 +5017,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="sdf1d8edef27236f0">
<source>A &quot;roaming&quot; authenticator, like a YubiKey</source>
<source>A "roaming" authenticator, like a YubiKey</source>
<target>像 YubiKey 这样的“漫游”身份验证器</target>
</trans-unit>
@ -5407,10 +5352,10 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${prompt.name}"/> (&quot;<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;, of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<target>
<x id="0" equiv-text="${prompt.name}"/>&quot;
<x id="1" equiv-text="${prompt.fieldKey}"/>&quot;,类型为
<x id="0" equiv-text="${prompt.name}"/>"
<x id="1" equiv-text="${prompt.fieldKey}"/>",类型为
<x id="2" equiv-text="${prompt.type}"/></target>
</trans-unit>
@ -5459,7 +5404,7 @@ doesn't pass when either or both of the selected options are equal or above the
</trans-unit>
<trans-unit id="s1608b2f94fa0dbd4">
<source>If set to a duration above 0, the user will have the option to choose to &quot;stay signed in&quot;, which will extend their session by the time specified here.</source>
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
<target>如果设置时长大于 0用户可以选择“保持登录”选项这将使用户的会话延长此处设置的时间。</target>
</trans-unit>
@ -7852,10 +7797,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>A copy of this recovery link has been placed in your clipboard</source>
<target>一份恢复链接拷贝已被写入剪贴板</target>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
<target>当前租户必须配置恢复流程才能使用恢复链接</target>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
<target>创建恢复链接</target>
@ -7965,7 +7906,7 @@ Bindings to groups/users are checked against the user of the event.</source>
<target>成功创建用户并添加到组 <x id="0" equiv-text="${this.group.name}"/></target>
</trans-unit>
<trans-unit id="s824e0943a7104668">
<source>This user will be added to the group &quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&quot;.</source>
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
<target>此用户将会被添加到组 &amp;quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&amp;quot;。</target>
</trans-unit>
<trans-unit id="s62e7f6ed7d9cb3ca">
@ -8231,7 +8172,123 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
<target>获取对象失败:<x id="0" equiv-text="${this.error.detail}"/></target>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>
</xliff>
</xliff>

View File

@ -355,10 +355,6 @@
<source>Client IP</source>
<target>客户端 IP</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>租户</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
</trans-unit>
@ -2755,14 +2751,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>更新令牌</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>已成功更新租户。</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>成功创建租户。</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
<target>域</target>
@ -2775,10 +2763,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>默认</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>对于没有专用租户的每个域,请使用此租户。</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
<target>品牌设置</target>
@ -2877,17 +2861,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>此设置仅影响新事件,因为过期时间是按事件保存的。</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>格式:"weeks=3;days=2;hours=3,seconds=2"。</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>租户</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
<target>配置不同域的可视化设置和默认值。</target>
@ -2896,18 +2869,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>默认?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>租户</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>更新租户</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>创建租户</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
<target>策略</target>
@ -3123,10 +3084,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>无法通过电子邮件发送恢复链接,用户没有保存电子邮件地址。</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>要让用户直接重置密码,请在当前活动的租户上配置恢复流程。</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
</trans-unit>
@ -5931,9 +5888,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<trans-unit id="saf6097bfa25205b8">
<source>A copy of this recovery link has been placed in your clipboard</source>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
</trans-unit>
@ -6215,6 +6169,122 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>

View File

@ -440,11 +440,6 @@
<source>Client IP</source>
<target>用戶端 IP</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>租戶</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
@ -3603,16 +3598,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Update Token</source>
<target>更新權杖</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>成功更新租户。</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>成功建立租戶。</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
@ -3628,11 +3613,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default</source>
<target>設為預設</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>對於每個沒有專有租戶的網域,請使用此租戶。</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
@ -3758,21 +3738,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>此設定僅會影響新的事件紀錄,舊的紀錄到期時間已經設定。</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>格式weeks=3;days=2;hours=3,seconds=2。</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
<target>使用 YAML 或 JSON 設定客製化特徵項。如果是此租戶處理的要求,這裡設定的任何特徵項都將被使用者繼承。</target>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>租戶</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
@ -3783,21 +3748,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Default?</source>
<target>是否為預設</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>租戶</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>更新租戶</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>建立租戶</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
@ -4062,11 +4012,6 @@ doesn't pass when either or both of the selected options are equal or above the
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>無法使用電子郵件傳送救援連結,因為使用者並沒有設定電子郵件。</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>若要讓使用者直接重設密碼,請在目前的活動租戶上設定救援流程。</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
@ -7786,10 +7731,6 @@ Bindings to groups/users are checked against the user of the event.</source>
<source>A copy of this recovery link has been placed in your clipboard</source>
<target>救援連結已經複製到您的剪貼簿中</target>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
<target>目前的租戶必需設定救援流程,才能使用救援連結</target>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
<target>建立救援連結</target>
@ -8104,6 +8045,122 @@ Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s16a15af46bc9aeef">
<source>Failed to fetch objects: <x id="0" equiv-text="${this.error.detail}"/></source>
</trans-unit>
<trans-unit id="s744401846fea6e76">
<source>Brand</source>
</trans-unit>
<trans-unit id="sab21e1f62676b56c">
<source>Successfully updated brand.</source>
</trans-unit>
<trans-unit id="sa43e43fd3a23e22d">
<source>Successfully created brand.</source>
</trans-unit>
<trans-unit id="s41b3f9b4c98aabd9">
<source>Use this brand for each domain that doesn't have a dedicated brand.</source>
</trans-unit>
<trans-unit id="s17260b71484b307f">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this brand.</source>
</trans-unit>
<trans-unit id="s79fc990a2b58f27f">
<source>Brands</source>
</trans-unit>
<trans-unit id="s02774bc46a167346">
<source>Brand(s)</source>
</trans-unit>
<trans-unit id="s801bf3d03f4a3ff1">
<source>Update Brand</source>
</trans-unit>
<trans-unit id="s5c3efec5330e0000">
<source>Create Brand</source>
</trans-unit>
<trans-unit id="sa9d13ce9e83aac17">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active brand.</source>
</trans-unit>
<trans-unit id="s6709b81e1ed4e39f">
<source>The current brand must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s634e2fd82c397576">
<source>Successfully updated settings.</source>
</trans-unit>
<trans-unit id="sb8e4edaea6f1d935">
<source>Avatars</source>
</trans-unit>
<trans-unit id="s945856050217c828">
<source>Configure how authentik should show avatars for users. The following values can be set:</source>
</trans-unit>
<trans-unit id="sf4ef4c8ce713f775">
<source>Disables per-user avatars and just shows a 1x1 pixel transparent picture</source>
</trans-unit>
<trans-unit id="s5446842a7e4a963b">
<source>Uses gravatar with the user's email address</source>
</trans-unit>
<trans-unit id="s35363b9e1cc2abd3">
<source>Generated avatars based on the user's name</source>
</trans-unit>
<trans-unit id="s48110ca292cad513">
<source>Any URL: If you want to use images hosted on another server, you can set any URL. Additionally, these placeholders can be used:</source>
</trans-unit>
<trans-unit id="sbe1dfda044bdc93b">
<source>The user's username</source>
</trans-unit>
<trans-unit id="s653f257c9c2d4dc5">
<source>The email address, md5 hashed</source>
</trans-unit>
<trans-unit id="s9c9183cd80916b4f">
<source>The user's UPN, if set (otherwise an empty string)</source>
</trans-unit>
<trans-unit id="h4963ed14d7e239a9">
<source>An attribute path like
<x id="0" equiv-text="&lt;code&gt;"/>attributes.something.avatar<x id="1" equiv-text="&lt;/code&gt;"/>, which can be used in
combination with the file field to allow users to upload custom
avatars for themselves.</source>
</trans-unit>
<trans-unit id="s4c80c34a67a6f1c9">
<source>Multiple values can be set, comma-separated, and authentik will fallback to the next mode when no avatar could be found.</source>
</trans-unit>
<trans-unit id="h2fafcc3ebafea2f8">
<source>For example, setting this to <x id="0" equiv-text="&lt;code&gt;"/>gravatar,initials<x id="1" equiv-text="&lt;/code&gt;"/> will
attempt to get an avatar from Gravatar, and if the user has not
configured on there, it will fallback to a generated avatar.</source>
</trans-unit>
<trans-unit id="s5faec5eb5faf62ac">
<source>Allow users to change name</source>
</trans-unit>
<trans-unit id="s078ffec0257621c0">
<source>Enable the ability for users to change their name.</source>
</trans-unit>
<trans-unit id="s456d88f3679190fd">
<source>Allow users to change email</source>
</trans-unit>
<trans-unit id="s5fc6c14d106f40d3">
<source>Enable the ability for users to change their email.</source>
</trans-unit>
<trans-unit id="s628e414bb2367057">
<source>Allow users to change username</source>
</trans-unit>
<trans-unit id="s6d816a95ca43a99d">
<source>Enable the ability for users to change their username.</source>
</trans-unit>
<trans-unit id="s57b52b60ed5e2bc7">
<source>Footer links</source>
</trans-unit>
<trans-unit id="s7349802b2f7f99c2">
<source>This option configures the footer links on the flow executor pages. It must be a valid JSON list and can be used as follows:</source>
</trans-unit>
<trans-unit id="s166b59f3cc5d8ec3">
<source>GDPR compliance</source>
</trans-unit>
<trans-unit id="sb8b23770f899e5bb">
<source>When enabled, all the events caused by a user will be deleted upon the user's deletion.</source>
</trans-unit>
<trans-unit id="s29501761df0fe837">
<source>Impersonation</source>
</trans-unit>
<trans-unit id="s8f503553d8432487">
<source>Globally enable/disable impersonation.</source>
</trans-unit>
<trans-unit id="see1eb81c1f734079">
<source>System settings</source>
</trans-unit>
</body>
</file>