Merge branch 'master' into outpost-ldap

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

# Conflicts:
#	authentik/core/api/users.py
#	authentik/policies/event_matcher/migrations/0013_alter_eventmatcherpolicy_app.py
This commit is contained in:
Jens Langhammer
2021-05-04 20:57:48 +02:00
127 changed files with 4765 additions and 6317 deletions

View File

@ -272,7 +272,7 @@ body {
.pf-c-login__main-header-desc {
color: var(--ak-dark-foreground);
}
.pf-c-login__main-footer-links-item-link > img {
.pf-c-login__main-footer-links-item img {
filter: invert(1);
}
.pf-c-login__main-footer-band {

View File

@ -54,7 +54,7 @@ export class Tabs extends LitElement {
this.currentPage = slot;
const currentUrl = window.location.hash.slice(1, Infinity).split(ROUTE_SEPARATOR)[0];
const newUrl = `#${currentUrl};${slot}`;
window.location.hash = newUrl;
history.replaceState(undefined, "", newUrl);
}
renderTab(page: Element): TemplateResult {

View File

@ -1,9 +1,18 @@
import { css, CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGlobal from "@patternfly/patternfly/patternfly-base.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import AKGlobal from "../../authentik.css";
import { configureSentry } from "../../api/Sentry";
import { Config } from "authentik-api";
import { ifDefined } from "lit-html/directives/if-defined";
import { EVENT_SIDEBAR_TOGGLE } from "../../constants";
// If the viewport is wider than MIN_WIDTH, the sidebar
// is shown besides the content, and not overlayed.
export const MIN_WIDTH = 1200;
export const DefaultConfig: Config = {
brandingLogo: " /static/dist/assets/icons/icon_left_brand.svg",
@ -21,12 +30,15 @@ export class SidebarBrand extends LitElement {
static get styles(): CSSResult[] {
return [
PFBase,
PFGlobal,
PFPage,
PFButton,
AKGlobal,
css`
:host {
display: flex;
flex-direction: column;
flex-direction: row;
align-items: center;
height: 114px;
min-height: 114px;
@ -36,19 +48,47 @@ export class SidebarBrand extends LitElement {
padding: 0 .5rem;
height: 42px;
}
button.pf-c-button.sidebar-trigger {
background-color: transparent;
border-radius: 0px;
height: 100%;
color: var(--ak-dark-foreground);
}
`,
];
}
constructor() {
super();
window.addEventListener("resize", () => {
this.requestUpdate();
});
}
firstUpdated(): void {
configureSentry(true).then((c) => {this.config = c;});
}
render(): TemplateResult {
return html` <a href="#/" class="pf-c-page__header-brand-link">
<div class="pf-c-brand ak-brand">
<img src="${ifDefined(this.config.brandingLogo)}" alt="authentik icon" loading="lazy" />
</div>
</a>`;
return html`
${window.innerWidth <= MIN_WIDTH ? html`
<button
class="sidebar-trigger pf-c-button"
@click=${() => {
this.dispatchEvent(
new CustomEvent(EVENT_SIDEBAR_TOGGLE, {
bubbles: true,
composed: true,
})
);
}}>
<i class="fas fa-bars"></i>
</button>
` : html``}
<a href="#/" class="pf-c-page__header-brand-link">
<div class="pf-c-brand ak-brand">
<img src="${ifDefined(this.config.brandingLogo)}" alt="authentik icon" loading="lazy" />
</div>
</a>`;
}
}

View File

@ -23,6 +23,7 @@ import "./stages/email/EmailStage";
import "./stages/identification/IdentificationStage";
import "./stages/password/PasswordStage";
import "./stages/prompt/PromptStage";
import "./sources/plex/PlexLoginInit";
import { ShellChallenge, RedirectChallenge } from "../api/Flows";
import { IdentificationChallenge } from "./stages/identification/IdentificationStage";
import { PasswordChallenge } from "./stages/password/PasswordStage";
@ -44,6 +45,7 @@ import { AccessDeniedChallenge } from "./access_denied/FlowAccessDenied";
import { PFSize } from "../elements/Spinner";
import { TITLE_DEFAULT } from "../constants";
import { configureSentry } from "../api/Sentry";
import { PlexAuthenticationChallenge } from "./sources/plex/PlexLoginInit";
@customElement("ak-flow-executor")
export class FlowExecutor extends LitElement implements StageHost {
@ -223,6 +225,8 @@ export class FlowExecutor extends LitElement implements StageHost {
return html`<ak-stage-authenticator-webauthn .host=${this} .challenge=${this.challenge as WebAuthnAuthenticatorRegisterChallenge}></ak-stage-authenticator-webauthn>`;
case "ak-stage-authenticator-validate":
return html`<ak-stage-authenticator-validate .host=${this} .challenge=${this.challenge as AuthenticatorValidateStageChallenge}></ak-stage-authenticator-validate>`;
case "ak-flow-sources-plex":
return html`<ak-flow-sources-plex .host=${this} .challenge=${this.challenge as PlexAuthenticationChallenge}></ak-flow-sources-plex>`;
default:
break;
}

View File

@ -0,0 +1,95 @@
import { VERSION } from "../../../constants";
export interface PlexPinResponse {
// Only has the fields we care about
authToken?: string;
code: string;
id: number;
}
export interface PlexResource {
name: string;
provides: string;
clientIdentifier: string;
}
export const DEFAULT_HEADERS = {
"Accept": "application/json",
"Content-Type": "application/json",
"X-Plex-Product": "authentik",
"X-Plex-Version": VERSION,
"X-Plex-Device-Vendor": "BeryJu.org",
};
export function popupCenterScreen(url: string, title: string, w: number, h: number): Window | null {
const top = (screen.height - h) / 4, left = (screen.width - w) / 2;
const popup = window.open(url, title, `scrollbars=yes,width=${w},height=${h},top=${top},left=${left}`);
return popup;
}
export class PlexAPIClient {
token: string;
constructor(token: string) {
this.token = token;
}
static async getPin(clientIdentifier: string): Promise<{ authUrl: string, pin: PlexPinResponse }> {
const headers = { ...DEFAULT_HEADERS, ...{
"X-Plex-Client-Identifier": clientIdentifier
}};
const pinResponse = await fetch("https://plex.tv/api/v2/pins.json?strong=true", {
method: "POST",
headers: headers
});
const pin: PlexPinResponse = await pinResponse.json();
return {
authUrl: `https://app.plex.tv/auth#!?clientID=${encodeURIComponent(clientIdentifier)}&code=${pin.code}`,
pin: pin
};
}
static async pinStatus(clientIdentifier: string, id: number): Promise<string | undefined> {
const headers = { ...DEFAULT_HEADERS, ...{
"X-Plex-Client-Identifier": clientIdentifier
}};
const pinResponse = await fetch(`https://plex.tv/api/v2/pins/${id}`, {
headers: headers
});
const pin: PlexPinResponse = await pinResponse.json();
return pin.authToken || "";
}
static async pinPoll(clientIdentifier: string, id: number): Promise<string> {
const executePoll = async (
resolve: (authToken: string) => void,
reject: (e: Error) => void
) => {
try {
const response = await PlexAPIClient.pinStatus(clientIdentifier, id);
if (response) {
resolve(response);
} else {
setTimeout(executePoll, 500, resolve, reject);
}
} catch (e) {
reject(e);
}
};
return new Promise(executePoll);
}
async getServers(): Promise<PlexResource[]> {
const resourcesResponse = await fetch(`https://plex.tv/api/v2/resources?X-Plex-Token=${this.token}&X-Plex-Client-Identifier=authentik`, {
headers: DEFAULT_HEADERS
});
const resources: PlexResource[] = await resourcesResponse.json();
return resources.filter(r => {
return r.provides === "server";
});
}
}

View File

@ -0,0 +1,69 @@
import { t } from "@lingui/macro";
import { Challenge } from "authentik-api";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import AKGlobal from "../../../authentik.css";
import { CSSResult, customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { BaseStage } from "../../stages/base";
import { PlexAPIClient, popupCenterScreen } from "./API";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { SourcesApi } from "authentik-api";
export interface PlexAuthenticationChallenge extends Challenge {
client_id: string;
slug: string;
}
@customElement("ak-flow-sources-plex")
export class PlexLoginInit extends BaseStage {
@property({ attribute: false })
challenge?: PlexAuthenticationChallenge;
static get styles(): CSSResult[] {
return [PFBase, PFLogin, PFForm, PFFormControl, PFButton, PFTitle, AKGlobal];
}
async firstUpdated(): Promise<void> {
const authInfo = await PlexAPIClient.getPin(this.challenge?.client_id || "");
const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
PlexAPIClient.pinPoll(this.challenge?.client_id || "", authInfo.pin.id).then(token => {
authWindow?.close();
new SourcesApi(DEFAULT_CONFIG).sourcesPlexRedeemToken({
data: {
plexToken: token,
},
slug: this.challenge?.slug || "",
}).then(r => {
window.location.assign(r.to);
});
});
}
render(): TemplateResult {
return html`<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">
${t`Authenticating with Plex...`}
</h1>
</header>
<div class="pf-c-login__main-body">
<form class="pf-c-form">
<ak-empty-state
?loading="${true}">
</ak-empty-state>
</form>
</div>
<footer class="pf-c-login__main-footer">
<ul class="pf-c-login__main-footer-links">
</ul>
</footer>`;
}
}

View File

@ -1,6 +1,8 @@
import { Challenge } from "authentik-api";
import { LitElement } from "lit-element";
export interface StageHost {
challenge?: Challenge;
submit<T>(formData?: T): Promise<void>;
}

View File

@ -35,7 +35,7 @@ export interface IdentificationChallenge extends Challenge {
export interface UILoginButton {
name: string;
url: string;
challenge: Challenge;
icon_url?: string;
}
@ -49,7 +49,11 @@ export class IdentificationStage extends BaseStage {
return [PFBase, PFLogin, PFForm, PFFormControl, PFTitle, PFButton, AKGlobal].concat(
css`
/* login page's icons */
.pf-c-login__main-footer-links-item-link img {
.pf-c-login__main-footer-links-item button {
background-color: transparent;
border: 0;
}
.pf-c-login__main-footer-links-item img {
fill: var(--pf-c-login__main-footer-links-item-link-svg--Fill);
width: 100px;
max-width: var(--pf-c-login__main-footer-links-item-link-svg--Width);
@ -131,9 +135,12 @@ export class IdentificationStage extends BaseStage {
icon = html`<img src="${source.icon_url}" alt="${source.name}">`;
}
return html`<li class="pf-c-login__main-footer-links-item">
<a href="${source.url}" class="pf-c-login__main-footer-links-item-link">
<button type="button" @click=${() => {
if (!this.host) return;
this.host.challenge = source.challenge;
}}>
${icon}
</a>
</button>
</li>`;
}

View File

@ -156,6 +156,10 @@ msgstr "Allow users to use Applications based on properties, enforce Password Cr
msgid "Allowed count"
msgstr "Allowed count"
#: src/pages/sources/plex/PlexSourceForm.ts:141
msgid "Allowed servers"
msgstr "Allowed servers"
#: src/pages/sources/saml/SAMLSourceForm.ts:144
msgid "Allows authentication flows initiated by the IdP. This can be a security risk, as no validation of the request ID is done."
msgstr "Allows authentication flows initiated by the IdP. This can be a security risk, as no validation of the request ID is done."
@ -277,11 +281,16 @@ msgstr "Attributes"
msgid "Audience"
msgstr "Audience"
#: src/flows/sources/plex/PlexLoginInit.ts:56
msgid "Authenticating with Plex..."
msgstr "Authenticating with Plex..."
#: src/pages/flows/FlowForm.ts:55
msgid "Authentication"
msgstr "Authentication"
#: src/pages/sources/oauth/OAuthSourceForm.ts:189
#: src/pages/sources/oauth/OAuthSourceForm.ts:211
#: src/pages/sources/plex/PlexSourceForm.ts:171
#: src/pages/sources/saml/SAMLSourceForm.ts:245
msgid "Authentication flow"
msgstr "Authentication flow"
@ -349,19 +358,19 @@ msgstr "Backup status"
msgid "Base DN"
msgstr "Base DN"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:213
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:217
msgid "Based on the Hashed User ID"
msgstr "Based on the Hashed User ID"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:219
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:223
msgid "Based on the User's Email. This is recommended over the UPN method."
msgstr "Based on the User's Email. This is recommended over the UPN method."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:222
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:226
msgid "Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains."
msgstr "Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:216
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:220
msgid "Based on the username"
msgstr "Based on the username"
@ -395,8 +404,8 @@ msgstr "Binding Type"
msgid "Build hash: {0}"
msgstr "Build hash: {0}"
#: src/pages/sources/SourcesListPage.ts:103
#: src/pages/sources/SourcesListPage.ts:105
#: src/pages/sources/SourcesListPage.ts:104
#: src/pages/sources/SourcesListPage.ts:106
msgid "Built-in"
msgstr "Built-in"
@ -473,13 +482,14 @@ msgstr "Change password"
msgid "Change your password"
msgstr "Change your password"
#: src/pages/applications/ApplicationViewPage.ts:123
#: src/pages/applications/ApplicationViewPage.ts:136
#: src/pages/flows/FlowViewPage.ts:110
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:136
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:135
#: src/pages/providers/saml/SAMLProviderViewPage.ts:129
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:113
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:133
#: src/pages/sources/plex/PlexSourceViewPage.ts:92
#: src/pages/sources/saml/SAMLSourceViewPage.ts:119
#: src/pages/users/UserViewPage.ts:185
msgid "Changelog"
@ -544,6 +554,7 @@ msgstr "Click to copy token"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:107
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:99
#: src/pages/sources/plex/PlexSourceForm.ts:135
msgid "Client ID"
msgstr "Client ID"
@ -611,7 +622,7 @@ msgstr "Configure how long refresh tokens and their id_tokens are valid for."
msgid "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected."
msgstr "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:251
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:255
msgid "Configure how the issuer field of the ID Token should be filled."
msgstr "Configure how the issuer field of the ID Token should be filled."
@ -623,7 +634,7 @@ msgstr "Configure settings relevant to your user profile."
msgid "Configure the maximum allowed time drift for an asseration."
msgstr "Configure the maximum allowed time drift for an asseration."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:226
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:230
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
@ -668,11 +679,11 @@ msgstr "Consider Objects matching this filter to be Groups."
msgid "Consider Objects matching this filter to be Users."
msgstr "Consider Objects matching this filter to be Users."
#: src/pages/sources/oauth/OAuthSourceForm.ts:126
#: src/pages/sources/oauth/OAuthSourceForm.ts:148
msgid "Consumer key"
msgstr "Consumer key"
#: src/pages/sources/oauth/OAuthSourceForm.ts:132
#: src/pages/sources/oauth/OAuthSourceForm.ts:154
msgid "Consumer secret"
msgstr "Consumer secret"
@ -744,8 +755,8 @@ msgstr "Copy Key"
#: src/pages/providers/ProviderListPage.ts:116
#: src/pages/providers/RelatedApplicationButton.ts:27
#: src/pages/providers/RelatedApplicationButton.ts:35
#: src/pages/sources/SourcesListPage.ts:113
#: src/pages/sources/SourcesListPage.ts:122
#: src/pages/sources/SourcesListPage.ts:114
#: src/pages/sources/SourcesListPage.ts:123
#: src/pages/stages/StageListPage.ts:119
#: src/pages/stages/StageListPage.ts:128
#: src/pages/stages/invitation/InvitationListPage.ts:77
@ -842,7 +853,7 @@ msgstr "Create provider"
#: src/pages/policies/PolicyListPage.ts:136
#: src/pages/property-mappings/PropertyMappingListPage.ts:125
#: src/pages/providers/ProviderListPage.ts:119
#: src/pages/sources/SourcesListPage.ts:125
#: src/pages/sources/SourcesListPage.ts:126
#: src/pages/stages/StageListPage.ts:131
msgid "Create {0}"
msgstr "Create {0}"
@ -898,7 +909,7 @@ msgstr "Define how notifications are sent to users, like Email or Webhook."
#: src/pages/policies/PolicyListPage.ts:115
#: src/pages/property-mappings/PropertyMappingListPage.ts:104
#: src/pages/providers/ProviderListPage.ts:98
#: src/pages/sources/SourcesListPage.ts:94
#: src/pages/sources/SourcesListPage.ts:95
#: src/pages/stages/StageListPage.ts:110
#: src/pages/stages/invitation/InvitationListPage.ts:68
#: src/pages/stages/prompt/PromptListPage.ts:87
@ -1008,7 +1019,7 @@ msgstr "Disable Static Tokens"
msgid "Disable Time-based OTP"
msgstr "Disable Time-based OTP"
#: src/pages/sources/SourcesListPage.ts:63
#: src/pages/sources/SourcesListPage.ts:64
msgid "Disabled"
msgstr "Disabled"
@ -1029,7 +1040,7 @@ msgstr "Download"
msgid "Dummy stage used for testing. Shows a simple continue button and always passes."
msgstr "Dummy stage used for testing. Shows a simple continue button and always passes."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:244
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:248
msgid "Each provider has a different issuer, based on the application slug."
msgstr "Each provider has a different issuer, based on the application slug."
@ -1049,9 +1060,10 @@ msgstr "Each provider has a different issuer, based on the application slug."
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:128
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:127
#: src/pages/providers/saml/SAMLProviderViewPage.ts:121
#: src/pages/sources/SourcesListPage.ts:82
#: src/pages/sources/SourcesListPage.ts:83
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:105
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:125
#: src/pages/sources/plex/PlexSourceViewPage.ts:84
#: src/pages/sources/saml/SAMLSourceViewPage.ts:111
#: src/pages/stages/StageListPage.ts:98
#: src/pages/stages/prompt/PromptListPage.ts:75
@ -1086,7 +1098,7 @@ msgstr "Edit User"
msgid "Either no applications are defined, or you don't have access to any."
msgstr "Either no applications are defined, or you don't have access to any."
#: src/flows/stages/identification/IdentificationStage.ts:138
#: src/flows/stages/identification/IdentificationStage.ts:146
#: src/pages/events/TransportForm.ts:46
#: src/pages/stages/identification/IdentificationStageForm.ts:81
#: src/pages/user-settings/UserDetailsPage.ts:71
@ -1099,7 +1111,7 @@ msgstr "Email"
msgid "Email address"
msgstr "Email address"
#: src/flows/stages/identification/IdentificationStage.ts:145
#: src/flows/stages/identification/IdentificationStage.ts:153
msgid "Email or username"
msgstr "Email or username"
@ -1136,6 +1148,7 @@ msgstr "Enable this if you don't want to use this provider as a proxy, and want
#: src/pages/policies/PolicyBindingForm.ts:199
#: src/pages/sources/ldap/LDAPSourceForm.ts:69
#: src/pages/sources/oauth/OAuthSourceForm.ts:115
#: src/pages/sources/plex/PlexSourceForm.ts:102
#: src/pages/sources/saml/SAMLSourceForm.ts:69
msgid "Enabled"
msgstr "Enabled"
@ -1144,7 +1157,8 @@ msgstr "Enabled"
msgid "Enrollment"
msgstr "Enrollment"
#: src/pages/sources/oauth/OAuthSourceForm.ts:210
#: src/pages/sources/oauth/OAuthSourceForm.ts:232
#: src/pages/sources/plex/PlexSourceForm.ts:192
#: src/pages/sources/saml/SAMLSourceForm.ts:266
#: src/pages/stages/identification/IdentificationStageForm.ts:106
msgid "Enrollment flow"
@ -1356,17 +1370,20 @@ msgstr "Flow"
msgid "Flow Overview"
msgstr "Flow Overview"
#: src/pages/sources/oauth/OAuthSourceForm.ts:185
#: src/pages/sources/oauth/OAuthSourceForm.ts:207
#: src/pages/sources/plex/PlexSourceForm.ts:167
#: src/pages/sources/saml/SAMLSourceForm.ts:220
msgid "Flow settings"
msgstr "Flow settings"
#: src/pages/sources/oauth/OAuthSourceForm.ts:207
#: src/pages/sources/oauth/OAuthSourceForm.ts:229
#: src/pages/sources/plex/PlexSourceForm.ts:189
#: src/pages/sources/saml/SAMLSourceForm.ts:263
msgid "Flow to use when authenticating existing users."
msgstr "Flow to use when authenticating existing users."
#: src/pages/sources/oauth/OAuthSourceForm.ts:228
#: src/pages/sources/oauth/OAuthSourceForm.ts:250
#: src/pages/sources/plex/PlexSourceForm.ts:210
#: src/pages/sources/saml/SAMLSourceForm.ts:284
msgid "Flow to use when enrolling new users."
msgstr "Flow to use when enrolling new users."
@ -1410,7 +1427,7 @@ msgstr "Force the user to configure an authenticator"
msgid "Forgot password?"
msgstr "Forgot password?"
#: src/flows/stages/identification/IdentificationStage.ts:124
#: src/flows/stages/identification/IdentificationStage.ts:132
msgid "Forgot username or password?"
msgstr "Forgot username or password?"
@ -1510,6 +1527,7 @@ msgstr "Hide managed mappings"
#: src/pages/providers/saml/SAMLProviderForm.ts:177
#: src/pages/sources/ldap/LDAPSourceForm.ts:167
#: src/pages/sources/ldap/LDAPSourceForm.ts:193
#: src/pages/sources/plex/PlexSourceForm.ts:154
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:114
#: src/pages/stages/identification/IdentificationStageForm.ts:85
#: src/pages/stages/password/PasswordStageForm.ts:86
@ -1580,11 +1598,11 @@ msgstr "Import certificates of external providers or create certificates to sign
msgid "In case you can't access any other method."
msgstr "In case you can't access any other method."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:236
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:240
msgid "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint."
msgstr "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:233
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:237
msgid "Include claims in id_token"
msgstr "Include claims in id_token"
@ -1628,7 +1646,7 @@ msgstr "Is superuser"
msgid "Issuer"
msgstr "Issuer"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:239
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:243
msgid "Issuer mode"
msgstr "Issuer mode"
@ -1636,7 +1654,7 @@ msgstr "Issuer mode"
msgid "JWT Algorithm"
msgstr "JWT Algorithm"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:205
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:209
msgid "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
msgstr "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
@ -1680,6 +1698,11 @@ msgstr "Last seen: {0}"
msgid "Last sync: {0}"
msgstr "Last sync: {0}"
#: src/pages/applications/ApplicationViewPage.ts:114
#: src/pages/applications/ApplicationViewPage.ts:119
msgid "Launch"
msgstr "Launch"
#: src/pages/applications/ApplicationForm.ts:159
msgid "Launch URL"
msgstr "Launch URL"
@ -1692,9 +1715,28 @@ msgstr "Let the user identify themselves with their username or Email address."
msgid "Library"
msgstr "Library"
#: src/pages/sources/oauth/OAuthSourceForm.ts:128
#: src/pages/sources/plex/PlexSourceForm.ts:115
msgid "Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses"
msgstr "Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses"
#: src/pages/sources/oauth/OAuthSourceForm.ts:134
#: src/pages/sources/plex/PlexSourceForm.ts:121
msgid "Link to a user with identical username address. Can have security implications when a username is used with another source."
msgstr "Link to a user with identical username address. Can have security implications when a username is used with another source."
#: src/pages/sources/oauth/OAuthSourceForm.ts:125
#: src/pages/sources/plex/PlexSourceForm.ts:112
msgid "Link users on unique identifier"
msgstr "Link users on unique identifier"
#: src/pages/sources/plex/PlexSourceForm.ts:159
msgid "Load servers"
msgstr "Load servers"
#: src/elements/table/Table.ts:120
#: src/flows/FlowExecutor.ts:167
#: src/flows/FlowExecutor.ts:213
#: src/flows/FlowExecutor.ts:168
#: src/flows/FlowExecutor.ts:216
#: src/flows/access_denied/FlowAccessDenied.ts:27
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts:43
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts:33
@ -1705,7 +1747,7 @@ msgstr "Library"
#: src/flows/stages/consent/ConsentStage.ts:28
#: src/flows/stages/dummy/DummyStage.ts:27
#: src/flows/stages/email/EmailStage.ts:26
#: src/flows/stages/identification/IdentificationStage.ts:170
#: src/flows/stages/identification/IdentificationStage.ts:179
#: src/flows/stages/password/PasswordStage.ts:31
#: src/flows/stages/prompt/PromptStage.ts:126
#: src/pages/applications/ApplicationViewPage.ts:43
@ -1736,7 +1778,7 @@ msgstr "Loading"
#: src/pages/property-mappings/PropertyMappingTestForm.ts:61
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:74
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:185
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:203
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:207
#: src/pages/providers/proxy/ProxyProviderForm.ts:116
#: src/pages/providers/proxy/ProxyProviderForm.ts:168
#: src/pages/providers/saml/SAMLProviderForm.ts:71
@ -1747,9 +1789,11 @@ msgstr "Loading"
#: src/pages/providers/saml/SAMLProviderImportForm.ts:55
#: src/pages/sources/ldap/LDAPSourceForm.ts:164
#: src/pages/sources/ldap/LDAPSourceForm.ts:190
#: src/pages/sources/oauth/OAuthSourceForm.ts:177
#: src/pages/sources/oauth/OAuthSourceForm.ts:205
#: src/pages/sources/oauth/OAuthSourceForm.ts:226
#: src/pages/sources/oauth/OAuthSourceForm.ts:199
#: src/pages/sources/oauth/OAuthSourceForm.ts:227
#: src/pages/sources/oauth/OAuthSourceForm.ts:248
#: src/pages/sources/plex/PlexSourceForm.ts:187
#: src/pages/sources/plex/PlexSourceForm.ts:208
#: src/pages/sources/saml/SAMLSourceForm.ts:126
#: src/pages/sources/saml/SAMLSourceForm.ts:240
#: src/pages/sources/saml/SAMLSourceForm.ts:261
@ -1780,7 +1824,7 @@ msgstr "Log the currently pending user in."
msgid "Login password is synced from LDAP into authentik automatically. Enable this option only to write password changes in authentik back to LDAP."
msgstr "Login password is synced from LDAP into authentik automatically. Enable this option only to write password changes in authentik back to LDAP."
#: src/flows/stages/identification/IdentificationStage.ts:182
#: src/flows/stages/identification/IdentificationStage.ts:191
msgid "Login to continue to {0}."
msgstr "Login to continue to {0}."
@ -1789,7 +1833,7 @@ msgid "Logins"
msgstr "Logins"
#: src/pages/admin-overview/AdminOverviewPage.ts:40
#: src/pages/applications/ApplicationViewPage.ts:115
#: src/pages/applications/ApplicationViewPage.ts:128
msgid "Logins over the last 24 hours"
msgstr "Logins over the last 24 hours"
@ -1913,11 +1957,13 @@ msgstr "Monitor"
#: src/pages/providers/saml/SAMLProviderForm.ts:53
#: src/pages/providers/saml/SAMLProviderImportForm.ts:38
#: src/pages/providers/saml/SAMLProviderViewPage.ts:66
#: src/pages/sources/SourcesListPage.ts:51
#: src/pages/sources/SourcesListPage.ts:52
#: src/pages/sources/ldap/LDAPSourceForm.ts:54
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:64
#: src/pages/sources/oauth/OAuthSourceForm.ts:100
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:64
#: src/pages/sources/plex/PlexSourceForm.ts:87
#: src/pages/sources/plex/PlexSourceViewPage.ts:63
#: src/pages/sources/saml/SAMLSourceForm.ts:54
#: src/pages/sources/saml/SAMLSourceViewPage.ts:66
#: src/pages/stages/StageListPage.ts:65
@ -1957,7 +2003,7 @@ msgstr "NameID Policy"
msgid "NameID Property Mapping"
msgstr "NameID Property Mapping"
#: src/flows/stages/identification/IdentificationStage.ts:119
#: src/flows/stages/identification/IdentificationStage.ts:127
msgid "Need an account?"
msgstr "Need an account?"
@ -2227,6 +2273,7 @@ msgstr "Outposts are deployments of authentik components to support different en
#: src/pages/providers/saml/SAMLProviderViewPage.ts:58
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:56
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:56
#: src/pages/sources/plex/PlexSourceViewPage.ts:55
#: src/pages/sources/saml/SAMLSourceViewPage.ts:58
#: src/pages/users/UserViewPage.ts:74
msgid "Overview"
@ -2297,7 +2344,7 @@ msgstr "Policies without binding exist."
msgid "Policy"
msgstr "Policy"
#: src/pages/applications/ApplicationViewPage.ts:134
#: src/pages/applications/ApplicationViewPage.ts:147
#: src/pages/flows/FlowViewPage.ts:101
msgid "Policy / Group / User Bindings"
msgstr "Policy / Group / User Bindings"
@ -2307,6 +2354,7 @@ msgid "Policy / User / Group"
msgstr "Policy / User / Group"
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:144
#: src/pages/sources/plex/PlexSourceViewPage.ts:103
#: src/pages/sources/saml/SAMLSourceViewPage.ts:150
msgid "Policy Bindings"
msgstr "Policy Bindings"
@ -2348,7 +2396,7 @@ msgstr "Post binding"
msgid "Post binding (auto-submit)"
msgstr "Post binding (auto-submit)"
#: src/flows/FlowExecutor.ts:255
#: src/flows/FlowExecutor.ts:258
msgid "Powered by authentik"
msgstr "Powered by authentik"
@ -2411,7 +2459,8 @@ msgstr "Property mappings used to user creation."
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:81
#: src/pages/providers/proxy/ProxyProviderForm.ts:123
#: src/pages/providers/saml/SAMLProviderForm.ts:78
#: src/pages/sources/oauth/OAuthSourceForm.ts:122
#: src/pages/sources/oauth/OAuthSourceForm.ts:144
#: src/pages/sources/plex/PlexSourceForm.ts:131
#: src/pages/sources/saml/SAMLSourceForm.ts:76
msgid "Protocol settings"
msgstr "Protocol settings"
@ -2433,7 +2482,7 @@ msgstr "Provider"
msgid "Provider Type"
msgstr "Provider Type"
#: src/pages/sources/oauth/OAuthSourceForm.ts:138
#: src/pages/sources/oauth/OAuthSourceForm.ts:160
msgid "Provider type"
msgstr "Provider type"
@ -2602,7 +2651,7 @@ msgstr "Retry Task"
msgid "Retry authentication"
msgstr "Retry authentication"
#: src/flows/FlowExecutor.ts:145
#: src/flows/FlowExecutor.ts:146
msgid "Return"
msgstr "Return"
@ -2665,7 +2714,7 @@ msgstr "SMTP Username"
msgid "SSO URL"
msgstr "SSO URL"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:247
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:251
msgid "Same identifier is used for all providers"
msgstr "Same identifier is used for all providers"
@ -2710,7 +2759,7 @@ msgstr "Select all rows"
msgid "Select an identification method."
msgstr "Select an identification method."
#: src/flows/stages/identification/IdentificationStage.ts:134
#: src/flows/stages/identification/IdentificationStage.ts:142
msgid "Select one of the sources below to login."
msgstr "Select one of the sources below to login."
@ -2722,6 +2771,10 @@ msgstr "Select users to add"
msgid "Select which scopes can be used by the client. The client stil has to specify the scope to access the data."
msgstr "Select which scopes can be used by the client. The client stil has to specify the scope to access the data."
#: src/pages/sources/plex/PlexSourceForm.ts:153
msgid "Select which server a user has to be a member of to be allowed to authenticate."
msgstr "Select which server a user has to be a member of to be allowed to authenticate."
#: src/pages/events/RuleForm.ts:92
msgid "Select which transports should be used to notify the user. If none are selected, the notification will only be shown in the authentik UI."
msgstr "Select which transports should be used to notify the user. If none are selected, the notification will only be shown in the authentik UI."
@ -2820,7 +2873,7 @@ msgstr "Show matched user"
msgid "Shown as the Title in Flow pages."
msgstr "Shown as the Title in Flow pages."
#: src/flows/stages/identification/IdentificationStage.ts:120
#: src/flows/stages/identification/IdentificationStage.ts:128
msgid "Sign up."
msgstr "Sign up."
@ -2841,6 +2894,10 @@ msgstr "Signing keypair"
msgid "Single Prompts that can be used for Prompt Stages."
msgstr "Single Prompts that can be used for Prompt Stages."
#: src/pages/stages/invitation/InvitationForm.ts:62
msgid "Single use"
msgstr "Single use"
#: src/pages/providers/proxy/ProxyProviderForm.ts:173
msgid "Skip path regex"
msgstr "Skip path regex"
@ -2850,16 +2907,17 @@ msgstr "Skip path regex"
#: src/pages/flows/FlowForm.ts:94
#: src/pages/sources/ldap/LDAPSourceForm.ts:60
#: src/pages/sources/oauth/OAuthSourceForm.ts:106
#: src/pages/sources/plex/PlexSourceForm.ts:93
#: src/pages/sources/saml/SAMLSourceForm.ts:60
msgid "Slug"
msgstr "Slug"
#: src/flows/FlowExecutor.ts:138
#: src/flows/FlowExecutor.ts:139
msgid "Something went wrong! Please try again later."
msgstr "Something went wrong! Please try again later."
#: src/pages/providers/ProviderListPage.ts:91
#: src/pages/sources/SourcesListPage.ts:87
#: src/pages/sources/SourcesListPage.ts:88
msgid "Source"
msgstr "Source"
@ -2868,11 +2926,11 @@ msgid "Source {0}"
msgstr "Source {0}"
#: src/interfaces/AdminInterface.ts:20
#: src/pages/sources/SourcesListPage.ts:30
#: src/pages/sources/SourcesListPage.ts:31
msgid "Sources"
msgstr "Sources"
#: src/pages/sources/SourcesListPage.ts:33
#: src/pages/sources/SourcesListPage.ts:34
msgid "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
msgstr "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
@ -2979,7 +3037,7 @@ msgstr "Stop impersonation"
msgid "Subject"
msgstr "Subject"
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:208
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:212
msgid "Subject mode"
msgstr "Subject mode"
@ -3069,6 +3127,7 @@ msgstr "Successfully created service-connection."
#: src/pages/sources/ldap/LDAPSourceForm.ts:47
#: src/pages/sources/oauth/OAuthSourceForm.ts:51
#: src/pages/sources/plex/PlexSourceForm.ts:60
#: src/pages/sources/saml/SAMLSourceForm.ts:47
msgid "Successfully created source."
msgstr "Successfully created source."
@ -3205,6 +3264,7 @@ msgstr "Successfully updated service-connection."
#: src/pages/sources/ldap/LDAPSourceForm.ts:44
#: src/pages/sources/oauth/OAuthSourceForm.ts:48
#: src/pages/sources/plex/PlexSourceForm.ts:57
#: src/pages/sources/saml/SAMLSourceForm.ts:44
msgid "Successfully updated source."
msgstr "Successfully updated source."
@ -3363,6 +3423,7 @@ msgid "These bindings control which users can access this flow."
msgstr "These bindings control which users can access this flow."
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:146
#: src/pages/sources/plex/PlexSourceViewPage.ts:105
#: src/pages/sources/saml/SAMLSourceViewPage.ts:152
msgid ""
"These bindings control which users can access this source.\n"
@ -3371,7 +3432,7 @@ msgstr ""
"These bindings control which users can access this source.\n"
"You can only use policies here as access is checked before the user is authenticated."
#: src/pages/applications/ApplicationViewPage.ts:136
#: src/pages/applications/ApplicationViewPage.ts:149
msgid "These policies control which users can access this application."
msgstr "These policies control which users can access this application."
@ -3460,7 +3521,7 @@ msgstr "Transports"
#: src/pages/policies/PolicyListPage.ts:57
#: src/pages/property-mappings/PropertyMappingListPage.ts:55
#: src/pages/providers/ProviderListPage.ts:54
#: src/pages/sources/SourcesListPage.ts:52
#: src/pages/sources/SourcesListPage.ts:53
#: src/pages/stages/prompt/PromptForm.ts:97
#: src/pages/stages/prompt/PromptListPage.ts:48
msgid "Type"
@ -3539,9 +3600,10 @@ msgstr "Up-to-date!"
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:118
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:117
#: src/pages/providers/saml/SAMLProviderViewPage.ts:111
#: src/pages/sources/SourcesListPage.ts:69
#: src/pages/sources/SourcesListPage.ts:70
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:95
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:115
#: src/pages/sources/plex/PlexSourceViewPage.ts:74
#: src/pages/sources/saml/SAMLSourceViewPage.ts:101
#: src/pages/stages/StageListPage.ts:85
#: src/pages/stages/prompt/PromptListPage.ts:67
@ -3602,6 +3664,10 @@ msgstr "Update OAuth2 Provider"
msgid "Update Outpost"
msgstr "Update Outpost"
#: src/pages/sources/plex/PlexSourceViewPage.ts:77
msgid "Update Plex Source"
msgstr "Update Plex Source"
#: src/pages/stages/prompt/PromptListPage.ts:70
msgid "Update Prompt"
msgstr "Update Prompt"
@ -3642,7 +3708,7 @@ msgstr "Update details"
#: src/pages/policies/PolicyListPage.ts:80
#: src/pages/property-mappings/PropertyMappingListPage.ts:69
#: src/pages/providers/ProviderListPage.ts:76
#: src/pages/sources/SourcesListPage.ts:72
#: src/pages/sources/SourcesListPage.ts:73
#: src/pages/stages/StageListPage.ts:88
#: src/pages/users/UserActiveForm.ts:41
msgid "Update {0}"
@ -3672,6 +3738,16 @@ msgstr "Use a security key to prove your identity."
msgid "Use global settings"
msgstr "Use global settings"
#: src/pages/sources/oauth/OAuthSourceForm.ts:131
#: src/pages/sources/plex/PlexSourceForm.ts:118
msgid "Use the user's email address, but deny enrollment when the email address already exists."
msgstr "Use the user's email address, but deny enrollment when the email address already exists."
#: src/pages/sources/oauth/OAuthSourceForm.ts:137
#: src/pages/sources/plex/PlexSourceForm.ts:124
msgid "Use the user's username, but deny enrollment when the username already exists."
msgstr "Use the user's username, but deny enrollment when the username already exists."
#: src/elements/events/ObjectChangelog.ts:39
#: src/elements/events/UserEvents.ts:36
#: src/pages/events/EventInfo.ts:83
@ -3712,6 +3788,11 @@ msgstr "User events"
msgid "User fields"
msgstr "User fields"
#: src/pages/sources/oauth/OAuthSourceForm.ts:120
#: src/pages/sources/plex/PlexSourceForm.ts:107
msgid "User matching mode"
msgstr "User matching mode"
#: src/pages/sources/ldap/LDAPSourceForm.ts:208
msgid "User object filter"
msgstr "User object filter"
@ -3746,7 +3827,7 @@ msgstr "User/Group Attribute used for the user part of the HTTP-Basic Header. If
msgid "Userinfo URL"
msgstr "Userinfo URL"
#: src/flows/stages/identification/IdentificationStage.ts:142
#: src/flows/stages/identification/IdentificationStage.ts:150
#: src/pages/stages/identification/IdentificationStageForm.ts:78
#: src/pages/user-settings/UserDetailsPage.ts:57
#: src/pages/users/UserForm.ts:47
@ -3877,6 +3958,10 @@ msgstr "When a valid username/email has been entered, and this option is enabled
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr "When enabled, global Email connection settings will be used and connection settings below will be ignored."
#: src/pages/stages/invitation/InvitationForm.ts:66
msgid "When enabled, the invitation will be deleted after usage."
msgstr "When enabled, the invitation will be deleted after usage."
#: src/pages/stages/identification/IdentificationStageForm.ts:94
msgid "When enabled, user fields are matched regardless of their casing."
msgstr "When enabled, user fields are matched regardless of their casing."
@ -3895,7 +3980,7 @@ msgstr "When selected, incoming assertion's Signatures will be validated against
msgid "When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged."
msgstr "When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged."
#: src/flows/FlowExecutor.ts:134
#: src/flows/FlowExecutor.ts:135
msgid "Whoops!"
msgstr "Whoops!"

View File

@ -156,6 +156,10 @@ msgstr ""
msgid "Allowed count"
msgstr ""
#: src/pages/sources/plex/PlexSourceForm.ts:141
msgid "Allowed servers"
msgstr ""
#: src/pages/sources/saml/SAMLSourceForm.ts:144
msgid "Allows authentication flows initiated by the IdP. This can be a security risk, as no validation of the request ID is done."
msgstr ""
@ -273,11 +277,16 @@ msgstr ""
msgid "Audience"
msgstr ""
#: src/flows/sources/plex/PlexLoginInit.ts:56
msgid "Authenticating with Plex..."
msgstr ""
#: src/pages/flows/FlowForm.ts:55
msgid "Authentication"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:189
#: src/pages/sources/oauth/OAuthSourceForm.ts:211
#: src/pages/sources/plex/PlexSourceForm.ts:171
#: src/pages/sources/saml/SAMLSourceForm.ts:245
msgid "Authentication flow"
msgstr ""
@ -345,19 +354,19 @@ msgstr ""
msgid "Base DN"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:213
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:217
msgid "Based on the Hashed User ID"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:219
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:223
msgid "Based on the User's Email. This is recommended over the UPN method."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:222
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:226
msgid "Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:216
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:220
msgid "Based on the username"
msgstr ""
@ -391,8 +400,8 @@ msgstr ""
msgid "Build hash: {0}"
msgstr ""
#: src/pages/sources/SourcesListPage.ts:103
#: src/pages/sources/SourcesListPage.ts:105
#: src/pages/sources/SourcesListPage.ts:104
#: src/pages/sources/SourcesListPage.ts:106
msgid "Built-in"
msgstr ""
@ -469,13 +478,14 @@ msgstr ""
msgid "Change your password"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts:123
#: src/pages/applications/ApplicationViewPage.ts:136
#: src/pages/flows/FlowViewPage.ts:110
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:136
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:135
#: src/pages/providers/saml/SAMLProviderViewPage.ts:129
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:113
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:133
#: src/pages/sources/plex/PlexSourceViewPage.ts:92
#: src/pages/sources/saml/SAMLSourceViewPage.ts:119
#: src/pages/users/UserViewPage.ts:185
msgid "Changelog"
@ -538,6 +548,7 @@ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:107
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:99
#: src/pages/sources/plex/PlexSourceForm.ts:135
msgid "Client ID"
msgstr ""
@ -605,7 +616,7 @@ msgstr ""
msgid "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:251
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:255
msgid "Configure how the issuer field of the ID Token should be filled."
msgstr ""
@ -617,7 +628,7 @@ msgstr ""
msgid "Configure the maximum allowed time drift for an asseration."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:226
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:230
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
msgstr ""
@ -662,11 +673,11 @@ msgstr ""
msgid "Consider Objects matching this filter to be Users."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:126
#: src/pages/sources/oauth/OAuthSourceForm.ts:148
msgid "Consumer key"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:132
#: src/pages/sources/oauth/OAuthSourceForm.ts:154
msgid "Consumer secret"
msgstr ""
@ -738,8 +749,8 @@ msgstr ""
#: src/pages/providers/ProviderListPage.ts:116
#: src/pages/providers/RelatedApplicationButton.ts:27
#: src/pages/providers/RelatedApplicationButton.ts:35
#: src/pages/sources/SourcesListPage.ts:113
#: src/pages/sources/SourcesListPage.ts:122
#: src/pages/sources/SourcesListPage.ts:114
#: src/pages/sources/SourcesListPage.ts:123
#: src/pages/stages/StageListPage.ts:119
#: src/pages/stages/StageListPage.ts:128
#: src/pages/stages/invitation/InvitationListPage.ts:77
@ -836,7 +847,7 @@ msgstr ""
#: src/pages/policies/PolicyListPage.ts:136
#: src/pages/property-mappings/PropertyMappingListPage.ts:125
#: src/pages/providers/ProviderListPage.ts:119
#: src/pages/sources/SourcesListPage.ts:125
#: src/pages/sources/SourcesListPage.ts:126
#: src/pages/stages/StageListPage.ts:131
msgid "Create {0}"
msgstr ""
@ -892,7 +903,7 @@ msgstr ""
#: src/pages/policies/PolicyListPage.ts:115
#: src/pages/property-mappings/PropertyMappingListPage.ts:104
#: src/pages/providers/ProviderListPage.ts:98
#: src/pages/sources/SourcesListPage.ts:94
#: src/pages/sources/SourcesListPage.ts:95
#: src/pages/stages/StageListPage.ts:110
#: src/pages/stages/invitation/InvitationListPage.ts:68
#: src/pages/stages/prompt/PromptListPage.ts:87
@ -1000,7 +1011,7 @@ msgstr ""
msgid "Disable Time-based OTP"
msgstr ""
#: src/pages/sources/SourcesListPage.ts:63
#: src/pages/sources/SourcesListPage.ts:64
msgid "Disabled"
msgstr ""
@ -1021,7 +1032,7 @@ msgstr ""
msgid "Dummy stage used for testing. Shows a simple continue button and always passes."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:244
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:248
msgid "Each provider has a different issuer, based on the application slug."
msgstr ""
@ -1041,9 +1052,10 @@ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:128
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:127
#: src/pages/providers/saml/SAMLProviderViewPage.ts:121
#: src/pages/sources/SourcesListPage.ts:82
#: src/pages/sources/SourcesListPage.ts:83
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:105
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:125
#: src/pages/sources/plex/PlexSourceViewPage.ts:84
#: src/pages/sources/saml/SAMLSourceViewPage.ts:111
#: src/pages/stages/StageListPage.ts:98
#: src/pages/stages/prompt/PromptListPage.ts:75
@ -1078,7 +1090,7 @@ msgstr ""
msgid "Either no applications are defined, or you don't have access to any."
msgstr ""
#: src/flows/stages/identification/IdentificationStage.ts:138
#: src/flows/stages/identification/IdentificationStage.ts:146
#: src/pages/events/TransportForm.ts:46
#: src/pages/stages/identification/IdentificationStageForm.ts:81
#: src/pages/user-settings/UserDetailsPage.ts:71
@ -1091,7 +1103,7 @@ msgstr ""
msgid "Email address"
msgstr ""
#: src/flows/stages/identification/IdentificationStage.ts:145
#: src/flows/stages/identification/IdentificationStage.ts:153
msgid "Email or username"
msgstr ""
@ -1128,6 +1140,7 @@ msgstr ""
#: src/pages/policies/PolicyBindingForm.ts:199
#: src/pages/sources/ldap/LDAPSourceForm.ts:69
#: src/pages/sources/oauth/OAuthSourceForm.ts:115
#: src/pages/sources/plex/PlexSourceForm.ts:102
#: src/pages/sources/saml/SAMLSourceForm.ts:69
msgid "Enabled"
msgstr ""
@ -1136,7 +1149,8 @@ msgstr ""
msgid "Enrollment"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:210
#: src/pages/sources/oauth/OAuthSourceForm.ts:232
#: src/pages/sources/plex/PlexSourceForm.ts:192
#: src/pages/sources/saml/SAMLSourceForm.ts:266
#: src/pages/stages/identification/IdentificationStageForm.ts:106
msgid "Enrollment flow"
@ -1348,17 +1362,20 @@ msgstr ""
msgid "Flow Overview"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:185
#: src/pages/sources/oauth/OAuthSourceForm.ts:207
#: src/pages/sources/plex/PlexSourceForm.ts:167
#: src/pages/sources/saml/SAMLSourceForm.ts:220
msgid "Flow settings"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:207
#: src/pages/sources/oauth/OAuthSourceForm.ts:229
#: src/pages/sources/plex/PlexSourceForm.ts:189
#: src/pages/sources/saml/SAMLSourceForm.ts:263
msgid "Flow to use when authenticating existing users."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:228
#: src/pages/sources/oauth/OAuthSourceForm.ts:250
#: src/pages/sources/plex/PlexSourceForm.ts:210
#: src/pages/sources/saml/SAMLSourceForm.ts:284
msgid "Flow to use when enrolling new users."
msgstr ""
@ -1402,7 +1419,7 @@ msgstr ""
msgid "Forgot password?"
msgstr ""
#: src/flows/stages/identification/IdentificationStage.ts:124
#: src/flows/stages/identification/IdentificationStage.ts:132
msgid "Forgot username or password?"
msgstr ""
@ -1502,6 +1519,7 @@ msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:177
#: src/pages/sources/ldap/LDAPSourceForm.ts:167
#: src/pages/sources/ldap/LDAPSourceForm.ts:193
#: src/pages/sources/plex/PlexSourceForm.ts:154
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts:114
#: src/pages/stages/identification/IdentificationStageForm.ts:85
#: src/pages/stages/password/PasswordStageForm.ts:86
@ -1572,11 +1590,11 @@ msgstr ""
msgid "In case you can't access any other method."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:236
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:240
msgid "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint."
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:233
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:237
msgid "Include claims in id_token"
msgstr ""
@ -1620,7 +1638,7 @@ msgstr ""
msgid "Issuer"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:239
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:243
msgid "Issuer mode"
msgstr ""
@ -1628,7 +1646,7 @@ msgstr ""
msgid "JWT Algorithm"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:205
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:209
msgid "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
msgstr ""
@ -1672,6 +1690,11 @@ msgstr ""
msgid "Last sync: {0}"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts:114
#: src/pages/applications/ApplicationViewPage.ts:119
msgid "Launch"
msgstr ""
#: src/pages/applications/ApplicationForm.ts:159
msgid "Launch URL"
msgstr ""
@ -1684,9 +1707,28 @@ msgstr ""
msgid "Library"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:128
#: src/pages/sources/plex/PlexSourceForm.ts:115
msgid "Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:134
#: src/pages/sources/plex/PlexSourceForm.ts:121
msgid "Link to a user with identical username address. Can have security implications when a username is used with another source."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:125
#: src/pages/sources/plex/PlexSourceForm.ts:112
msgid "Link users on unique identifier"
msgstr ""
#: src/pages/sources/plex/PlexSourceForm.ts:159
msgid "Load servers"
msgstr ""
#: src/elements/table/Table.ts:120
#: src/flows/FlowExecutor.ts:167
#: src/flows/FlowExecutor.ts:213
#: src/flows/FlowExecutor.ts:168
#: src/flows/FlowExecutor.ts:216
#: src/flows/access_denied/FlowAccessDenied.ts:27
#: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts:43
#: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts:33
@ -1697,7 +1739,7 @@ msgstr ""
#: src/flows/stages/consent/ConsentStage.ts:28
#: src/flows/stages/dummy/DummyStage.ts:27
#: src/flows/stages/email/EmailStage.ts:26
#: src/flows/stages/identification/IdentificationStage.ts:170
#: src/flows/stages/identification/IdentificationStage.ts:179
#: src/flows/stages/password/PasswordStage.ts:31
#: src/flows/stages/prompt/PromptStage.ts:126
#: src/pages/applications/ApplicationViewPage.ts:43
@ -1728,7 +1770,7 @@ msgstr ""
#: src/pages/property-mappings/PropertyMappingTestForm.ts:61
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:74
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:185
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:203
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:207
#: src/pages/providers/proxy/ProxyProviderForm.ts:116
#: src/pages/providers/proxy/ProxyProviderForm.ts:168
#: src/pages/providers/saml/SAMLProviderForm.ts:71
@ -1739,9 +1781,11 @@ msgstr ""
#: src/pages/providers/saml/SAMLProviderImportForm.ts:55
#: src/pages/sources/ldap/LDAPSourceForm.ts:164
#: src/pages/sources/ldap/LDAPSourceForm.ts:190
#: src/pages/sources/oauth/OAuthSourceForm.ts:177
#: src/pages/sources/oauth/OAuthSourceForm.ts:205
#: src/pages/sources/oauth/OAuthSourceForm.ts:226
#: src/pages/sources/oauth/OAuthSourceForm.ts:199
#: src/pages/sources/oauth/OAuthSourceForm.ts:227
#: src/pages/sources/oauth/OAuthSourceForm.ts:248
#: src/pages/sources/plex/PlexSourceForm.ts:187
#: src/pages/sources/plex/PlexSourceForm.ts:208
#: src/pages/sources/saml/SAMLSourceForm.ts:126
#: src/pages/sources/saml/SAMLSourceForm.ts:240
#: src/pages/sources/saml/SAMLSourceForm.ts:261
@ -1772,7 +1816,7 @@ msgstr ""
msgid "Login password is synced from LDAP into authentik automatically. Enable this option only to write password changes in authentik back to LDAP."
msgstr ""
#: src/flows/stages/identification/IdentificationStage.ts:182
#: src/flows/stages/identification/IdentificationStage.ts:191
msgid "Login to continue to {0}."
msgstr ""
@ -1781,7 +1825,7 @@ msgid "Logins"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts:40
#: src/pages/applications/ApplicationViewPage.ts:115
#: src/pages/applications/ApplicationViewPage.ts:128
msgid "Logins over the last 24 hours"
msgstr ""
@ -1905,11 +1949,13 @@ msgstr ""
#: src/pages/providers/saml/SAMLProviderForm.ts:53
#: src/pages/providers/saml/SAMLProviderImportForm.ts:38
#: src/pages/providers/saml/SAMLProviderViewPage.ts:66
#: src/pages/sources/SourcesListPage.ts:51
#: src/pages/sources/SourcesListPage.ts:52
#: src/pages/sources/ldap/LDAPSourceForm.ts:54
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:64
#: src/pages/sources/oauth/OAuthSourceForm.ts:100
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:64
#: src/pages/sources/plex/PlexSourceForm.ts:87
#: src/pages/sources/plex/PlexSourceViewPage.ts:63
#: src/pages/sources/saml/SAMLSourceForm.ts:54
#: src/pages/sources/saml/SAMLSourceViewPage.ts:66
#: src/pages/stages/StageListPage.ts:65
@ -1949,7 +1995,7 @@ msgstr ""
msgid "NameID Property Mapping"
msgstr ""
#: src/flows/stages/identification/IdentificationStage.ts:119
#: src/flows/stages/identification/IdentificationStage.ts:127
msgid "Need an account?"
msgstr ""
@ -2219,6 +2265,7 @@ msgstr ""
#: src/pages/providers/saml/SAMLProviderViewPage.ts:58
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:56
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:56
#: src/pages/sources/plex/PlexSourceViewPage.ts:55
#: src/pages/sources/saml/SAMLSourceViewPage.ts:58
#: src/pages/users/UserViewPage.ts:74
msgid "Overview"
@ -2289,7 +2336,7 @@ msgstr ""
msgid "Policy"
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts:134
#: src/pages/applications/ApplicationViewPage.ts:147
#: src/pages/flows/FlowViewPage.ts:101
msgid "Policy / Group / User Bindings"
msgstr ""
@ -2299,6 +2346,7 @@ msgid "Policy / User / Group"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:144
#: src/pages/sources/plex/PlexSourceViewPage.ts:103
#: src/pages/sources/saml/SAMLSourceViewPage.ts:150
msgid "Policy Bindings"
msgstr ""
@ -2340,7 +2388,7 @@ msgstr ""
msgid "Post binding (auto-submit)"
msgstr ""
#: src/flows/FlowExecutor.ts:255
#: src/flows/FlowExecutor.ts:258
msgid "Powered by authentik"
msgstr ""
@ -2403,7 +2451,8 @@ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:81
#: src/pages/providers/proxy/ProxyProviderForm.ts:123
#: src/pages/providers/saml/SAMLProviderForm.ts:78
#: src/pages/sources/oauth/OAuthSourceForm.ts:122
#: src/pages/sources/oauth/OAuthSourceForm.ts:144
#: src/pages/sources/plex/PlexSourceForm.ts:131
#: src/pages/sources/saml/SAMLSourceForm.ts:76
msgid "Protocol settings"
msgstr ""
@ -2425,7 +2474,7 @@ msgstr ""
msgid "Provider Type"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:138
#: src/pages/sources/oauth/OAuthSourceForm.ts:160
msgid "Provider type"
msgstr ""
@ -2594,7 +2643,7 @@ msgstr ""
msgid "Retry authentication"
msgstr ""
#: src/flows/FlowExecutor.ts:145
#: src/flows/FlowExecutor.ts:146
msgid "Return"
msgstr ""
@ -2657,7 +2706,7 @@ msgstr ""
msgid "SSO URL"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:247
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:251
msgid "Same identifier is used for all providers"
msgstr ""
@ -2702,7 +2751,7 @@ msgstr ""
msgid "Select an identification method."
msgstr ""
#: src/flows/stages/identification/IdentificationStage.ts:134
#: src/flows/stages/identification/IdentificationStage.ts:142
msgid "Select one of the sources below to login."
msgstr ""
@ -2714,6 +2763,10 @@ msgstr ""
msgid "Select which scopes can be used by the client. The client stil has to specify the scope to access the data."
msgstr ""
#: src/pages/sources/plex/PlexSourceForm.ts:153
msgid "Select which server a user has to be a member of to be allowed to authenticate."
msgstr ""
#: src/pages/events/RuleForm.ts:92
msgid "Select which transports should be used to notify the user. If none are selected, the notification will only be shown in the authentik UI."
msgstr ""
@ -2812,7 +2865,7 @@ msgstr ""
msgid "Shown as the Title in Flow pages."
msgstr ""
#: src/flows/stages/identification/IdentificationStage.ts:120
#: src/flows/stages/identification/IdentificationStage.ts:128
msgid "Sign up."
msgstr ""
@ -2833,6 +2886,10 @@ msgstr ""
msgid "Single Prompts that can be used for Prompt Stages."
msgstr ""
#: src/pages/stages/invitation/InvitationForm.ts:62
msgid "Single use"
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts:173
msgid "Skip path regex"
msgstr ""
@ -2842,16 +2899,17 @@ msgstr ""
#: src/pages/flows/FlowForm.ts:94
#: src/pages/sources/ldap/LDAPSourceForm.ts:60
#: src/pages/sources/oauth/OAuthSourceForm.ts:106
#: src/pages/sources/plex/PlexSourceForm.ts:93
#: src/pages/sources/saml/SAMLSourceForm.ts:60
msgid "Slug"
msgstr ""
#: src/flows/FlowExecutor.ts:138
#: src/flows/FlowExecutor.ts:139
msgid "Something went wrong! Please try again later."
msgstr ""
#: src/pages/providers/ProviderListPage.ts:91
#: src/pages/sources/SourcesListPage.ts:87
#: src/pages/sources/SourcesListPage.ts:88
msgid "Source"
msgstr ""
@ -2860,11 +2918,11 @@ msgid "Source {0}"
msgstr ""
#: src/interfaces/AdminInterface.ts:20
#: src/pages/sources/SourcesListPage.ts:30
#: src/pages/sources/SourcesListPage.ts:31
msgid "Sources"
msgstr ""
#: src/pages/sources/SourcesListPage.ts:33
#: src/pages/sources/SourcesListPage.ts:34
msgid "Sources of identities, which can either be synced into authentik's database, like LDAP, or can be used by users to authenticate and enroll themselves, like OAuth and social logins"
msgstr ""
@ -2971,7 +3029,7 @@ msgstr ""
msgid "Subject"
msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:208
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:212
msgid "Subject mode"
msgstr ""
@ -3061,6 +3119,7 @@ msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts:47
#: src/pages/sources/oauth/OAuthSourceForm.ts:51
#: src/pages/sources/plex/PlexSourceForm.ts:60
#: src/pages/sources/saml/SAMLSourceForm.ts:47
msgid "Successfully created source."
msgstr ""
@ -3197,6 +3256,7 @@ msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts:44
#: src/pages/sources/oauth/OAuthSourceForm.ts:48
#: src/pages/sources/plex/PlexSourceForm.ts:57
#: src/pages/sources/saml/SAMLSourceForm.ts:44
msgid "Successfully updated source."
msgstr ""
@ -3353,13 +3413,14 @@ msgid "These bindings control which users can access this flow."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:146
#: src/pages/sources/plex/PlexSourceViewPage.ts:105
#: src/pages/sources/saml/SAMLSourceViewPage.ts:152
msgid ""
"These bindings control which users can access this source.\n"
"You can only use policies here as access is checked before the user is authenticated."
msgstr ""
#: src/pages/applications/ApplicationViewPage.ts:136
#: src/pages/applications/ApplicationViewPage.ts:149
msgid "These policies control which users can access this application."
msgstr ""
@ -3448,7 +3509,7 @@ msgstr ""
#: src/pages/policies/PolicyListPage.ts:57
#: src/pages/property-mappings/PropertyMappingListPage.ts:55
#: src/pages/providers/ProviderListPage.ts:54
#: src/pages/sources/SourcesListPage.ts:52
#: src/pages/sources/SourcesListPage.ts:53
#: src/pages/stages/prompt/PromptForm.ts:97
#: src/pages/stages/prompt/PromptListPage.ts:48
msgid "Type"
@ -3527,9 +3588,10 @@ msgstr ""
#: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:118
#: src/pages/providers/proxy/ProxyProviderViewPage.ts:117
#: src/pages/providers/saml/SAMLProviderViewPage.ts:111
#: src/pages/sources/SourcesListPage.ts:69
#: src/pages/sources/SourcesListPage.ts:70
#: src/pages/sources/ldap/LDAPSourceViewPage.ts:95
#: src/pages/sources/oauth/OAuthSourceViewPage.ts:115
#: src/pages/sources/plex/PlexSourceViewPage.ts:74
#: src/pages/sources/saml/SAMLSourceViewPage.ts:101
#: src/pages/stages/StageListPage.ts:85
#: src/pages/stages/prompt/PromptListPage.ts:67
@ -3590,6 +3652,10 @@ msgstr ""
msgid "Update Outpost"
msgstr ""
#: src/pages/sources/plex/PlexSourceViewPage.ts:77
msgid "Update Plex Source"
msgstr ""
#: src/pages/stages/prompt/PromptListPage.ts:70
msgid "Update Prompt"
msgstr ""
@ -3630,7 +3696,7 @@ msgstr ""
#: src/pages/policies/PolicyListPage.ts:80
#: src/pages/property-mappings/PropertyMappingListPage.ts:69
#: src/pages/providers/ProviderListPage.ts:76
#: src/pages/sources/SourcesListPage.ts:72
#: src/pages/sources/SourcesListPage.ts:73
#: src/pages/stages/StageListPage.ts:88
#: src/pages/users/UserActiveForm.ts:41
msgid "Update {0}"
@ -3660,6 +3726,16 @@ msgstr ""
msgid "Use global settings"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:131
#: src/pages/sources/plex/PlexSourceForm.ts:118
msgid "Use the user's email address, but deny enrollment when the email address already exists."
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:137
#: src/pages/sources/plex/PlexSourceForm.ts:124
msgid "Use the user's username, but deny enrollment when the username already exists."
msgstr ""
#: src/elements/events/ObjectChangelog.ts:39
#: src/elements/events/UserEvents.ts:36
#: src/pages/events/EventInfo.ts:83
@ -3700,6 +3776,11 @@ msgstr ""
msgid "User fields"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts:120
#: src/pages/sources/plex/PlexSourceForm.ts:107
msgid "User matching mode"
msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts:208
msgid "User object filter"
msgstr ""
@ -3734,7 +3815,7 @@ msgstr ""
msgid "Userinfo URL"
msgstr ""
#: src/flows/stages/identification/IdentificationStage.ts:142
#: src/flows/stages/identification/IdentificationStage.ts:150
#: src/pages/stages/identification/IdentificationStageForm.ts:78
#: src/pages/user-settings/UserDetailsPage.ts:57
#: src/pages/users/UserForm.ts:47
@ -3865,6 +3946,10 @@ msgstr ""
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
msgstr ""
#: src/pages/stages/invitation/InvitationForm.ts:66
msgid "When enabled, the invitation will be deleted after usage."
msgstr ""
#: src/pages/stages/identification/IdentificationStageForm.ts:94
msgid "When enabled, user fields are matched regardless of their casing."
msgstr ""
@ -3883,7 +3968,7 @@ msgstr ""
msgid "When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged."
msgstr ""
#: src/flows/FlowExecutor.ts:134
#: src/flows/FlowExecutor.ts:135
msgid "Whoops!"
msgstr ""

View File

@ -111,6 +111,19 @@ export class ApplicationViewPage extends LitElement {
</div>
</dd>
</div>
${this.application.launchUrl ?
html`<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${t`Launch`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">
<a target="_blank" href=${this.application.launchUrl} slot="trigger" class="pf-c-button pf-m-secondary">
${t`Launch`}
</a>
</div>
</dd>
</div>`: html``}
</dl>
</div>
</div>

View File

@ -192,7 +192,11 @@ export class OAuth2ProviderFormPage extends Form<OAuth2Provider> {
hasKey: "true",
}).then(keys => {
return keys.results.map(key => {
return html`<option value=${ifDefined(key.pk)} ?selected=${this.provider?.rsaKey === key.pk}>${key.name}</option>`;
let selected = this.provider?.rsaKey === key.pk;
if (keys.results.length === 1) {
selected = true;
}
return html`<option value=${ifDefined(key.pk)} ?selected=${selected}>${key.name}</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>

View File

@ -9,6 +9,7 @@ import "../../elements/PageHeader";
import "./ldap/LDAPSourceViewPage";
import "./oauth/OAuthSourceViewPage";
import "./saml/SAMLSourceViewPage";
import "./plex/PlexSourceViewPage";
import { ifDefined } from "lit-html/directives/if-defined";
@customElement("ak-source-view")
@ -37,6 +38,8 @@ export class SourceViewPage extends LitElement {
return html`<ak-source-oauth-view sourceSlug=${this.source.slug}></ak-source-oauth-view>`;
case "ak-source-saml-form":
return html`<ak-source-saml-view sourceSlug=${this.source.slug}></ak-source-saml-view>`;
case "ak-source-plex-form":
return html`<ak-source-plex-view sourceSlug=${this.source.slug}></ak-source-plex-view>`;
default:
return html`<p>Invalid source type ${this.source.component}</p>`;
}

View File

@ -17,6 +17,7 @@ import { ifDefined } from "lit-html/directives/if-defined";
import "./ldap/LDAPSourceForm";
import "./saml/SAMLSourceForm";
import "./oauth/OAuthSourceForm";
import "./plex/PlexSourceForm";
@customElement("ak-source-list")
export class SourceListPage extends TablePage<Source> {

View File

@ -1,4 +1,4 @@
import { OAuthSource, SourcesApi, FlowsApi, FlowDesignationEnum } from "authentik-api";
import { OAuthSource, SourcesApi, FlowsApi, FlowDesignationEnum, OAuthSourceUserMatchingModeEnum } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
@ -119,6 +119,28 @@ export class OAuthSourceForm extends Form<OAuthSource> {
</label>
</div>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`User matching mode`}
?required=${true}
name="userMatchingMode">
<select class="pf-c-form-control">
<option value=${OAuthSourceUserMatchingModeEnum.Identifier} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.Identifier}>
${t`Link users on unique identifier`}
</option>
<option value=${OAuthSourceUserMatchingModeEnum.UsernameLink} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.UsernameLink}>
${t`Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses`}
</option>
<option value=${OAuthSourceUserMatchingModeEnum.UsernameDeny} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.UsernameDeny}>
${t`Use the user's email address, but deny enrollment when the email address already exists.`}
</option>
<option value=${OAuthSourceUserMatchingModeEnum.EmailLink} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.EmailLink}>
${t`Link to a user with identical username address. Can have security implications when a username is used with another source.`}
</option>
<option value=${OAuthSourceUserMatchingModeEnum.EmailDeny} ?selected=${this.source?.userMatchingMode === OAuthSourceUserMatchingModeEnum.EmailDeny}>
${t`Use the user's username, but deny enrollment when the username already exists.`}
</option>
</select>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">

View File

@ -0,0 +1,205 @@
import { PlexSource, SourcesApi, FlowsApi, FlowDesignationEnum, PlexSourceUserMatchingModeEnum } from "authentik-api";
import { t } from "@lingui/macro";
import { customElement, property } from "lit-element";
import { html, TemplateResult } from "lit-html";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { Form } from "../../../elements/forms/Form";
import "../../../elements/forms/FormGroup";
import "../../../elements/forms/HorizontalFormElement";
import { ifDefined } from "lit-html/directives/if-defined";
import { until } from "lit-html/directives/until";
import { first, randomString } from "../../../utils";
import { PlexAPIClient, PlexResource, popupCenterScreen} from "../../../flows/sources/plex/API";
@customElement("ak-source-plex-form")
export class PlexSourceForm extends Form<PlexSource> {
set sourceSlug(value: string) {
new SourcesApi(DEFAULT_CONFIG).sourcesPlexRead({
slug: value,
}).then(source => {
this.source = source;
});
}
@property({attribute: false})
source: PlexSource = {
clientId: randomString(40)
} as PlexSource;
@property()
plexToken?: string;
@property({attribute: false})
plexResources?: PlexResource[];
getSuccessMessage(): string {
if (this.source) {
return t`Successfully updated source.`;
} else {
return t`Successfully created source.`;
}
}
send = (data: PlexSource): Promise<PlexSource> => {
if (this.source.slug) {
return new SourcesApi(DEFAULT_CONFIG).sourcesPlexUpdate({
slug: this.source.slug,
data: data
});
} else {
return new SourcesApi(DEFAULT_CONFIG).sourcesPlexCreate({
data: data
});
}
};
async doAuth(): Promise<void> {
const authInfo = await PlexAPIClient.getPin(this.source?.clientId || "");
const authWindow = popupCenterScreen(authInfo.authUrl, "plex auth", 550, 700);
PlexAPIClient.pinPoll(this.source?.clientId || "", authInfo.pin.id).then(token => {
authWindow?.close();
this.plexToken = token;
this.loadServers();
});
}
async loadServers(): Promise<void> {
if (!this.plexToken) {
return;
}
this.plexResources = await new PlexAPIClient(this.plexToken).getServers();
}
renderForm(): TemplateResult {
return html`<form class="pf-c-form pf-m-horizontal">
<ak-form-element-horizontal
label=${t`Name`}
?required=${true}
name="name">
<input type="text" value="${ifDefined(this.source?.name)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Slug`}
?required=${true}
name="slug">
<input type="text" value="${ifDefined(this.source?.slug)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="enabled">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.source?.enabled, true)}>
<label class="pf-c-check__label">
${t`Enabled`}
</label>
</div>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`User matching mode`}
?required=${true}
name="userMatchingMode">
<select class="pf-c-form-control">
<option value=${PlexSourceUserMatchingModeEnum.Identifier} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.Identifier}>
${t`Link users on unique identifier`}
</option>
<option value=${PlexSourceUserMatchingModeEnum.UsernameLink} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.UsernameLink}>
${t`Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses`}
</option>
<option value=${PlexSourceUserMatchingModeEnum.UsernameDeny} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.UsernameDeny}>
${t`Use the user's email address, but deny enrollment when the email address already exists.`}
</option>
<option value=${PlexSourceUserMatchingModeEnum.EmailLink} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.EmailLink}>
${t`Link to a user with identical username address. Can have security implications when a username is used with another source.`}
</option>
<option value=${PlexSourceUserMatchingModeEnum.EmailDeny} ?selected=${this.source?.userMatchingMode === PlexSourceUserMatchingModeEnum.EmailDeny}>
${t`Use the user's username, but deny enrollment when the username already exists.`}
</option>
</select>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header">
${t`Protocol settings`}
</span>
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal
label=${t`Client ID`}
?required=${true}
name="clientId">
<input type="text" value="${first(this.source?.clientId)}" class="pf-c-form-control" required>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Allowed servers`}
?required=${true}
name="allowedServers">
<select class="pf-c-form-control" multiple>
${this.plexResources?.map(r => {
const selected = Array.from(this.source?.allowedServers || []).some(server => {
return server == r.clientIdentifier;
});
return html`<option value=${r.clientIdentifier} ?selected=${selected}>${r.name}</option>`;
})}
</select>
<p class="pf-c-form__helper-text">${t`Select which server a user has to be a member of to be allowed to authenticate.`}</p>
<p class="pf-c-form__helper-text">${t`Hold control/command to select multiple items.`}</p>
<p class="pf-c-form__helper-text">
<button class="pf-c-button pf-m-primary" type="button" @click=${() => {
this.doAuth();
}}>
${t`Load servers`}
</button>
</p>
</ak-form-element-horizontal>
</div>
</ak-form-group>
<ak-form-group>
<span slot="header">
${t`Flow settings`}
</span>
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal
label=${t`Authentication flow`}
?required=${true}
name="authenticationFlow">
<select class="pf-c-form-control">
${until(new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
ordering: "pk",
designation: FlowDesignationEnum.Authentication,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.source?.authenticationFlow === flow.pk;
if (!this.source?.pk && !this.source?.authenticationFlow && flow.slug === "default-source-authentication") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
<p class="pf-c-form__helper-text">${t`Flow to use when authenticating existing users.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal
label=${t`Enrollment flow`}
?required=${true}
name="enrollmentFlow">
<select class="pf-c-form-control">
${until(new FlowsApi(DEFAULT_CONFIG).flowsInstancesList({
ordering: "pk",
designation: FlowDesignationEnum.Enrollment,
}).then(flows => {
return flows.results.map(flow => {
let selected = this.source?.enrollmentFlow === flow.pk;
if (!this.source?.pk && !this.source?.enrollmentFlow && flow.slug === "default-source-enrollment") {
selected = true;
}
return html`<option value=${ifDefined(flow.pk)} ?selected=${selected}>${flow.name} (${flow.slug})</option>`;
});
}), html`<option>${t`Loading...`}</option>`)}
</select>
<p class="pf-c-form__helper-text">${t`Flow to use when enrolling new users.`}</p>
</ak-form-element-horizontal>
</div>
</ak-form-group>
</form>`;
}
}

View File

@ -0,0 +1,119 @@
import { t } from "@lingui/macro";
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFGallery from "@patternfly/patternfly/layouts/Gallery/gallery.css";
import PFCard from "@patternfly/patternfly/components/Card/card.css";
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
import PFSizing from "@patternfly/patternfly/utilities/Sizing/sizing.css";
import PFFlex from "@patternfly/patternfly/utilities/Flex/flex.css";
import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css";
import AKGlobal from "../../../authentik.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import "../../../elements/buttons/SpinnerButton";
import "../../../elements/CodeMirror";
import "../../../elements/Tabs";
import "../../../elements/events/ObjectChangelog";
import "../../../elements/forms/ModalForm";
import "../../policies/BoundPoliciesList";
import "./PlexSourceForm";
import { PlexSource, SourcesApi } from "authentik-api";
import { DEFAULT_CONFIG } from "../../../api/Config";
import { EVENT_REFRESH } from "../../../constants";
@customElement("ak-source-plex-view")
export class PlexSourceViewPage extends LitElement {
@property({ type: String })
set sourceSlug(value: string) {
new SourcesApi(DEFAULT_CONFIG).sourcesPlexRead({
slug: value
}).then((source) => {
this.source = source;
});
}
@property({ attribute: false })
source?: PlexSource;
static get styles(): CSSResult[] {
return [PFBase, PFPage, PFButton, PFFlex, PFDisplay, PFGallery, PFContent, PFCard, PFDescriptionList, PFSizing, AKGlobal];
}
constructor() {
super();
this.addEventListener(EVENT_REFRESH, () => {
if (!this.source?.pk) return;
this.sourceSlug = this.source?.slug;
});
}
render(): TemplateResult {
if (!this.source) {
return html``;
}
return html`<ak-tabs>
<section slot="page-overview" data-tab-title="${t`Overview`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-u-display-flex pf-u-justify-content-center">
<div class="pf-u-w-75">
<div class="pf-c-card">
<div class="pf-c-card__body">
<dl class="pf-c-description-list pf-m-2-col-on-lg">
<div class="pf-c-description-list__group">
<dt class="pf-c-description-list__term">
<span class="pf-c-description-list__text">${t`Name`}</span>
</dt>
<dd class="pf-c-description-list__description">
<div class="pf-c-description-list__text">${this.source.name}</div>
</dd>
</div>
</dl>
</div>
<div class="pf-c-card__footer">
<ak-forms-modal>
<span slot="submit">
${t`Update`}
</span>
<span slot="header">
${t`Update Plex Source`}
</span>
<ak-source-plex-form
slot="form"
.sourceSlug=${this.source.slug}>
</ak-source-plex-form>
<button slot="trigger" class="pf-c-button pf-m-primary">
${t`Edit`}
</button>
</ak-forms-modal>
</div>
</div>
</div>
</div>
</section>
<section slot="page-changelog" data-tab-title="${t`Changelog`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-card__body">
<ak-object-changelog
targetModelPk=${this.source.pk || ""}
targetModelApp="authentik_sources_plex"
targetModelName="plexsource">
</ak-object-changelog>
</div>
</div>
</section>
<div slot="page-policy-binding" data-tab-title="${t`Policy Bindings`}" class="pf-c-page__main-section pf-m-no-padding-mobile">
<div class="pf-c-card">
<div class="pf-c-card__title">${t`These bindings control which users can access this source.
You can only use policies here as access is checked before the user is authenticated.`}</div>
<div class="pf-c-card__body">
<ak-bound-policies-list .target=${this.source.pk} ?policyOnly=${true}>
</ak-bound-policies-list>
</div>
</div>
</div>
</ak-tabs>`;
}
}

View File

@ -51,6 +51,17 @@ export class InvitationForm extends Form<Invitation> {
</ak-codemirror>
<p class="pf-c-form__helper-text">${t`Optional data which is loaded into the flow's 'prompt_data' context variable. YAML or JSON.`}</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal name="singleUse">
<div class="pf-c-check">
<input type="checkbox" class="pf-c-check__input" ?checked=${first(this.invitation?.singleUse, true)}>
<label class="pf-c-check__label">
${t`Single use`}
</label>
</div>
<p class="pf-c-form__helper-text">
${t`When enabled, the invitation will be deleted after usage.`}
</p>
</ak-form-element-horizontal>
</form>`;
}

View File

@ -35,12 +35,18 @@ export class UserListPage extends TablePage<User> {
@property()
order = "last_login";
@property({ type: Boolean })
hideServiceAccounts = true;
apiEndpoint(page: number): Promise<AKResponse<User>> {
return new CoreApi(DEFAULT_CONFIG).coreUsersList({
ordering: this.order,
page: page,
pageSize: PAGE_SIZE,
search: this.search || "",
attributes: this.hideServiceAccounts ? JSON.stringify({
"goauthentik.io/user/service-account__isnull": "true"
}) : undefined
});
}
@ -163,4 +169,29 @@ export class UserListPage extends TablePage<User> {
`;
}
renderToolbarAfter(): TemplateResult {
return html`&nbsp;
<div class="pf-c-toolbar__group pf-m-filter-group">
<div class="pf-c-toolbar__item pf-m-search-filter">
<div class="pf-c-input-group">
<div class="pf-c-check">
<input class="pf-c-check__input"
type="checkbox"
id="hide-service-accounts"
name="hide-service-accounts"
?checked=${this.hideServiceAccounts}
@change=${() => {
this.hideServiceAccounts = !this.hideServiceAccounts;
this.page = 1;
this.fetch();
}} />
<label class="pf-c-check__label" for="hide-service-accounts">
${t`Hide service-accounts`}
</label>
</div>
</div>
</div>
</div>`;
}
}