Merge branch 'master' into version-2021.12

This commit is contained in:
Jens Langhammer
2021-12-15 10:16:05 +01:00
125 changed files with 2887 additions and 1747 deletions

View File

@ -3,6 +3,7 @@ import { getCookie } from "../utils";
import { APIMiddleware } from "../elements/notifications/APIDrawer";
import { MessageMiddleware } from "../elements/messages/Middleware";
import { VERSION } from "../constants";
import { getMetaContent } from "@sentry/tracing/dist/browser/browsertracing";
export class LoggingMiddleware implements Middleware {
@ -53,6 +54,7 @@ export const DEFAULT_CONFIG = new Configuration({
basePath: process.env.AK_API_BASE_PATH + "/api/v3",
headers: {
"X-CSRFToken": getCookie("authentik_csrf"),
"sentry-trace": getMetaContent("sentry-trace") || "",
},
middleware: [
new APIMiddleware(),

View File

@ -27,7 +27,10 @@ export function configureSentry(canDoPpi: boolean = false): Promise<Config> {
],
tracesSampleRate: config.errorReporting.tracesSampleRate,
environment: config.errorReporting.environment,
beforeSend: async (event: Sentry.Event, hint: Sentry.EventHint): Promise<Sentry.Event | null> => {
beforeSend: async (event: Sentry.Event, hint: Sentry.EventHint | undefined): Promise<Sentry.Event | null> => {
if (!hint) {
return event;
}
if (hint.originalException instanceof SentryIgnoredError) {
return null;
}
@ -40,8 +43,13 @@ export function configureSentry(canDoPpi: boolean = false): Promise<Config> {
Sentry.setTag(TAG_SENTRY_CAPABILITIES, config.capabilities.join(","));
if (window.location.pathname.includes("if/")) {
// Get the interface name from URL
const intf = window.location.pathname.replace(/.+if\/(.+)\//, "$1");
Sentry.setTag(TAG_SENTRY_COMPONENT, `web/${intf}`);
const pathMatches = window.location.pathname.match(/.+if\/(\w+)\//);
let currentInterface = "unknown";
if (pathMatches && pathMatches.length >= 2) {
currentInterface = pathMatches[1];
}
Sentry.setTag(TAG_SENTRY_COMPONENT, `web/${currentInterface}`);
Sentry.configureScope((scope) => scope.setTransactionName(`authentik.web.if.${currentInterface}`));
}
if (config.errorReporting.sendPii && canDoPpi) {
me().then(user => {

View File

@ -108,10 +108,11 @@ export class PageHeader extends LitElement {
renderIcon(): TemplateResult {
if (this.icon) {
if (this.iconImage) {
if (this.iconImage && !this.icon.startsWith("fa://")) {
return html`<img class="pf-icon" src="${this.icon}" />&nbsp;`;
}
return html`<i class=${this.icon}></i>&nbsp;`;
const icon = this.icon.replaceAll("fa://", "fa ");
return html`<i class=${icon}></i>&nbsp;`;
}
return html``;
}
@ -132,7 +133,10 @@ export class PageHeader extends LitElement {
</button>
<section class="pf-c-page__main-section pf-m-light">
<div class="pf-c-content">
<h1>${this.renderIcon()} ${this.header}</h1>
<h1>
${this.renderIcon()}
<slot name="header"> ${this.header} </slot>
</h1>
${this.description ? html`<p>${this.description}</p>` : html``}
</div>
</section>

View File

@ -18,6 +18,9 @@ export class AggregateCard extends LitElement {
@property()
headerLink?: string;
@property({ type: Boolean })
isCenter = true;
static get styles(): CSSResult[] {
return [PFBase, PFCard, PFFlex, AKGlobal].concat([
css`
@ -59,7 +62,9 @@ export class AggregateCard extends LitElement {
</div>
${this.renderHeaderLink()}
</div>
<div class="pf-c-card__body center-value">${this.renderInner()}</div>
<div class="pf-c-card__body ${this.isCenter ? "center-value" : ""}">
${this.renderInner()}
</div>
</div>`;
}
}

View File

@ -0,0 +1,52 @@
import { ChartData, Tick } from "chart.js";
import { t } from "@lingui/macro";
import { customElement, property } from "lit/decorators.js";
import { Coordinate, EventActions, EventsApi } from "@goauthentik/api";
import { DEFAULT_CONFIG } from "../../api/Config";
import { AKChart } from "./Chart";
@customElement("ak-charts-admin-model-per-day")
export class AdminModelPerDay extends AKChart<Coordinate[]> {
@property()
action: EventActions = EventActions.ModelCreated;
@property({ attribute: false })
query?: { [key: string]: unknown } | undefined;
apiRequest(): Promise<Coordinate[]> {
return new EventsApi(DEFAULT_CONFIG).eventsEventsPerMonthList({
action: this.action,
query: JSON.stringify(this.query || {}),
});
}
timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string {
const valueStamp = ticks[index];
const delta = Date.now() - valueStamp.value;
const ago = Math.round(delta / 1000 / 3600 / 24);
return t`${ago} days ago`;
}
getChartData(data: Coordinate[]): ChartData {
return {
datasets: [
{
label: t`Objects created`,
backgroundColor: "rgba(189, 229, 184, .5)",
spanGaps: true,
data:
data.map((cord) => {
return {
x: cord.xCord || 0,
y: cord.yCord || 0,
};
}) || [],
},
],
};
}
}

View File

@ -5,6 +5,8 @@ import { ArcElement, BarElement } from "chart.js";
import { LinearScale, TimeScale } from "chart.js";
import "chartjs-adapter-moment";
import { t } from "@lingui/macro";
import { CSSResult, LitElement, TemplateResult, css, html } from "lit";
import { property } from "lit/decorators.js";
@ -114,6 +116,13 @@ export abstract class AKChart<T> extends LitElement {
];
}
timeTickCallback(tickValue: string | number, index: number, ticks: Tick[]): string {
const valueStamp = ticks[index];
const delta = Date.now() - valueStamp.value;
const ago = Math.round(delta / 1000 / 3600);
return t`${ago} hours ago`;
}
getOptions(): ChartOptions {
return {
maintainAspectRatio: false,
@ -122,15 +131,8 @@ export abstract class AKChart<T> extends LitElement {
type: "time",
display: true,
ticks: {
callback: function (
tickValue: string | number,
index: number,
ticks: Tick[],
): string {
const valueStamp = ticks[index];
const delta = Date.now() - valueStamp.value;
const ago = Math.round(delta / 1000 / 3600);
return `${ago} Hours ago`;
callback: (tickValue: string | number, index: number, ticks: Tick[]) => {
return this.timeTickCallback(tickValue, index, ticks);
},
autoSkip: true,
maxTicksLimit: 8,

View File

@ -187,6 +187,7 @@ export class DeleteBulkForm extends ModalButton {
<p class="pf-c-title">
${t`Are you sure you want to delete ${this.objects.length} ${this.objectLabel}?`}
</p>
<slot name="notice"></slot>
</form>
</section>
<section class="pf-c-page__main-section">

View File

@ -102,6 +102,7 @@ export class APIDrawer extends LitElement {
<div class="pf-c-notification-drawer__header">
<div class="text">
<h1 class="pf-c-notification-drawer__header-title">${t`API Requests`}</h1>
<a href="/api/v3/" target="_blank">${t`Open API Browser`}</a>
</div>
<div class="pf-c-notification-drawer__header-action">
<div class="pf-c-notification-drawer__header-action-close">

View File

@ -30,6 +30,19 @@ window.addEventListener("load", () => {
})();
});
export function paramURL(url: string, params?: { [key: string]: unknown }): string {
let finalUrl = "#";
finalUrl += url;
if (params) {
finalUrl += ";";
finalUrl += encodeURIComponent(JSON.stringify(params));
}
return finalUrl;
}
export function navigate(url: string, params?: { [key: string]: unknown }): void {
window.location.assign(paramURL(url, params));
}
@customElement("ak-router-outlet")
export class RouterOutlet extends LitElement {
@property({ attribute: false })

View File

@ -32,6 +32,7 @@ import "../elements/LoadingOverlay";
import { first } from "../utils";
import "./FlowInspector";
import "./access_denied/FlowAccessDenied";
import "./sources/apple/AppleLoginInit";
import "./sources/plex/PlexLoginInit";
import "./stages/RedirectStage";
import "./stages/authenticator_duo/AuthenticatorDuoStage";
@ -321,6 +322,11 @@ export class FlowExecutor extends LitElement implements StageHost {
.host=${this as StageHost}
.challenge=${this.challenge}
></ak-flow-sources-plex>`;
case "ak-flow-sources-oauth-apple":
return html`<ak-flow-sources-oauth-apple
.host=${this as StageHost}
.challenge=${this.challenge}
></ak-flow-sources-oauth-apple>`;
default:
break;
}

View File

@ -0,0 +1,79 @@
import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import AKGlobal from "../../../authentik.css";
import PFButton from "@patternfly/patternfly/components/Button/button.css";
import PFForm from "@patternfly/patternfly/components/Form/form.css";
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
import PFLogin from "@patternfly/patternfly/components/Login/login.css";
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { AppleChallengeResponseRequest, AppleLoginChallenge } from "@goauthentik/api";
import "../../../elements/EmptyState";
import { BaseStage } from "../../stages/base";
@customElement("ak-flow-sources-oauth-apple")
export class AppleLoginInit extends BaseStage<AppleLoginChallenge, AppleChallengeResponseRequest> {
@property({ type: Boolean })
isModalShown = false;
static get styles(): CSSResult[] {
return [PFBase, PFLogin, PFForm, PFFormControl, PFButton, PFTitle, AKGlobal];
}
firstUpdated(): void {
const appleAuth = document.createElement("script");
appleAuth.src =
"https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js";
appleAuth.type = "text/javascript";
appleAuth.onload = () => {
AppleID.auth.init({
clientId: this.challenge?.clientId,
scope: this.challenge.scope,
redirectURI: this.challenge.redirectUri,
state: this.challenge.state,
usePopup: false,
});
AppleID.auth.signIn();
this.isModalShown = true;
};
document.head.append(appleAuth);
//Listen for authorization success
document.addEventListener("AppleIDSignInOnSuccess", () => {
//handle successful response
});
//Listen for authorization failures
document.addEventListener("AppleIDSignInOnFailure", (error) => {
console.warn(error);
this.isModalShown = false;
});
}
render(): TemplateResult {
return html`<header class="pf-c-login__main-header">
<h1 class="pf-c-title pf-m-3xl">${t`Authenticating with Apple...`}</h1>
</header>
<div class="pf-c-login__main-body">
<form class="pf-c-form">
<ak-empty-state ?loading="${true}"> </ak-empty-state>
${!this.isModalShown
? html`<button
class="pf-c-button pf-m-primary pf-m-block"
@click=${() => {
AppleID.auth.signIn();
}}
>
${t`Retry`}
</button>`
: html``}
</form>
</div>
<footer class="pf-c-login__main-footer">
<ul class="pf-c-login__main-footer-links"></ul>
</footer>`;
}
}

14
web/src/flows/sources/apple/apple.d.ts vendored Normal file
View File

@ -0,0 +1,14 @@
declare namespace AppleID {
const auth: AppleIDAuth;
class AppleIDAuth {
init({
clientId: string,
scope: string,
redirectURI: string,
state: string,
usePopup: boolean,
}): void;
async signIn(): Promise<void>;
}
}

View File

@ -51,6 +51,7 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage<
// byte arrays as expected by the spec.
const publicKeyCredentialCreateOptions = transformCredentialCreateOptions(
this.challenge?.registration as PublicKeyCredentialCreationOptions,
this.challenge?.registration.user.id,
);
// request the authenticator(s) to create a new credential keypair.

View File

@ -8,15 +8,26 @@ export function b64RawEnc(buf: Uint8Array): string {
return base64js.fromByteArray(buf).replace(/\+/g, "-").replace(/\//g, "_");
}
export function u8arr(input: string): Uint8Array {
return Uint8Array.from(atob(input.replace(/_/g, "/").replace(/-/g, "+")), (c) =>
c.charCodeAt(0),
);
}
/**
* Transforms items in the credentialCreateOptions generated on the server
* into byte arrays expected by the navigator.credentials.create() call
*/
export function transformCredentialCreateOptions(
credentialCreateOptions: PublicKeyCredentialCreationOptions,
userId: string,
): PublicKeyCredentialCreationOptions {
const user = credentialCreateOptions.user;
user.id = u8arr(b64enc(credentialCreateOptions.user.id as Uint8Array));
// Because json can't contain raw bytes, the server base64-encodes the User ID
// So to get the base64 encoded byte array, we first need to convert it to a regular
// string, then a byte array, re-encode it and wrap that in an array.
const stringId = decodeURIComponent(escape(window.atob(userId)));
user.id = u8arr(b64enc(u8arr(stringId)));
const challenge = u8arr(credentialCreateOptions.challenge.toString());
const transformedCredentialCreateOptions = Object.assign({}, credentialCreateOptions, {
@ -63,12 +74,6 @@ export function transformNewAssertionForServer(newAssertion: PublicKeyCredential
};
}
function u8arr(input: string): Uint8Array {
return Uint8Array.from(atob(input.replace(/_/g, "/").replace(/-/g, "+")), (c) =>
c.charCodeAt(0),
);
}
export function transformCredentialRequestOptions(
credentialRequestOptions: PublicKeyCredentialRequestOptions,
): PublicKeyCredentialRequestOptions {

View File

@ -189,43 +189,37 @@ export class AdminInterface extends LitElement {
<ak-sidebar-item path="/if/user/" ?isAbsoluteLink=${true} ?highlight=${true}>
<span slot="label">${t`User interface`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/administration/overview">
<span slot="label">${t`Overview`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/administration/system-tasks">
<span slot="label">${t`System Tasks`}</span>
<ak-sidebar-item .expanded=${true}>
<span slot="label">${t`Dashboards`}</span>
<ak-sidebar-item path="/administration/overview">
<span slot="label">${t`Overview`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/administration/dashboard/users">
<span slot="label">${t`Users`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/administration/system-tasks">
<span slot="label">${t`System Tasks`}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${t`Resources`}</span>
<span slot="label">${t`Applications`}</span>
<ak-sidebar-item
path="/core/applications"
.activeWhen=${[`^/core/applications/(?<slug>${SLUG_REGEX})$`]}
>
<span slot="label">${t`Applications`}</span>
</ak-sidebar-item>
<ak-sidebar-item
path="/core/sources"
.activeWhen=${[`^/core/sources/(?<slug>${SLUG_REGEX})$`]}
>
<span slot="label">${t`Sources`}</span>
</ak-sidebar-item>
<ak-sidebar-item
path="/core/providers"
.activeWhen=${[`^/core/providers/(?<id>${ID_REGEX})$`]}
>
<span slot="label">${t`Providers`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/core/tenants">
<span slot="label">${t`Tenants`}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${t`Outposts`}</span>
<ak-sidebar-item path="/outpost/outposts">
<span slot="label">${t`Outposts`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/outpost/integrations">
<span slot="label">${t`Integrations`}</span>
<span slot="label">${t`Outpost Integrations`}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
@ -272,12 +266,9 @@ export class AdminInterface extends LitElement {
<ak-sidebar-item path="/flow/stages/prompts">
<span slot="label">${t`Prompts`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/flow/stages/invitations">
<span slot="label">${t`Invitations`}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${t`Identity & Cryptography`}</span>
<span slot="label">${t`Directory`}</span>
<ak-sidebar-item
path="/identity/users"
.activeWhen=${[`^/identity/users/(?<id>${ID_REGEX})$`]}
@ -287,12 +278,27 @@ export class AdminInterface extends LitElement {
<ak-sidebar-item path="/identity/groups">
<span slot="label">${t`Groups`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/crypto/certificates">
<span slot="label">${t`Certificates`}</span>
<ak-sidebar-item
path="/core/sources"
.activeWhen=${[`^/core/sources/(?<slug>${SLUG_REGEX})$`]}
>
<span slot="label">${t`Federation & Social login`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/core/tokens">
<span slot="label">${t`Tokens & App passwords`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/flow/stages/invitations">
<span slot="label">${t`Invitations`}</span>
</ak-sidebar-item>
</ak-sidebar-item>
<ak-sidebar-item>
<span slot="label">${t`System`}</span>
<ak-sidebar-item path="/core/tenants">
<span slot="label">${t`Tenants`}</span>
</ak-sidebar-item>
<ak-sidebar-item path="/crypto/certificates">
<span slot="label">${t`Certificates`}</span>
</ak-sidebar-item>
</ak-sidebar-item>
`;
}

View File

@ -296,6 +296,10 @@ msgstr "Alternatively, if your current device has Duo installed, click on this l
msgid "Always require consent"
msgstr "Always require consent"
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "An example setup can look like this:"
msgstr "An example setup can look like this:"
#: src/pages/stages/prompt/PromptForm.ts
msgid "Any HTML can be used."
msgstr "Any HTML can be used."
@ -344,6 +348,7 @@ msgstr "Application's display Name."
msgid "Application(s)"
msgstr "Application(s)"
#: src/interfaces/AdminInterface.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/outposts/OutpostForm.ts
@ -407,8 +412,12 @@ msgid "Assigned to application"
msgstr "Assigned to application"
#: src/pages/policies/PolicyListPage.ts
msgid "Assigned to {0} objects."
msgstr "Assigned to {0} objects."
msgid "Assigned to {0} object(s)."
msgstr "Assigned to {0} object(s)."
#: src/pages/policies/PolicyListPage.ts
#~ msgid "Assigned to {0} objects."
#~ msgstr "Assigned to {0} objects."
#: src/pages/events/EventInfo.ts
msgid "Attempted to log in as {0}"
@ -433,6 +442,10 @@ msgstr "Audience"
#~ msgid "Auth Type"
#~ msgstr "Auth Type"
#: src/flows/sources/apple/AppleLoginInit.ts
msgid "Authenticating with Apple..."
msgstr "Authenticating with Apple..."
#: src/flows/sources/plex/PlexLoginInit.ts
msgid "Authenticating with Plex..."
msgstr "Authenticating with Plex..."
@ -445,6 +458,10 @@ msgstr "Authentication"
msgid "Authentication Type"
msgstr "Authentication Type"
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "Authentication URL"
msgstr "Authentication URL"
#: src/pages/sources/oauth/OAuthSourceForm.ts
#: src/pages/sources/plex/PlexSourceForm.ts
#: src/pages/sources/saml/SAMLSourceForm.ts
@ -760,6 +777,10 @@ msgstr "Check status"
msgid "Check the IP of the Kubernetes service, or"
msgstr "Check the IP of the Kubernetes service, or"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Check the logs"
msgstr "Check the logs"
#:
#~ msgid "Check your Emails for a password reset link."
#~ msgstr "Check your Emails for a password reset link."
@ -1200,6 +1221,10 @@ msgstr "Create Token"
msgid "Create User"
msgstr "Create User"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Create a new application"
msgstr "Create a new application"
#: src/pages/users/ServiceAccountForm.ts
msgid "Create group"
msgstr "Create group"
@ -1260,6 +1285,10 @@ msgstr "Customisation"
msgid "DSA-SHA1"
msgstr "DSA-SHA1"
#: src/interfaces/AdminInterface.ts
msgid "Dashboards"
msgstr "Dashboards"
#: src/pages/stages/prompt/PromptForm.ts
msgid "Date"
msgstr "Date"
@ -1449,6 +1478,10 @@ msgstr "Digits"
msgid "Direct querying, always returns the latest data, but slower than cached querying."
msgstr "Direct querying, always returns the latest data, but slower than cached querying."
#: src/interfaces/AdminInterface.ts
msgid "Directory"
msgstr "Directory"
#:
#:
#~ msgid "Disable"
@ -1818,6 +1851,10 @@ msgstr "Expiry date"
msgid "Explicit Consent"
msgstr "Explicit Consent"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Explore integrations"
msgstr "Explore integrations"
#: src/pages/flows/FlowViewPage.ts
msgid "Export"
msgstr "Export"
@ -1855,7 +1892,6 @@ msgstr "External Applications which use authentik as Identity-Provider, utilizin
msgid "External Host"
msgstr "External Host"
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "External host"
@ -1866,6 +1902,10 @@ msgstr "External host"
msgid "Failed Logins"
msgstr "Failed Logins"
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "Failed Logins per day in the last month"
msgstr "Failed Logins per day in the last month"
#: src/pages/stages/password/PasswordStageForm.ts
msgid "Failed attempts before cancel"
msgstr "Failed attempts before cancel"
@ -1899,6 +1939,11 @@ msgstr "Failed to update {0}: {1}"
msgid "Favicon"
msgstr "Favicon"
#: src/interfaces/AdminInterface.ts
#: src/pages/sources/SourcesListPage.ts
msgid "Federation & Social login"
msgstr "Federation & Social login"
#: src/pages/stages/prompt/PromptListPage.ts
msgid "Field"
msgstr "Field"
@ -1944,6 +1989,10 @@ msgstr "Flow"
msgid "Flow Overview"
msgstr "Flow Overview"
#: src/pages/events/utils.ts
msgid "Flow execution"
msgstr "Flow execution"
#: src/flows/FlowInspector.ts
#: src/flows/FlowInspector.ts
msgid "Flow inspector"
@ -2270,8 +2319,8 @@ msgid "Identifier"
msgstr "Identifier"
#: src/interfaces/AdminInterface.ts
msgid "Identity & Cryptography"
msgstr "Identity & Cryptography"
#~ msgid "Identity & Cryptography"
#~ msgstr "Identity & Cryptography"
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
@ -2344,6 +2393,10 @@ 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/proxy/ProxyProviderForm.ts
msgid "In this case, you'd set the Authentication URL to auth.example.com and Cookie domain to example.com."
msgstr "In this case, you'd set the Authentication URL to auth.example.com and Cookie domain to example.com."
#: src/pages/users/UserListPage.ts
msgid "Inactive"
msgstr "Inactive"
@ -2366,8 +2419,8 @@ msgid "Integration key"
msgstr "Integration key"
#: src/interfaces/AdminInterface.ts
msgid "Integrations"
msgstr "Integrations"
#~ msgid "Integrations"
#~ msgstr "Integrations"
#: src/pages/tokens/TokenForm.ts
#: src/pages/tokens/TokenListPage.ts
@ -2689,6 +2742,10 @@ msgstr "Logins"
msgid "Logins over the last 24 hours"
msgstr "Logins over the last 24 hours"
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "Logins per day in the last month"
msgstr "Logins per day in the last month"
#: src/pages/tenants/TenantForm.ts
msgid "Logo"
msgstr "Logo"
@ -2996,6 +3053,10 @@ msgstr "No Stages bound"
msgid "No additional data available."
msgstr "No additional data available."
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
msgid "No additional setup is required."
msgstr "No additional setup is required."
#: src/elements/forms/ModalForm.ts
msgid "No form found"
msgstr "No form found"
@ -3143,6 +3204,10 @@ msgstr "Object field"
msgid "Object uniqueness field"
msgstr "Object uniqueness field"
#: src/elements/charts/AdminModelPerDay.ts
msgid "Objects created"
msgstr "Objects created"
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
@ -3161,6 +3226,10 @@ msgstr "Only fail the policy, don't invalidate user's password."
msgid "Only send notification once, for example when sending a webhook into a chat channel."
msgstr "Only send notification once, for example when sending a webhook into a chat channel."
#: src/elements/notifications/APIDrawer.ts
msgid "Open API Browser"
msgstr "Open API Browser"
#:
#~ msgid "Open application"
#~ msgstr "Open application"
@ -3210,8 +3279,8 @@ msgid "Optionally set the 'FriendlyName' value of the Assertion attribute."
msgstr "Optionally set the 'FriendlyName' value of the Assertion attribute."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "Optionally set this to your parent domain, if you want authentication and authorization to happen on a domain level. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
msgstr "Optionally set this to your parent domain, if you want authentication and authorization to happen on a domain level. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
#~ msgid "Optionally set this to your parent domain, if you want authentication and authorization to happen on a domain level. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
#~ msgstr "Optionally set this to your parent domain, if you want authentication and authorization to happen on a domain level. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
#: src/pages/flows/BoundStagesList.ts
#: src/pages/flows/StageBindingForm.ts
@ -3239,6 +3308,10 @@ msgstr "Outdated outposts"
msgid "Outpost Deployment Info"
msgstr "Outpost Deployment Info"
#: src/interfaces/AdminInterface.ts
msgid "Outpost Integrations"
msgstr "Outpost Integrations"
#:
#~ msgid "Outpost Service-connection"
#~ msgstr "Outpost Service-connection"
@ -3259,7 +3332,6 @@ msgstr "Outpost status"
msgid "Outpost(s)"
msgstr "Outpost(s)"
#: src/interfaces/AdminInterface.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/outposts/OutpostListPage.ts
msgid "Outposts"
@ -3365,7 +3437,6 @@ msgid "Please enter your password"
msgstr "Please enter your password"
#: src/interfaces/AdminInterface.ts
#: src/pages/admin-overview/AdminOverviewPage.ts
#: src/pages/flows/FlowListPage.ts
#: src/pages/policies/PolicyListPage.ts
msgid "Policies"
@ -3584,6 +3655,10 @@ msgstr "Public key, acquired from https://www.google.com/recaptcha/intro/v3.html
msgid "Publisher"
msgstr "Publisher"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Quick actions"
msgstr "Quick actions"
#: src/pages/flows/StageBindingForm.ts
msgid "RESTART restarts the flow from the beginning, while keeping the flow context."
msgstr "RESTART restarts the flow from the beginning, while keeping the flow context."
@ -3761,14 +3836,18 @@ msgid "Reset Password"
msgstr "Reset Password"
#: src/interfaces/AdminInterface.ts
msgid "Resources"
msgstr "Resources"
#~ msgid "Resources"
#~ msgstr "Resources"
#: src/pages/events/EventInfo.ts
#: src/pages/property-mappings/PropertyMappingTestForm.ts
msgid "Result"
msgstr "Result"
#: src/flows/sources/apple/AppleLoginInit.ts
msgid "Retry"
msgstr "Retry"
#:
#~ msgid "Retry Task"
#~ msgstr "Retry Task"
@ -4109,6 +4188,10 @@ msgstr "Set a custom HTTP-Basic Authentication header based on values from authe
msgid "Set custom attributes using YAML or JSON."
msgstr "Set custom attributes using YAML or JSON."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "Set this to the domain you wish the authentication to be valid for. Must be a parent domain of the URL above. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
msgstr "Set this to the domain you wish the authentication to be valid for. Must be a parent domain of the URL above. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
msgid "Setup"
msgstr "Setup"
@ -4206,8 +4289,6 @@ msgstr "Source {0}"
msgid "Source(s)"
msgstr "Source(s)"
#: src/interfaces/AdminInterface.ts
#: src/pages/sources/SourcesListPage.ts
#: src/pages/stages/identification/IdentificationStageForm.ts
msgid "Sources"
msgstr "Sources"
@ -4298,6 +4379,7 @@ msgstr "Stage(s)"
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
#: src/pages/stages/captcha/CaptchaStageForm.ts
#: src/pages/stages/consent/ConsentStageForm.ts
#: src/pages/stages/email/EmailStageForm.ts
@ -4734,9 +4816,13 @@ msgstr "Sync status"
msgid "Sync users"
msgstr "Sync users"
#: src/interfaces/AdminInterface.ts
msgid "System"
msgstr "System"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "System Overview"
msgstr "System Overview"
#~ msgid "System Overview"
#~ msgstr "System Overview"
#: src/interfaces/AdminInterface.ts
#: src/pages/system-tasks/SystemTaskListPage.ts
@ -4845,8 +4931,12 @@ msgid "The external URL you'll access the application at. Include any non-standa
msgstr "The external URL you'll access the application at. Include any non-standard port."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
msgstr "The external URL you'll authenticate at. Can be the same domain as authentik."
#~ msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
#~ msgstr "The external URL you'll authenticate at. Can be the same domain as authentik."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
#:
#~ msgid "The following objects use {0}:"
@ -5115,6 +5205,7 @@ msgid "UI settings"
msgstr "UI settings"
#: src/pages/events/EventInfo.ts
#: src/pages/users/UserListPage.ts
msgid "UID"
msgstr "UID"
@ -5467,6 +5558,10 @@ msgstr "User interface"
msgid "User matching mode"
msgstr "User matching mode"
#: src/pages/admin-overview/UserDashboardPage.ts
#~ msgid "User metrics"
#~ msgstr "User metrics"
#: src/pages/sources/ldap/LDAPSourceForm.ts
msgid "User object filter"
msgstr "User object filter"
@ -5475,10 +5570,30 @@ msgstr "User object filter"
msgid "User password writeback"
msgstr "User password writeback"
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "User statistics"
msgstr "User statistics"
#: src/pages/users/UserListPage.ts
msgid "User status"
msgstr "User status"
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification"
msgstr "User verification"
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification is preferred if available, but not required."
msgstr "User verification is preferred if available, but not required."
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification must occur."
msgstr "User verification must occur."
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification should not occur."
msgstr "User verification should not occur."
#: src/pages/events/utils.ts
msgid "User was written to"
msgstr "User was written to"
@ -5529,6 +5644,7 @@ msgstr "Username"
msgid "Username: Same as Text input, but checks for and prevents duplicate usernames."
msgstr "Username: Same as Text input, but checks for and prevents duplicate usernames."
#: src/interfaces/AdminInterface.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/admin-overview/AdminOverviewPage.ts
#: src/pages/users/UserListPage.ts
@ -5539,6 +5655,10 @@ msgstr "Users"
msgid "Users added to this group will be superusers."
msgstr "Users added to this group will be superusers."
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "Users created per day in the last month"
msgstr "Users created per day in the last month"
#: src/pages/providers/ldap/LDAPProviderForm.ts
msgid "Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed."
msgstr "Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed."
@ -5651,6 +5771,10 @@ msgstr "Warning: Provider is not used by any Outpost."
msgid "Warning: Provider not assigned to any application."
msgstr "Warning: Provider not assigned to any application."
#: src/pages/users/UserListPage.ts
msgid "Warning: You're about to delete the user you're logged in as ({0}). Proceed at your own risk."
msgstr "Warning: You're about to delete the user you're logged in as ({0}). Proceed at your own risk."
#: src/pages/outposts/OutpostListPage.ts
msgid "Warning: authentik Domain is not configured, authentication will not work."
msgstr "Warning: authentik Domain is not configured, authentication will not work."
@ -5679,6 +5803,10 @@ msgstr "Webhook Mapping"
msgid "Webhook URL"
msgstr "Webhook URL"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Welcome, {name}."
msgstr "Welcome, {name}."
#: src/pages/stages/email/EmailStageForm.ts
msgid "When a user returns from the email successfully, their account will be activated."
msgstr "When a user returns from the email successfully, their account will be activated."
@ -5782,6 +5910,10 @@ msgstr "You're about to be redirect to the following URL."
msgid "You're currently impersonating {0}. Click to stop."
msgstr "You're currently impersonating {0}. Click to stop."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "app1 running on app1.example.com"
msgstr "app1 running on app1.example.com"
#:
#~ msgid "authentik Builtin Database"
#~ msgstr "authentik Builtin Database"
@ -5790,6 +5922,10 @@ msgstr "You're currently impersonating {0}. Click to stop."
#~ msgid "authentik LDAP Backend"
#~ msgstr "authentik LDAP Backend"
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "authentik running on auth.example.com"
msgstr "authentik running on auth.example.com"
#: src/elements/forms/DeleteForm.ts
msgid "connecting object will be deleted"
msgstr "connecting object will be deleted"
@ -5858,3 +5994,11 @@ msgstr "{0}, should be {1}"
#: src/elements/forms/ConfirmationForm.ts
msgid "{0}: {1}"
msgstr "{0}: {1}"
#: src/elements/charts/AdminModelPerDay.ts
msgid "{ago} days ago"
msgstr "{ago} days ago"
#: src/elements/charts/Chart.ts
msgid "{ago} hours ago"
msgstr "{ago} hours ago"

View File

@ -300,6 +300,10 @@ msgstr "Sinon, si Duo est installé sur cet appareil, cliquez sur ce lien :"
msgid "Always require consent"
msgstr "Toujours exiger l'approbation"
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "An example setup can look like this:"
msgstr ""
#: src/pages/stages/prompt/PromptForm.ts
msgid "Any HTML can be used."
msgstr ""
@ -348,6 +352,7 @@ msgstr "Nom d'affichage de l'application"
msgid "Application(s)"
msgstr "Application(s)"
#: src/interfaces/AdminInterface.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/outposts/OutpostForm.ts
@ -411,8 +416,12 @@ msgid "Assigned to application"
msgstr "Assigné à l'application"
#: src/pages/policies/PolicyListPage.ts
msgid "Assigned to {0} objects."
msgstr "Assigné à {0} objets"
msgid "Assigned to {0} object(s)."
msgstr ""
#: src/pages/policies/PolicyListPage.ts
#~ msgid "Assigned to {0} objects."
#~ msgstr "Assigné à {0} objets"
#: src/pages/events/EventInfo.ts
msgid "Attempted to log in as {0}"
@ -437,6 +446,10 @@ msgstr "Audience"
#~ msgid "Auth Type"
#~ msgstr ""
#: src/flows/sources/apple/AppleLoginInit.ts
msgid "Authenticating with Apple..."
msgstr ""
#: src/flows/sources/plex/PlexLoginInit.ts
msgid "Authenticating with Plex..."
msgstr "Authentification avec Plex..."
@ -449,6 +462,10 @@ msgstr "Authentification"
msgid "Authentication Type"
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "Authentication URL"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts
#: src/pages/sources/plex/PlexSourceForm.ts
#: src/pages/sources/saml/SAMLSourceForm.ts
@ -761,6 +778,10 @@ msgstr "Vérifier le statut"
msgid "Check the IP of the Kubernetes service, or"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Check the logs"
msgstr ""
#:
#~ msgid "Check your Emails for a password reset link."
#~ msgstr "Vérifiez vos courriels pour un lien de récupération de mot de passe."
@ -1198,6 +1219,10 @@ msgstr "Créer un jeton"
msgid "Create User"
msgstr "Créer un utilisateu"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Create a new application"
msgstr ""
#: src/pages/users/ServiceAccountForm.ts
msgid "Create group"
msgstr "Créer un groupe"
@ -1258,6 +1283,10 @@ msgstr "Personalisation"
msgid "DSA-SHA1"
msgstr "DSA-SHA1"
#: src/interfaces/AdminInterface.ts
msgid "Dashboards"
msgstr ""
#: src/pages/stages/prompt/PromptForm.ts
msgid "Date"
msgstr "Date"
@ -1439,6 +1468,10 @@ msgstr "Chiffres"
msgid "Direct querying, always returns the latest data, but slower than cached querying."
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "Directory"
msgstr ""
#~ msgid "Disable"
#~ msgstr "Désactiver"
@ -1804,6 +1837,10 @@ msgstr "Date d'expiration"
msgid "Explicit Consent"
msgstr "Approbation explicite"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Explore integrations"
msgstr ""
#: src/pages/flows/FlowViewPage.ts
msgid "Export"
msgstr "Exporter"
@ -1841,7 +1878,6 @@ msgstr "Applications externes qui utilisent authentik comme fournisseur d'identi
msgid "External Host"
msgstr "Hôte externe"
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "External host"
@ -1852,6 +1888,10 @@ msgstr "Hôte externe"
msgid "Failed Logins"
msgstr "Connexions échouées"
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "Failed Logins per day in the last month"
msgstr ""
#: src/pages/stages/password/PasswordStageForm.ts
msgid "Failed attempts before cancel"
msgstr "Échecs avant annulation"
@ -1885,6 +1925,11 @@ msgstr "Impossible de mettre à jour {0} : {1}"
msgid "Favicon"
msgstr "Favicon"
#: src/interfaces/AdminInterface.ts
#: src/pages/sources/SourcesListPage.ts
msgid "Federation & Social login"
msgstr ""
#: src/pages/stages/prompt/PromptListPage.ts
msgid "Field"
msgstr "Champ"
@ -1929,6 +1974,10 @@ msgstr "Flux"
msgid "Flow Overview"
msgstr "Aperçu du flux"
#: src/pages/events/utils.ts
msgid "Flow execution"
msgstr ""
#: src/flows/FlowInspector.ts
#: src/flows/FlowInspector.ts
msgid "Flow inspector"
@ -2253,8 +2302,8 @@ msgid "Identifier"
msgstr "Identifiant"
#: src/interfaces/AdminInterface.ts
msgid "Identity & Cryptography"
msgstr "Identité et chiffrement"
#~ msgid "Identity & Cryptography"
#~ msgstr "Identité et chiffrement"
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
@ -2327,6 +2376,10 @@ msgstr "Importer les certificats des fournisseurs externes ou créer des certifi
msgid "In case you can't access any other method."
msgstr "Au cas où aucune autre méthode ne soit disponible."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "In this case, you'd set the Authentication URL to auth.example.com and Cookie domain to example.com."
msgstr ""
#: src/pages/users/UserListPage.ts
msgid "Inactive"
msgstr "Inactif"
@ -2349,8 +2402,8 @@ msgid "Integration key"
msgstr "Clé d'intégration"
#: src/interfaces/AdminInterface.ts
msgid "Integrations"
msgstr "Intégrations"
#~ msgid "Integrations"
#~ msgstr "Intégrations"
#: src/pages/tokens/TokenForm.ts
#: src/pages/tokens/TokenListPage.ts
@ -2668,6 +2721,10 @@ msgstr "Connexions"
msgid "Logins over the last 24 hours"
msgstr "Connexions ces dernières 24 heures"
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "Logins per day in the last month"
msgstr ""
#: src/pages/tenants/TenantForm.ts
msgid "Logo"
msgstr "Logo"
@ -2974,6 +3031,10 @@ msgstr "Aucune étape liée"
msgid "No additional data available."
msgstr "Aucune donnée additionnelle disponible."
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
msgid "No additional setup is required."
msgstr ""
#: src/elements/forms/ModalForm.ts
msgid "No form found"
msgstr "Aucun formulaire trouvé"
@ -3119,6 +3180,10 @@ msgstr "Champ d'objet"
msgid "Object uniqueness field"
msgstr "Champ d'unicité de l'objet"
#: src/elements/charts/AdminModelPerDay.ts
msgid "Objects created"
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr "Durée d'expiration du consentement (Format : hours=1;minutes=2;seconds=3)."
@ -3137,6 +3202,10 @@ msgstr "Faire simplement échouer la politique sans invalider le mot de passe ut
msgid "Only send notification once, for example when sending a webhook into a chat channel."
msgstr "Envoyer une seule fois la notification, par exemple lors de l'envoi d'un webhook dans un canal de discussion."
#: src/elements/notifications/APIDrawer.ts
msgid "Open API Browser"
msgstr ""
#~ msgid "Open application"
#~ msgstr "Ouvrir l'appication"
@ -3185,8 +3254,8 @@ msgid "Optionally set the 'FriendlyName' value of the Assertion attribute."
msgstr "Indiquer la valeur \"FriendlyName\" de l'attribut d'assertion (optionnel)"
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "Optionally set this to your parent domain, if you want authentication and authorization to happen on a domain level. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
msgstr "Indiquer votre domaine parent (optionnel), si vous souhaitez que l'authentification et l'autorisation soient réalisés au niveau du domaine. Si vous exécutez des applications sur app1.domain.tld, app2.domain.tld, indiquez ici \"domain.tld\"."
#~ msgid "Optionally set this to your parent domain, if you want authentication and authorization to happen on a domain level. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
#~ msgstr "Indiquer votre domaine parent (optionnel), si vous souhaitez que l'authentification et l'autorisation soient réalisés au niveau du domaine. Si vous exécutez des applications sur app1.domain.tld, app2.domain.tld, indiquez ici \"domain.tld\"."
#: src/pages/flows/BoundStagesList.ts
#: src/pages/flows/StageBindingForm.ts
@ -3213,6 +3282,10 @@ msgstr "Avant-postes périmés"
msgid "Outpost Deployment Info"
msgstr "Info de déploiement de l'avant-poste"
#: src/interfaces/AdminInterface.ts
msgid "Outpost Integrations"
msgstr ""
#~ msgid "Outpost Service-connection"
#~ msgstr "Connexion de service de l'avant-poste"
@ -3231,7 +3304,6 @@ msgstr "Statut de l'avant-poste"
msgid "Outpost(s)"
msgstr "Avant-poste(s)"
#: src/interfaces/AdminInterface.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/outposts/OutpostListPage.ts
msgid "Outposts"
@ -3337,7 +3409,6 @@ msgid "Please enter your password"
msgstr "Veuillez saisir votre mot de passe"
#: src/interfaces/AdminInterface.ts
#: src/pages/admin-overview/AdminOverviewPage.ts
#: src/pages/flows/FlowListPage.ts
#: src/pages/policies/PolicyListPage.ts
msgid "Policies"
@ -3552,6 +3623,10 @@ msgstr "Clé publique, obtenue depuis https://www.google.com/recaptcha/intro/v3.
msgid "Publisher"
msgstr "Éditeur"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Quick actions"
msgstr ""
#: src/pages/flows/StageBindingForm.ts
msgid "RESTART restarts the flow from the beginning, while keeping the flow context."
msgstr "REDÉMARRER redémarre le flux depuis le début, en gardant le contexte du flux."
@ -3732,14 +3807,18 @@ msgid "Reset Password"
msgstr "Réinitialiser le mot de passe"
#: src/interfaces/AdminInterface.ts
msgid "Resources"
msgstr "Ressources"
#~ msgid "Resources"
#~ msgstr "Ressources"
#: src/pages/events/EventInfo.ts
#: src/pages/property-mappings/PropertyMappingTestForm.ts
msgid "Result"
msgstr "Résultat"
#: src/flows/sources/apple/AppleLoginInit.ts
msgid "Retry"
msgstr ""
#~ msgid "Retry Task"
#~ msgstr "Réessayer la tâche"
@ -4072,6 +4151,10 @@ msgstr "Définir un en-tête d'authentification HTTP-Basic personnalisé basé s
msgid "Set custom attributes using YAML or JSON."
msgstr "Définissez des attributs personnalisés via YAML ou JSON."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "Set this to the domain you wish the authentication to be valid for. Must be a parent domain of the URL above. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
msgstr ""
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
msgid "Setup"
msgstr ""
@ -4168,8 +4251,6 @@ msgstr "Source {0}"
msgid "Source(s)"
msgstr "Source(s)"
#: src/interfaces/AdminInterface.ts
#: src/pages/sources/SourcesListPage.ts
#: src/pages/stages/identification/IdentificationStageForm.ts
msgid "Sources"
msgstr "Sources"
@ -4258,6 +4339,7 @@ msgstr "Étape(s)"
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
#: src/pages/stages/captcha/CaptchaStageForm.ts
#: src/pages/stages/consent/ConsentStageForm.ts
#: src/pages/stages/email/EmailStageForm.ts
@ -4689,9 +4771,13 @@ msgstr "Synchroniser les statuts"
msgid "Sync users"
msgstr "Synchroniser les utilisateurs"
#: src/interfaces/AdminInterface.ts
msgid "System"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "System Overview"
msgstr "Vue d'ensemble du système"
#~ msgid "System Overview"
#~ msgstr "Vue d'ensemble du système"
#: src/interfaces/AdminInterface.ts
#: src/pages/system-tasks/SystemTaskListPage.ts
@ -4799,8 +4885,12 @@ msgid "The external URL you'll access the application at. Include any non-standa
msgstr "L'URL externe par laquelle vous accéderez à l'application. Incluez un port non-standard si besoin."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
msgstr "L'URL externe sur laquelle vous vous authentifierez. Cela peut être le même domaine qu'authentik."
#~ msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
#~ msgstr "L'URL externe sur laquelle vous vous authentifierez. Cela peut être le même domaine qu'authentik."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr ""
#~ msgid "The following objects use {0}:"
#~ msgstr "Les objets suivants utilisent {0} :"
@ -5056,6 +5146,7 @@ msgid "UI settings"
msgstr "Paramètres d'UI"
#: src/pages/events/EventInfo.ts
#: src/pages/users/UserListPage.ts
msgid "UID"
msgstr "UID"
@ -5405,6 +5496,10 @@ msgstr "Interface utilisateur"
msgid "User matching mode"
msgstr "Mode de correspondance utilisateur"
#: src/pages/admin-overview/UserDashboardPage.ts
#~ msgid "User metrics"
#~ msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts
msgid "User object filter"
msgstr "Filtre des objets utilisateur"
@ -5413,10 +5508,30 @@ msgstr "Filtre des objets utilisateur"
msgid "User password writeback"
msgstr "Réécriture du mot de passe utilisateur"
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "User statistics"
msgstr ""
#: src/pages/users/UserListPage.ts
msgid "User status"
msgstr "Statut utilisateur"
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification"
msgstr ""
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification is preferred if available, but not required."
msgstr ""
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification must occur."
msgstr ""
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification should not occur."
msgstr ""
#: src/pages/events/utils.ts
msgid "User was written to"
msgstr "L'utilisateur a été écrit vers "
@ -5467,6 +5582,7 @@ msgstr "Nom d'utilisateur"
msgid "Username: Same as Text input, but checks for and prevents duplicate usernames."
msgstr "Nom d'utilisateur : Identique à la saisie de texte, mais vérifie et empêche les noms d'utilisateur en double."
#: src/interfaces/AdminInterface.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/admin-overview/AdminOverviewPage.ts
#: src/pages/users/UserListPage.ts
@ -5477,6 +5593,10 @@ msgstr "Utilisateurs"
msgid "Users added to this group will be superusers."
msgstr "Les utilisateurs ajoutés à ce groupe seront des super-utilisateurs."
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "Users created per day in the last month"
msgstr ""
#: src/pages/providers/ldap/LDAPProviderForm.ts
msgid "Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed."
msgstr "Les utilisateurs de ce groupe peuvent effectuer des recherches. Si aucun groupe n'est sélectionné, aucune recherche LDAP n'est autorisée."
@ -5589,6 +5709,10 @@ msgstr ""
msgid "Warning: Provider not assigned to any application."
msgstr "Avertissement : le fournisseur n'est assigné à aucune application."
#: src/pages/users/UserListPage.ts
msgid "Warning: You're about to delete the user you're logged in as ({0}). Proceed at your own risk."
msgstr ""
#: src/pages/outposts/OutpostListPage.ts
msgid "Warning: authentik Domain is not configured, authentication will not work."
msgstr "Avertissement : le domaine d'authentik n'est pas configuré, l'authentification ne fonctionnera pas."
@ -5617,6 +5741,10 @@ msgstr "Mapping Webhook"
msgid "Webhook URL"
msgstr "URL Webhoo"
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Welcome, {name}."
msgstr ""
#: src/pages/stages/email/EmailStageForm.ts
msgid "When a user returns from the email successfully, their account will be activated."
msgstr "Lorsqu'un utilisateur revient de l'e-mail avec succès, son compte sera activé."
@ -5718,12 +5846,20 @@ msgstr "Vous allez être redirigé vers l'URL suivante."
msgid "You're currently impersonating {0}. Click to stop."
msgstr "Vous êtes en train de vous faire passer pour {0}. Cliquez pour arrêter."
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "app1 running on app1.example.com"
msgstr ""
#~ msgid "authentik Builtin Database"
#~ msgstr "Base de données intégrée à authentik"
#~ msgid "authentik LDAP Backend"
#~ msgstr "Backend LDAP authentik"
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "authentik running on auth.example.com"
msgstr ""
#: src/elements/forms/DeleteForm.ts
msgid "connecting object will be deleted"
msgstr "L'objet connecté sera supprimé"
@ -5792,3 +5928,11 @@ msgstr "{0}, devrait être {1}"
#: src/elements/forms/ConfirmationForm.ts
msgid "{0}: {1}"
msgstr "{0} : {1}"
#: src/elements/charts/AdminModelPerDay.ts
msgid "{ago} days ago"
msgstr ""
#: src/elements/charts/Chart.ts
msgid "{ago} hours ago"
msgstr ""

View File

@ -296,6 +296,10 @@ msgstr ""
msgid "Always require consent"
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "An example setup can look like this:"
msgstr ""
#: src/pages/stages/prompt/PromptForm.ts
msgid "Any HTML can be used."
msgstr ""
@ -344,6 +348,7 @@ msgstr ""
msgid "Application(s)"
msgstr ""
#: src/interfaces/AdminInterface.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/applications/ApplicationListPage.ts
#: src/pages/outposts/OutpostForm.ts
@ -403,9 +408,13 @@ msgid "Assigned to application"
msgstr ""
#: src/pages/policies/PolicyListPage.ts
msgid "Assigned to {0} objects."
msgid "Assigned to {0} object(s)."
msgstr ""
#: src/pages/policies/PolicyListPage.ts
#~ msgid "Assigned to {0} objects."
#~ msgstr ""
#: src/pages/events/EventInfo.ts
msgid "Attempted to log in as {0}"
msgstr ""
@ -429,6 +438,10 @@ msgstr ""
#~ msgid "Auth Type"
#~ msgstr ""
#: src/flows/sources/apple/AppleLoginInit.ts
msgid "Authenticating with Apple..."
msgstr ""
#: src/flows/sources/plex/PlexLoginInit.ts
msgid "Authenticating with Plex..."
msgstr ""
@ -441,6 +454,10 @@ msgstr ""
msgid "Authentication Type"
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "Authentication URL"
msgstr ""
#: src/pages/sources/oauth/OAuthSourceForm.ts
#: src/pages/sources/plex/PlexSourceForm.ts
#: src/pages/sources/saml/SAMLSourceForm.ts
@ -756,6 +773,10 @@ msgstr ""
msgid "Check the IP of the Kubernetes service, or"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Check the logs"
msgstr ""
#:
#~ msgid "Check your Emails for a password reset link."
#~ msgstr ""
@ -1194,6 +1215,10 @@ msgstr ""
msgid "Create User"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Create a new application"
msgstr ""
#: src/pages/users/ServiceAccountForm.ts
msgid "Create group"
msgstr ""
@ -1254,6 +1279,10 @@ msgstr ""
msgid "DSA-SHA1"
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "Dashboards"
msgstr ""
#: src/pages/stages/prompt/PromptForm.ts
msgid "Date"
msgstr ""
@ -1441,6 +1470,10 @@ msgstr ""
msgid "Direct querying, always returns the latest data, but slower than cached querying."
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "Directory"
msgstr ""
#:
#:
#~ msgid "Disable"
@ -1810,6 +1843,10 @@ msgstr ""
msgid "Explicit Consent"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Explore integrations"
msgstr ""
#: src/pages/flows/FlowViewPage.ts
msgid "Export"
msgstr ""
@ -1847,7 +1884,6 @@ msgstr ""
msgid "External Host"
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "External host"
@ -1858,6 +1894,10 @@ msgstr ""
msgid "Failed Logins"
msgstr ""
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "Failed Logins per day in the last month"
msgstr ""
#: src/pages/stages/password/PasswordStageForm.ts
msgid "Failed attempts before cancel"
msgstr ""
@ -1891,6 +1931,11 @@ msgstr ""
msgid "Favicon"
msgstr ""
#: src/interfaces/AdminInterface.ts
#: src/pages/sources/SourcesListPage.ts
msgid "Federation & Social login"
msgstr ""
#: src/pages/stages/prompt/PromptListPage.ts
msgid "Field"
msgstr ""
@ -1936,6 +1981,10 @@ msgstr ""
msgid "Flow Overview"
msgstr ""
#: src/pages/events/utils.ts
msgid "Flow execution"
msgstr ""
#: src/flows/FlowInspector.ts
#: src/flows/FlowInspector.ts
msgid "Flow inspector"
@ -2262,8 +2311,8 @@ msgid "Identifier"
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "Identity & Cryptography"
msgstr ""
#~ msgid "Identity & Cryptography"
#~ msgstr ""
#: src/pages/outposts/ServiceConnectionDockerForm.ts
#: src/pages/outposts/ServiceConnectionKubernetesForm.ts
@ -2336,6 +2385,10 @@ msgstr ""
msgid "In case you can't access any other method."
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "In this case, you'd set the Authentication URL to auth.example.com and Cookie domain to example.com."
msgstr ""
#: src/pages/users/UserListPage.ts
msgid "Inactive"
msgstr ""
@ -2358,8 +2411,8 @@ msgid "Integration key"
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "Integrations"
msgstr ""
#~ msgid "Integrations"
#~ msgstr ""
#: src/pages/tokens/TokenForm.ts
#: src/pages/tokens/TokenListPage.ts
@ -2679,6 +2732,10 @@ msgstr ""
msgid "Logins over the last 24 hours"
msgstr ""
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "Logins per day in the last month"
msgstr ""
#: src/pages/tenants/TenantForm.ts
msgid "Logo"
msgstr ""
@ -2986,6 +3043,10 @@ msgstr ""
msgid "No additional data available."
msgstr ""
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
msgid "No additional setup is required."
msgstr ""
#: src/elements/forms/ModalForm.ts
msgid "No form found"
msgstr ""
@ -3133,6 +3194,10 @@ msgstr ""
msgid "Object uniqueness field"
msgstr ""
#: src/elements/charts/AdminModelPerDay.ts
msgid "Objects created"
msgstr ""
#: src/pages/stages/consent/ConsentStageForm.ts
msgid "Offset after which consent expires. (Format: hours=1;minutes=2;seconds=3)."
msgstr ""
@ -3151,6 +3216,10 @@ msgstr ""
msgid "Only send notification once, for example when sending a webhook into a chat channel."
msgstr ""
#: src/elements/notifications/APIDrawer.ts
msgid "Open API Browser"
msgstr ""
#:
#~ msgid "Open application"
#~ msgstr ""
@ -3200,8 +3269,8 @@ msgid "Optionally set the 'FriendlyName' value of the Assertion attribute."
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "Optionally set this to your parent domain, if you want authentication and authorization to happen on a domain level. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
msgstr ""
#~ msgid "Optionally set this to your parent domain, if you want authentication and authorization to happen on a domain level. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
#~ msgstr ""
#: src/pages/flows/BoundStagesList.ts
#: src/pages/flows/StageBindingForm.ts
@ -3229,6 +3298,10 @@ msgstr ""
msgid "Outpost Deployment Info"
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "Outpost Integrations"
msgstr ""
#:
#~ msgid "Outpost Service-connection"
#~ msgstr ""
@ -3249,7 +3322,6 @@ msgstr ""
msgid "Outpost(s)"
msgstr ""
#: src/interfaces/AdminInterface.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/outposts/OutpostListPage.ts
msgid "Outposts"
@ -3355,7 +3427,6 @@ msgid "Please enter your password"
msgstr ""
#: src/interfaces/AdminInterface.ts
#: src/pages/admin-overview/AdminOverviewPage.ts
#: src/pages/flows/FlowListPage.ts
#: src/pages/policies/PolicyListPage.ts
msgid "Policies"
@ -3574,6 +3645,10 @@ msgstr ""
msgid "Publisher"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Quick actions"
msgstr ""
#: src/pages/flows/StageBindingForm.ts
msgid "RESTART restarts the flow from the beginning, while keeping the flow context."
msgstr ""
@ -3751,14 +3826,18 @@ msgid "Reset Password"
msgstr ""
#: src/interfaces/AdminInterface.ts
msgid "Resources"
msgstr ""
#~ msgid "Resources"
#~ msgstr ""
#: src/pages/events/EventInfo.ts
#: src/pages/property-mappings/PropertyMappingTestForm.ts
msgid "Result"
msgstr ""
#: src/flows/sources/apple/AppleLoginInit.ts
msgid "Retry"
msgstr ""
#:
#~ msgid "Retry Task"
#~ msgstr ""
@ -4099,6 +4178,10 @@ msgstr ""
msgid "Set custom attributes using YAML or JSON."
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "Set this to the domain you wish the authentication to be valid for. Must be a parent domain of the URL above. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'."
msgstr ""
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
msgid "Setup"
msgstr ""
@ -4196,8 +4279,6 @@ msgstr ""
msgid "Source(s)"
msgstr ""
#: src/interfaces/AdminInterface.ts
#: src/pages/sources/SourcesListPage.ts
#: src/pages/stages/identification/IdentificationStageForm.ts
msgid "Sources"
msgstr ""
@ -4288,6 +4369,7 @@ msgstr ""
#: src/pages/stages/authenticator_static/AuthenticatorStaticStageForm.ts
#: src/pages/stages/authenticator_totp/AuthenticatorTOTPStageForm.ts
#: src/pages/stages/authenticator_validate/AuthenticatorValidateStageForm.ts
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
#: src/pages/stages/captcha/CaptchaStageForm.ts
#: src/pages/stages/consent/ConsentStageForm.ts
#: src/pages/stages/email/EmailStageForm.ts
@ -4724,10 +4806,14 @@ msgstr ""
msgid "Sync users"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "System Overview"
#: src/interfaces/AdminInterface.ts
msgid "System"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts
#~ msgid "System Overview"
#~ msgstr ""
#: src/interfaces/AdminInterface.ts
#: src/pages/system-tasks/SystemTaskListPage.ts
msgid "System Tasks"
@ -4835,7 +4921,11 @@ msgid "The external URL you'll access the application at. Include any non-standa
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
#~ msgid "The external URL you'll authenticate at. Can be the same domain as authentik."
#~ msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "The external URL you'll authenticate at. The authentik core server should be reachable under this URL."
msgstr ""
#:
@ -5095,6 +5185,7 @@ msgid "UI settings"
msgstr ""
#: src/pages/events/EventInfo.ts
#: src/pages/users/UserListPage.ts
msgid "UID"
msgstr ""
@ -5447,6 +5538,10 @@ msgstr ""
msgid "User matching mode"
msgstr ""
#: src/pages/admin-overview/UserDashboardPage.ts
#~ msgid "User metrics"
#~ msgstr ""
#: src/pages/sources/ldap/LDAPSourceForm.ts
msgid "User object filter"
msgstr ""
@ -5455,10 +5550,30 @@ msgstr ""
msgid "User password writeback"
msgstr ""
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "User statistics"
msgstr ""
#: src/pages/users/UserListPage.ts
msgid "User status"
msgstr ""
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification"
msgstr ""
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification is preferred if available, but not required."
msgstr ""
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification must occur."
msgstr ""
#: src/pages/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm.ts
msgid "User verification should not occur."
msgstr ""
#: src/pages/events/utils.ts
msgid "User was written to"
msgstr ""
@ -5509,6 +5624,7 @@ msgstr ""
msgid "Username: Same as Text input, but checks for and prevents duplicate usernames."
msgstr ""
#: src/interfaces/AdminInterface.ts
#: src/interfaces/AdminInterface.ts
#: src/pages/admin-overview/AdminOverviewPage.ts
#: src/pages/users/UserListPage.ts
@ -5519,6 +5635,10 @@ msgstr ""
msgid "Users added to this group will be superusers."
msgstr ""
#: src/pages/admin-overview/DashboardUserPage.ts
msgid "Users created per day in the last month"
msgstr ""
#: src/pages/providers/ldap/LDAPProviderForm.ts
msgid "Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed."
msgstr ""
@ -5631,6 +5751,10 @@ msgstr ""
msgid "Warning: Provider not assigned to any application."
msgstr ""
#: src/pages/users/UserListPage.ts
msgid "Warning: You're about to delete the user you're logged in as ({0}). Proceed at your own risk."
msgstr ""
#: src/pages/outposts/OutpostListPage.ts
msgid "Warning: authentik Domain is not configured, authentication will not work."
msgstr ""
@ -5659,6 +5783,10 @@ msgstr ""
msgid "Webhook URL"
msgstr ""
#: src/pages/admin-overview/AdminOverviewPage.ts
msgid "Welcome, {name}."
msgstr ""
#: src/pages/stages/email/EmailStageForm.ts
msgid "When a user returns from the email successfully, their account will be activated."
msgstr ""
@ -5760,6 +5888,10 @@ msgstr ""
msgid "You're currently impersonating {0}. Click to stop."
msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "app1 running on app1.example.com"
msgstr ""
#:
#~ msgid "authentik Builtin Database"
#~ msgstr ""
@ -5768,6 +5900,10 @@ msgstr ""
#~ msgid "authentik LDAP Backend"
#~ msgstr ""
#: src/pages/providers/proxy/ProxyProviderForm.ts
msgid "authentik running on auth.example.com"
msgstr ""
#: src/elements/forms/DeleteForm.ts
msgid "connecting object will be deleted"
msgstr ""
@ -5836,3 +5972,11 @@ msgstr ""
#: src/elements/forms/ConfirmationForm.ts
msgid "{0}: {1}"
msgstr ""
#: src/elements/charts/AdminModelPerDay.ts
msgid "{ago} days ago"
msgstr ""
#: src/elements/charts/Chart.ts
msgid "{ago} hours ago"
msgstr ""

View File

@ -2,15 +2,19 @@ import { t } from "@lingui/macro";
import { CSSResult, LitElement, TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import AKGlobal from "../../authentik.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFList from "@patternfly/patternfly/components/List/list.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import { me } from "../../api/Users";
import "../../elements/PageHeader";
import "../../elements/cards/AggregatePromiseCard";
import "../../elements/charts/AdminLoginsChart";
import { paramURL } from "../../elements/router/RouterOutlet";
import "./TopApplicationsTable";
import "./cards/AdminStatusCard";
import "./cards/BackupStatusCard";
@ -31,6 +35,7 @@ export class AdminOverviewPage extends LitElement {
PFGrid,
PFPage,
PFContent,
PFList,
AKGlobal,
css`
.row-divider {
@ -51,11 +56,18 @@ export class AdminOverviewPage extends LitElement {
}
render(): TemplateResult {
return html` <ak-page-header
icon=""
header=${t`System Overview`}
description=${t`General system status`}
>
return html`<ak-page-header icon="" header="" description=${t`General system status`}>
<span slot="header">
${until(
me().then((user) => {
let name = user.user.username;
if (user.user.name !== "") {
name = user.user.name;
}
return t`Welcome, ${name}.`;
}),
)}
</span>
</ak-page-header>
<section class="pf-c-page__main-section">
<div class="pf-l-grid pf-m-gutter">
@ -64,11 +76,33 @@ export class AdminOverviewPage extends LitElement {
class="pf-l-grid__item pf-m-6-col pf-m-4-col-on-xl pf-m-2-col-on-2xl graph-container"
>
<ak-aggregate-card
icon="pf-icon pf-icon-infrastructure"
header=${t`Policies`}
headerLink="#/policy/policies"
icon="fa fa-share"
header=${t`Quick actions`}
.isCenter=${false}
>
<ak-admin-status-chart-policy></ak-admin-status-chart-policy>
<ul class="pf-c-list">
<li>
<a
class="pf-u-mb-xl"
href=${paramURL("/core/applications", {
createForm: true,
})}
>${t`Create a new application`}</a
>
</li>
<li>
<a class="pf-u-mb-xl" href=${paramURL("/events/log")}
>${t`Check the logs`}</a
>
</li>
<li>
<a
class="pf-u-mb-xl"
href="https://goauthentik.io/integrations/"
>${t`Explore integrations`}</a
>
</li>
</ul>
</ak-aggregate-card>
</div>
<div

View File

@ -0,0 +1,86 @@
import { t } from "@lingui/macro";
import { CSSResult, LitElement, TemplateResult, css, html } from "lit";
import { customElement } from "lit/decorators.js";
import AKGlobal from "../../authentik.css";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFList from "@patternfly/patternfly/components/List/list.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import { EventActions } from "@goauthentik/api";
import "../../elements/PageHeader";
import "../../elements/cards/AggregatePromiseCard";
import "../../elements/charts/AdminModelPerDay";
@customElement("ak-admin-dashboard-users")
export class DashboardUserPage extends LitElement {
static get styles(): CSSResult[] {
return [
PFGrid,
PFPage,
PFContent,
PFList,
AKGlobal,
css`
.row-divider {
margin-top: -4px;
margin-bottom: -4px;
}
.graph-container {
height: 20em;
}
.big-graph-container {
height: 35em;
}
.card-container {
max-height: 10em;
}
`,
];
}
render(): TemplateResult {
return html`<ak-page-header icon="pf-icon pf-icon-user" header=${t`User statistics`}>
</ak-page-header>
<section class="pf-c-page__main-section">
<div class="pf-l-grid pf-m-gutter">
<div
class="pf-l-grid__item pf-m-12-col pf-m-12-col-on-xl pf-m-12-col-on-2xl big-graph-container"
>
<ak-aggregate-card header=${t`Users created per day in the last month`}>
<ak-charts-admin-model-per-day
.query=${{
context__model__app: "authentik_core",
context__model__model_name: "user",
}}
>
</ak-charts-admin-model-per-day>
</ak-aggregate-card>
</div>
<div class="pf-l-grid__item pf-m-12-col row-divider">
<hr />
</div>
<!-- row 2 -->
<div
class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-6-col-on-2xl big-graph-container"
>
<ak-aggregate-card header=${t`Logins per day in the last month`}>
<ak-charts-admin-model-per-day action=${EventActions.Login}>
</ak-charts-admin-model-per-day>
</ak-aggregate-card>
</div>
<div
class="pf-l-grid__item pf-m-12-col pf-m-6-col-on-xl pf-m-6-col-on-2xl big-graph-container"
>
<ak-aggregate-card header=${t`Failed Logins per day in the last month`}>
<ak-charts-admin-model-per-day action=${EventActions.LoginFailed}>
</ak-charts-admin-model-per-day>
</ak-aggregate-card>
</div>
</div>
</section> `;
}
}

View File

@ -36,37 +36,41 @@ export class LDAPSyncStatusChart extends AKChart<LDAPSyncStats> {
async apiRequest(): Promise<LDAPSyncStats> {
const api = new SourcesApi(DEFAULT_CONFIG);
const sources = await api.sourcesLdapList({});
let healthy = 0;
let failed = 0;
let unsynced = 0;
const metrics: { [key: string]: number } = {
healthy: 0,
failed: 0,
unsynced: 0,
};
await Promise.all(
sources.results.map(async (element) => {
// Each source should have 3 successful tasks, so the worst task overwrites
let sourceKey = "healthy";
try {
const health = await api.sourcesLdapSyncStatusList({
slug: element.slug,
});
health.forEach((task) => {
if (task.status !== StatusEnum.Successful) {
failed += 1;
sourceKey = "failed";
}
const now = new Date().getTime();
const maxDelta = 3600000; // 1 hour
if (!health || now - task.taskFinishTimestamp.getTime() > maxDelta) {
unsynced += 1;
} else {
healthy += 1;
sourceKey = "unsynced";
}
});
} catch {
unsynced += 1;
sourceKey = "unsynced";
}
metrics[sourceKey] += 1;
}),
);
this.centerText = sources.pagination.count.toString();
return {
healthy: sources.pagination.count === 0 ? -1 : healthy,
failed,
unsynced,
healthy: sources.pagination.count === 0 ? -1 : metrics.healthy,
failed: metrics.failed,
unsynced: metrics.unsynced,
};
}

View File

@ -2,6 +2,7 @@ import { t } from "@lingui/macro";
import { CSSResult, TemplateResult, css, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
@ -13,6 +14,7 @@ import { uiConfig } from "../../common/config";
import "../../elements/buttons/SpinnerButton";
import "../../elements/forms/DeleteBulkForm";
import "../../elements/forms/ModalForm";
import { getURLParam } from "../../elements/router/RouteMatch";
import { TableColumn } from "../../elements/table/Table";
import { TablePage } from "../../elements/table/TablePage";
import "./ApplicationForm";
@ -94,15 +96,24 @@ export class ApplicationListPage extends TablePage<Application> {
</ak-forms-delete-bulk>`;
}
renderIcon(item: Application): TemplateResult {
if (item?.metaIcon) {
if (item.metaIcon.startsWith("fa://")) {
const icon = item.metaIcon.replaceAll("fa://", "");
return html`<i class="fas ${icon}"></i>`;
}
return html`<img
class="app-icon pf-c-avatar"
src="${ifDefined(item.metaIcon)}"
alt="${t`Application Icon`}"
/>`;
}
return html`<i class="fas fa-share-square"></i>`;
}
row(item: Application): TemplateResult[] {
return [
item.metaIcon
? html`<img
class="app-icon pf-c-avatar"
src="${item.metaIcon}"
alt="${t`Application Icon`}"
/>`
: html`<i class="fas fa-question-circle"></i>`,
this.renderIcon(item),
html`<a href="#/core/applications/${item.slug}">
<div>${item.name}</div>
${item.metaPublisher ? html`<small>${item.metaPublisher}</small>` : html``}
@ -133,7 +144,7 @@ export class ApplicationListPage extends TablePage<Application> {
renderToolbar(): TemplateResult {
return html`
<ak-forms-modal>
<ak-forms-modal .open=${getURLParam("createForm", false)}>
<span slot="submit"> ${t`Create`} </span>
<span slot="header"> ${t`Create Application`} </span>
<ak-application-form slot="form"> </ak-application-form>

View File

@ -31,6 +31,8 @@ export function ActionToLabel(action?: EventActions): string {
return t`Impersonation started`;
case EventActions.ImpersonationEnded:
return t`Impersonation ended`;
case EventActions.FlowExecution:
return t`Flow execution`;
case EventActions.PolicyExecution:
return t`Policy execution`;
case EventActions.PolicyException:

View File

@ -75,7 +75,7 @@ export class PolicyListPage extends TablePage<Policy> {
<div>${item.name}</div>
${(item.boundTo || 0) > 0
? html`<i class="pf-icon pf-icon-ok"></i>
<small> ${t`Assigned to ${item.boundTo} objects.`} </small>`
<small> ${t`Assigned to ${item.boundTo} object(s).`} </small>`
: html`<i class="pf-icon pf-icon-warning-triangle"></i>
<small>${t`Warning: Policy is not assigned.`}</small>`}
</div>`,

View File

@ -7,6 +7,7 @@ import { ifDefined } from "lit/directives/if-defined.js";
import { until } from "lit/directives/until.js";
import PFContent from "@patternfly/patternfly/components/Content/content.css";
import PFList from "@patternfly/patternfly/components/List/list.css";
import PFToggleGroup from "@patternfly/patternfly/components/ToggleGroup/toggle-group.css";
import PFSpacing from "@patternfly/patternfly/utilities/Spacing/spacing.css";
@ -32,6 +33,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
return super.styles.concat(
PFToggleGroup,
PFContent,
PFList,
PFSpacing,
css`
.pf-c-toggle-group {
@ -162,7 +164,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
renderSettings(): TemplateResult {
switch (this.mode) {
case ProxyMode.Proxy:
return html` <p class="pf-u-mb-xl">
return html`<p class="pf-u-mb-xl">
${t`This provider will behave like a transparent reverse-proxy, except requests must be authenticated. If your upstream application uses HTTPS, make sure to connect to the outpost using HTTPS as well.`}
</p>
<ak-form-element-horizontal
@ -211,7 +213,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
</p>
</ak-form-element-horizontal>`;
case ProxyMode.ForwardSingle:
return html` <p class="pf-u-mb-xl">
return html`<p class="pf-u-mb-xl">
${t`Use this provider with nginx's auth_request or traefik's forwardAuth. Each application/domain needs its own provider. Additionally, on each domain, /akprox must be routed to the outpost (when using a manged outpost, this is done for you).`}
</p>
<ak-form-element-horizontal
@ -230,11 +232,19 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
</p>
</ak-form-element-horizontal>`;
case ProxyMode.ForwardDomain:
return html` <p class="pf-u-mb-xl">
return html`<p class="pf-u-mb-xl">
${t`Use this provider with nginx's auth_request or traefik's forwardAuth. Only a single provider is required per root domain. You can't do per-application authorization, but you don't have to create a provider for each application.`}
</p>
<div class="pf-u-mb-xl">
${t`An example setup can look like this:`}
<ul class="pf-c-list">
<li>${t`authentik running on auth.example.com`}</li>
<li>${t`app1 running on app1.example.com`}</li>
</ul>
${t`In this case, you'd set the Authentication URL to auth.example.com and Cookie domain to example.com.`}
</div>
<ak-form-element-horizontal
label=${t`External host`}
label=${t`Authentication URL`}
?required=${true}
name="externalHost"
>
@ -245,10 +255,14 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
required
/>
<p class="pf-c-form__helper-text">
${t`The external URL you'll authenticate at. Can be the same domain as authentik.`}
${t`The external URL you'll authenticate at. The authentik core server should be reachable under this URL.`}
</p>
</ak-form-element-horizontal>
<ak-form-element-horizontal label=${t`Cookie domain`} name="cookieDomain">
<ak-form-element-horizontal
label=${t`Cookie domain`}
name="cookieDomain"
?required=${true}
>
<input
type="text"
value="${ifDefined(this.instance?.cookieDomain)}"
@ -256,7 +270,7 @@ export class ProxyProviderFormPage extends ModelForm<ProxyProvider, number> {
required
/>
<p class="pf-c-form__helper-text">
${t`Optionally set this to your parent domain, if you want authentication and authorization to happen on a domain level. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'.`}
${t`Set this to the domain you wish the authentication to be valid for. Must be a parent domain of the URL above. If you're running applications as app1.domain.tld, app2.domain.tld, set this to 'domain.tld'.`}
</p>
</ak-form-element-horizontal>`;
}

View File

@ -92,10 +92,17 @@ export class ProxyProviderViewPage extends LitElement {
renderConfigTemplate(tmpl: string): TemplateResult {
// See website/docs/providers/proxy/forward_auth.mdx
const final = tmpl
.replaceAll("authentik.company", window.location.hostname)
.replaceAll("outpost.company", window.location.hostname)
.replaceAll("app.company", this.provider?.externalHost || "");
let final = "";
if (this.provider?.mode === ProxyMode.ForwardSingle) {
final = tmpl
.replaceAll("authentik.company", window.location.hostname)
.replaceAll("outpost.company", window.location.hostname)
.replaceAll("app.company", this.provider?.externalHost || "");
} else if (this.provider?.mode == ProxyMode.ForwardDomain) {
final = tmpl
.replaceAll("authentik.company", window.location.hostname)
.replaceAll("outpost.company", this.provider?.externalHost || "");
}
return html`${unsafeHTML(final)}`;
}
@ -233,50 +240,56 @@ export class ProxyProviderViewPage extends LitElement {
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
<div class="pf-c-card__title">${t`Setup`}</div>
<div class="pf-c-card__body">
<ak-tabs pageIdentifier="proxy-setup">
<section
slot="page-nginx-ingress"
data-tab-title="${t`Nginx (Ingress)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDNginxIngress.html)}
</section>
<section
slot="page-nginx-proxy-manager"
data-tab-title="${t`Nginx (Proxy Manager)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDNginxPM.html)}
</section>
<section
slot="page-nginx-standalone"
data-tab-title="${t`Nginx (standalone)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDNginxStandalone.html)}
</section>
<section
slot="page-traefik-ingress"
data-tab-title="${t`Traefik (Ingress)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDTraefikIngres.html)}
</section>
<section
slot="page-traefik-compose"
data-tab-title="${t`Traefik (Compose)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDTraefikCompose.html)}
</section>
<section
slot="page-traefik-standalone"
data-tab-title="${t`Traefik (Standalone)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDTraefikStandalone.html)}
</section>
</ak-tabs>
${[ProxyMode.ForwardSingle, ProxyMode.ForwardDomain].includes(
this.provider?.mode || ProxyMode.Proxy,
)
? html`
<ak-tabs pageIdentifier="proxy-setup">
<section
slot="page-nginx-ingress"
data-tab-title="${t`Nginx (Ingress)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDNginxIngress.html)}
</section>
<section
slot="page-nginx-proxy-manager"
data-tab-title="${t`Nginx (Proxy Manager)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDNginxPM.html)}
</section>
<section
slot="page-nginx-standalone"
data-tab-title="${t`Nginx (standalone)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDNginxStandalone.html)}
</section>
<section
slot="page-traefik-ingress"
data-tab-title="${t`Traefik (Ingress)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDTraefikIngres.html)}
</section>
<section
slot="page-traefik-compose"
data-tab-title="${t`Traefik (Compose)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDTraefikCompose.html)}
</section>
<section
slot="page-traefik-standalone"
data-tab-title="${t`Traefik (Standalone)`}"
class="pf-c-page__main-section pf-m-light pf-m-no-padding-mobile"
>
${this.renderConfigTemplate(MDTraefikStandalone.html)}
</section>
</ak-tabs>
`
: html` <p>${t`No additional setup is required.`}</p> `}
</div>
</div>
</div>`;

View File

@ -25,7 +25,7 @@ import "./saml/SAMLSourceForm";
@customElement("ak-source-list")
export class SourceListPage extends TablePage<Source> {
pageTitle(): string {
return t`Sources`;
return t`Federation & Social login`;
}
pageDescription(): string | undefined {
return t`Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.`;
@ -139,8 +139,7 @@ export class SourceListPage extends TablePage<Source> {
>
</ak-proxy-form>
<button slot="trigger" class="pf-c-dropdown__menu-item">
${type.name}<br />
<small>${type.description}</small>
${type.name}
</button>
</ak-forms-modal>
</li>`;

View File

@ -1,3 +1,5 @@
import { UserVerificationEnum } from "@goauthentik/api/dist/models/UserVerificationEnum";
import { t } from "@lingui/macro";
import { TemplateResult, html } from "lit";
@ -52,6 +54,40 @@ export class AuthenticateWebAuthnStageForm extends ModelForm<AuthenticateWebAuth
required
/>
</ak-form-element-horizontal>
<ak-form-group .expanded=${true}>
<span slot="header"> ${t`Stage-specific settings`} </span>
<div slot="body" class="pf-c-form">
<ak-form-element-horizontal
label=${t`User verification`}
?required=${true}
name="userVerification"
>
<select name="users" class="pf-c-form-control">
<option
value="${UserVerificationEnum.Required}"
?selected=${this.instance?.userVerification ===
UserVerificationEnum.Required}
>
${t`User verification must occur.`}
</option>
<option
value="${UserVerificationEnum.Preferred}"
?selected=${this.instance?.userVerification ===
UserVerificationEnum.Preferred}
>
${t`User verification is preferred if available, but not required.`}
</option>
<option
value="${UserVerificationEnum.Discouraged}"
?selected=${this.instance?.userVerification ===
UserVerificationEnum.Discouraged}
>
${t`User verification should not occur.`}
</option>
</select>
</ak-form-element-horizontal>
</div>
</ak-form-group>
</form>`;
}
}

View File

@ -4,12 +4,14 @@ import { CSSResult, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import PFAlert from "@patternfly/patternfly/components/Alert/alert.css";
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
import { CoreApi, User } from "@goauthentik/api";
import { AKResponse } from "../../api/Client";
import { DEFAULT_CONFIG, tenant } from "../../api/Config";
import { me } from "../../api/Users";
import { uiConfig } from "../../common/config";
import { PFColor } from "../../elements/Label";
import "../../elements/buttons/ActionButton";
@ -51,7 +53,7 @@ export class UserListPage extends TablePage<User> {
hideServiceAccounts = getURLParam<boolean>("hideServiceAccounts", true);
static get styles(): CSSResult[] {
return super.styles.concat(PFDescriptionList);
return super.styles.concat(PFDescriptionList, PFAlert);
}
async apiEndpoint(page: number): Promise<AKResponse<User>> {
@ -79,13 +81,14 @@ export class UserListPage extends TablePage<User> {
renderToolbarSelected(): TemplateResult {
const disabled = this.selectedElements.length < 1;
return html` <ak-forms-delete-bulk
return html`<ak-forms-delete-bulk
objectLabel=${t`User(s)`}
.objects=${this.selectedElements}
.metadata=${(item: User) => {
return [
{ key: t`Username`, value: item.username },
{ key: t`ID`, value: item.pk.toString() },
{ key: t`UID`, value: item.uid },
];
}}
.usedBy=${(item: User) => {
@ -99,6 +102,28 @@ export class UserListPage extends TablePage<User> {
});
}}
>
${until(
me().then((user) => {
const shouldShowWarning = this.selectedElements.find((el) => {
return el.pk === user.user.pk || el.pk == user.original?.pk;
});
if (shouldShowWarning) {
return html`
<div slot="notice" class="pf-c-form__alert">
<div class="pf-c-alert pf-m-inline pf-m-warning">
<div class="pf-c-alert__icon">
<i class="fas fa-exclamation-circle"></i>
</div>
<h4 class="pf-c-alert__title">
${t`Warning: You're about to delete the user you're logged in as (${shouldShowWarning.username}). Proceed at your own risk.`}
</h4>
</div>
</div>
`;
}
return html``;
}),
)}
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
${t`Delete`}
</button>

View File

@ -2,6 +2,7 @@ import { html } from "lit";
import { ID_REGEX, Route, SLUG_REGEX, UUID_REGEX } from "./elements/router/Route";
import "./pages/admin-overview/AdminOverviewPage";
import "./pages/admin-overview/DashboardUserPage";
import "./pages/applications/ApplicationListPage";
import "./pages/applications/ApplicationViewPage";
import "./pages/crypto/CertificateKeyPairListPage";
@ -40,6 +41,10 @@ export const ROUTES: Route[] = [
new RegExp("^/administration/overview$"),
html`<ak-admin-overview></ak-admin-overview>`,
),
new Route(
new RegExp("^/administration/dashboard/users$"),
html`<ak-admin-dashboard-users></ak-admin-dashboard-users>`,
),
new Route(
new RegExp("^/administration/system-tasks$"),
html`<ak-system-task-list></ak-system-task-list>`,