This repository has been archived on 2024-05-31. You can view files and clone it, but cannot push or open issues or pull requests.
authentik/web/xliff/en.xlf

6401 lines
276 KiB
Plaintext
Raw Normal View History

web: Replace lingui.js with lit-localize (#5761) * \#\# Details web: replace lingui with lit/localize \#\# Changes This rather massive shift replaces the lingui and `t()` syntax with lit-localize, XLIFF, and the `msg()` syntax used by lit-localize. 90% of this work was mechanized; simple perl scripts found and replaced all uses of `t()` with the appropriate corresponding syntax for `msg()` and `msg(str())`. The XLIFF files were auto-generated from the PO files. They have not been audited, and they should be checked over by professional translators. The actual _strings_ have not been changed, but as this was a mechanized change there is always the possibility of mis-translation-- not by the translator, but by the script. * web: revise lit/localize: fix two installation issues. * web: revise localization TL;DR: - Replaced all of Lingui's `t()` syntax with `msg()` syntax. - Mechanically (i.e with a script) converted all of the PO files to XLIFF files - Refactored the localization code to be a bit smarter: - the function `getBestMatchLocale` takes the locale lists and a requested locale, and returns the first match of: - The locale's code exactly matches the requested locale - The locale code exactly matches the prefix of the requested locale (i.e the "en" part of "en-US") - the locale code's prefix exactly matches the prefix of the requested locale This function is passed to lit-locate's `loadLocale()`. - `activateLocale()` just calls `loadLocale()` now. - `autodetectLanguage` searches the following, and picks the first that returns a valid locale object, before passing it to `loadLocale()`: - The User's settings - A `?locale=` component found in `window.location.search` - The `window.navigator.language` field - English The `msg()` only runs when it's run. This seems obvious, but it means that you cannot cache strings at load time; they must be kept inside functions that are re-run so that the `msg()` engine can look up the strings in the preferred language of the user at that moment. You can use thunks-of-strings if you really need them that way. * Including the 'xliff-converter' in case anyone wants to review it. * The xliff-converter is tagged as 'xliff-converter', but has been deleted. \#\# Details - Resolves #5171 \#\# Changes \#\#\# New Features - Adds a "Add an Application" to the LibraryView if there are no applications and the user is an administrator. \#\#\# Breaking Changes - Adds breaking change which causes \<issue\>. \#\# Checklist - [ ] Local tests pass (`ak test authentik/`) - [ ] The code has been formatted (`make lint-fix`) If an API change has been made - [ ] The API schema has been updated (`make gen-build`) If changes to the frontend have been made - [ ] The code has been formatted (`make web`) - [ ] The translation files have been updated (`make i18n-extract`) If applicable - [ ] The documentation has been updated - [ ] The documentation has been formatted (`make website`) * web: fix redundant locales for zh suite. * web: prettier pass for locale update * web: localization moderization Changed the names of the lit-localize commands to make it clear they're part of the localization effort, and not just "build" and "extract". * update transifex config Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix package lock? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use build not compile Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: conversion to lit-localize The CI produced a list of problems that I hadn't caught earlier, due to a typo ("localize build" is correct, "localize compile" is not) I had left in package.json. They were minor and linty, but it was still wise to fix them. * web: replace lingui with lit/locale This commit fixes some minor linting issues that were hidden by a typo in package.json. The issues were not apparently problematic from a Javascript point of view, but they pointed to sloppy thinking in the progression of types through the system, so I cleaned them up and formalized the types from LocaleModule to AkLocale. * web: replace lingui with lit/localize One problem that has repeatedly come up is that localize's templates do not produce JavaScript that conforms with our shop style. I've replaced `build-locale` with a two-step that builds the locale *and* ensures that it conforms to the shop style via `prettier` every time. * web: replace lingui with lit-locale This commit applies the most recent bundle of translations to the new lit-locale aspect component. It also revises the algorithm for *finding* the correct locale, replacing the complex fall-back with some rather straightforward regular expressions. In the case of Chinese, the fallback comes at the end of the selection list, which may not be, er, politically valuable (since Taiwan and Hong Kong come before, being exceptions that need to be tested). If we need a different order for presentation, that'll be a future feature. * web: replace lingui with lit/locale Well, that was embarassing. --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-06-02 15:08:36 +00:00
<?xml version="1.0" encoding="utf-8"?>
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
<file target-language="en" source-language="en" original="lit-localize-inputs" datatype="plaintext">
<body>
<trans-unit id="s4caed5b7a7e5d89b">
<source>English</source>
<target>English</target>
</trans-unit>
<trans-unit id="s75a27f43413e02c5">
<source>French</source>
<target>French</target>
</trans-unit>
<trans-unit id="s9d2d00982edafabb">
<source>Turkish</source>
<target>Turkish</target>
</trans-unit>
<trans-unit id="sf1868dc19e3917bb">
<source>Spanish</source>
<target>Spanish</target>
</trans-unit>
<trans-unit id="s03f49e598ffb11cc">
<source>Polish</source>
<target>Polish</target>
</trans-unit>
<trans-unit id="s4660da32fb311ac0">
<source>Taiwanese Mandarin</source>
<target>Taiwanese Mandarin</target>
</trans-unit>
<trans-unit id="s354e0a9f146d2869">
<source>Chinese (simplified)</source>
<target>Chinese (simplified)</target>
</trans-unit>
<trans-unit id="se3e6af2ce24d80e8">
<source>Chinese (traditional)</source>
<target>Chinese (traditional)</target>
</trans-unit>
<trans-unit id="s63e71d20d1eaca93">
<source>German</source>
<target>German</target>
</trans-unit>
<trans-unit id="s49730f3d5751a433">
<source>Loading...</source>
<target>Loading...</target>
</trans-unit>
<trans-unit id="sf1e9d421f35b51e5">
<source>Application</source>
<target>Application</target>
</trans-unit>
<trans-unit id="s310d8757ce319673">
<source>Logins</source>
<target>Logins</target>
</trans-unit>
<trans-unit id="sa50a6326530d8a0d">
<source>Show less</source>
<target>Show less</target>
</trans-unit>
<trans-unit id="sb2c57b2d347203dd">
<source>Show more</source>
<target>Show more</target>
</trans-unit>
<trans-unit id="s6238f519db67980d">
<source>UID</source>
<target>UID</target>
</trans-unit>
<trans-unit id="sef49aec68fd1dc66">
<source>Name</source>
<target>Name</target>
</trans-unit>
<trans-unit id="sf9f2c719a04066ec">
<source>App</source>
<target>App</target>
</trans-unit>
<trans-unit id="sda796c87fa97ed4d">
<source>Model Name</source>
<target>Model Name</target>
</trans-unit>
<trans-unit id="s79e8cc71a5975b04">
<source>Message</source>
<target>Message</target>
</trans-unit>
<trans-unit id="sbbc53e0e54d7946f">
<source>Subject</source>
<target>Subject</target>
</trans-unit>
<trans-unit id="sa6ab5184d6315895">
<source>From</source>
<target>From</target>
</trans-unit>
<trans-unit id="s09353907b5c79284">
<source>To</source>
<target>To</target>
</trans-unit>
<trans-unit id="s63e03c70f67ebf9c">
<source>Context</source>
<target>Context</target>
</trans-unit>
<trans-unit id="sa48f81f001b893d2">
<source>User</source>
<target>User</target>
</trans-unit>
<trans-unit id="s119498d4e4cf59a6">
<source>Affected model:</source>
<target>Affected model:</target>
</trans-unit>
<trans-unit id="sa3660d505e7011e0">
<source>Authorized application:</source>
<target>Authorized application:</target>
</trans-unit>
<trans-unit id="s95a032ae86881bf5">
<source>Using flow</source>
<target>Using flow</target>
</trans-unit>
<trans-unit id="scb5c9a7cc4ccd68d">
<source>Email info:</source>
<target>Email info:</target>
</trans-unit>
<trans-unit id="s677f1b675fc21bb1">
<source>Secret:</source>
<target>Secret:</target>
</trans-unit>
<trans-unit id="sd947d57c9a9b7108">
<source>Open issue on GitHub...</source>
<target>Open issue on GitHub...</target>
</trans-unit>
<trans-unit id="sa6905be242387f36">
<source>Exception</source>
<target>Exception</target>
</trans-unit>
<trans-unit id="s6ab73c998850c5ab">
<source>Expression</source>
<target>Expression</target>
</trans-unit>
<trans-unit id="s50ebe627b4bc7d02">
<source>Binding</source>
<target>Binding</target>
</trans-unit>
<trans-unit id="s3c6de3f257e0c912">
<source>Request</source>
<target>Request</target>
</trans-unit>
<trans-unit id="s730182ad28374cda">
<source>Object</source>
<target>Object</target>
</trans-unit>
<trans-unit id="s890e983a7be64da4">
<source>Result</source>
<target>Result</target>
</trans-unit>
<trans-unit id="sd3a853f63f45dcb0">
<source>Passing</source>
<target>Passing</target>
</trans-unit>
<trans-unit id="sbdeedc1c60306b35">
<source>Messages</source>
<target>Messages</target>
</trans-unit>
<trans-unit id="s0a5401d4419f9958">
<source>Using source</source>
<target>Using source</target>
</trans-unit>
<trans-unit id="s14622ee6de586485">
<source>Attempted to log in as <x id="0" equiv-text="${this.event.context.username}"/></source>
<target>Attempted to log in as
<x id="0" equiv-text="${this.event.context.username}"/></target>
</trans-unit>
<trans-unit id="sb07bf992e3d00664">
<source>No additional data available.</source>
<target>No additional data available.</target>
</trans-unit>
<trans-unit id="s09810653c832e935">
<source>Click to change value</source>
<target>Click to change value</target>
</trans-unit>
<trans-unit id="sfefce784ec55868f">
<source>Select an object.</source>
<target>Select an object.</target>
</trans-unit>
<trans-unit id="s04ceadb276bbe149">
<source>Loading options...</source>
<target>Loading options...</target>
</trans-unit>
<trans-unit id="sfe629863ba1338c2">
<source>Connection error, reconnecting...</source>
<target>Connection error, reconnecting...</target>
</trans-unit>
<trans-unit id="sc8da3cc71de63832">
<source>Login</source>
<target>Login</target>
</trans-unit>
<trans-unit id="sb4564c127ab8b921">
<source>Failed login</source>
<target>Failed login</target>
</trans-unit>
<trans-unit id="s67749057edb2586b">
<source>Logout</source>
<target>Logout</target>
</trans-unit>
<trans-unit id="s7e537ad68d7c16e1">
<source>User was written to</source>
<target>User was written to</target>
</trans-unit>
<trans-unit id="sa0e0bdd7e244416b">
<source>Suspicious request</source>
<target>Suspicious request</target>
</trans-unit>
<trans-unit id="s7bda44013984fc48">
<source>Password set</source>
<target>Password set</target>
</trans-unit>
<trans-unit id="sa1b41e334ad89d94">
<source>Secret was viewed</source>
<target>Secret was viewed</target>
</trans-unit>
<trans-unit id="s92ca679592a36b35">
<source>Secret was rotated</source>
<target>Secret was rotated</target>
</trans-unit>
<trans-unit id="s8a1d9403ca90989b">
<source>Invitation used</source>
<target>Invitation used</target>
</trans-unit>
<trans-unit id="s5f496533610103f2">
<source>Application authorized</source>
<target>Application authorized</target>
</trans-unit>
<trans-unit id="sdc9e222be9612939">
<source>Source linked</source>
<target>Source linked</target>
</trans-unit>
<trans-unit id="sb1c91762ae3a9bee">
<source>Impersonation started</source>
<target>Impersonation started</target>
</trans-unit>
<trans-unit id="s9c73bd29b279d26b">
<source>Impersonation ended</source>
<target>Impersonation ended</target>
</trans-unit>
<trans-unit id="s1cd264012278c047">
<source>Flow execution</source>
<target>Flow execution</target>
</trans-unit>
<trans-unit id="s32f04d33924ce8ad">
<source>Policy execution</source>
<target>Policy execution</target>
</trans-unit>
<trans-unit id="sb6d7128df5978cee">
<source>Policy exception</source>
<target>Policy exception</target>
</trans-unit>
<trans-unit id="s77f572257f69a8db">
<source>Property Mapping exception</source>
<target>Property Mapping exception</target>
</trans-unit>
<trans-unit id="s2543cffd6ebb6803">
<source>System task execution</source>
<target>System task execution</target>
</trans-unit>
<trans-unit id="se2f258b996f7279c">
<source>System task exception</source>
<target>System task exception</target>
</trans-unit>
<trans-unit id="s81eff3409d572a21">
<source>General system exception</source>
<target>General system exception</target>
</trans-unit>
<trans-unit id="sf8f49cdbf0036343">
<source>Configuration error</source>
<target>Configuration error</target>
</trans-unit>
<trans-unit id="s9c6f61dc47bc4f0a">
<source>Model created</source>
<target>Model created</target>
</trans-unit>
<trans-unit id="s47a4983a2c6bb749">
<source>Model updated</source>
<target>Model updated</target>
</trans-unit>
<trans-unit id="sc9f69360b58706c7">
<source>Model deleted</source>
<target>Model deleted</target>
</trans-unit>
<trans-unit id="sa266303caf1bd27f">
<source>Email sent</source>
<target>Email sent</target>
</trans-unit>
<trans-unit id="s6c410fedda2a575f">
<source>Update available</source>
<target>Update available</target>
</trans-unit>
<trans-unit id="s02240309358f557c">
<source>Unknown severity</source>
<target>Unknown severity</target>
</trans-unit>
<trans-unit id="sf1ec4acb8d744ed9">
<source>Alert</source>
<target>Alert</target>
</trans-unit>
<trans-unit id="s9117fb5195e75151">
<source>Notice</source>
<target>Notice</target>
</trans-unit>
<trans-unit id="s34be76c6b1eadbef">
<source>Warning</source>
<target>Warning</target>
</trans-unit>
<trans-unit id="sf45a0d2f00bcc6ff">
<source>no tabs defined</source>
<target>no tabs defined</target>
</trans-unit>
<trans-unit id="s04c5a637328c9b67">
<source><x id="0" equiv-text="${this.pages?.startIndex}"/> - <x id="1" equiv-text="${this.pages?.endIndex}"/> of <x id="2" equiv-text="${this.pages?.count}"/></source>
<target>
<x id="0" equiv-text="${this.pages?.startIndex}"/>-
<x id="1" equiv-text="${this.pages?.endIndex}"/>of
<x id="2" equiv-text="${this.pages?.count}"/></target>
</trans-unit>
<trans-unit id="s6a89bb10338369b4">
<source>Go to previous page</source>
<target>Go to previous page</target>
</trans-unit>
<trans-unit id="s7edad99c6b7bfe88">
<source>Go to next page</source>
<target>Go to next page</target>
</trans-unit>
<trans-unit id="sffa721bb6aa3128d">
<source>Search...</source>
<target>Search...</target>
</trans-unit>
<trans-unit id="sb59d68ed12d46377">
<source>Loading</source>
<target>Loading</target>
</trans-unit>
<trans-unit id="s7bc8c327f1f7c82c">
<source>No objects found.</source>
<target>No objects found.</target>
</trans-unit>
<trans-unit id="sfd44ce578f643145">
<source>Failed to fetch objects.</source>
<target>Failed to fetch objects.</target>
</trans-unit>
<trans-unit id="s7b7163270e57e8b4">
<source>Refresh</source>
<target>Refresh</target>
</trans-unit>
<trans-unit id="s909e876731a8febb">
<source>Select all rows</source>
<target>Select all rows</target>
</trans-unit>
<trans-unit id="sa442044b586ec8bf">
<source>Action</source>
<target>Action</target>
</trans-unit>
<trans-unit id="s02839b01844d6ca8">
<source>Creation Date</source>
<target>Creation Date</target>
</trans-unit>
<trans-unit id="s4d00f1de1c82281b">
<source>Client IP</source>
<target>Client IP</target>
</trans-unit>
<trans-unit id="s45f9e7ce0897f9e5">
<source>Tenant</source>
<target>Tenant</target>
</trans-unit>
<trans-unit id="s2152f3482784705f">
<source>Recent events</source>
<target>Recent events</target>
</trans-unit>
<trans-unit id="sc35581d9c1cd67ff">
<source>On behalf of <x id="0" equiv-text="${item.user.on_behalf_of.username}"/></source>
<target>On behalf of
<x id="0" equiv-text="${item.user.on_behalf_of.username}"/></target>
</trans-unit>
<trans-unit id="saf63a04c86018698">
<source>-</source>
<target>-</target>
</trans-unit>
<trans-unit id="s1b448a4ea79d4eef">
<source>No Events found.</source>
<target>No Events found.</target>
</trans-unit>
<trans-unit id="s50911ec1c8aee99a">
<source>No matching events could be found.</source>
<target>No matching events could be found.</target>
</trans-unit>
<trans-unit id="s113c05ef9996ca4b">
<source>Embedded outpost is not configured correctly.</source>
<target>Embedded outpost is not configured correctly.</target>
</trans-unit>
<trans-unit id="seb5ba88f21937c98">
<source>Check outposts.</source>
<target>Check outposts.</target>
</trans-unit>
<trans-unit id="sd0bc94e11935ee5a">
<source>HTTPS is not detected correctly</source>
<target>HTTPS is not detected correctly</target>
</trans-unit>
<trans-unit id="s40bf151b56a64f51">
<source>Server and client are further than 5 seconds apart.</source>
<target>Server and client are further than 5 seconds apart.</target>
</trans-unit>
<trans-unit id="s091d3d07b5b3076f">
<source>OK</source>
<target>OK</target>
</trans-unit>
<trans-unit id="sae486938be80729c">
<source>Everything is ok.</source>
<target>Everything is ok.</target>
</trans-unit>
<trans-unit id="sea91c57b3d3969fe">
<source>System status</source>
<target>System status</target>
</trans-unit>
<trans-unit id="scefe482c547fb3f3">
<source>Based on <x id="0" equiv-text="${value.versionCurrent}"/></source>
<target>Based on
<x id="0" equiv-text="${value.versionCurrent}"/></target>
</trans-unit>
<trans-unit id="s68a50b1ee6efee7b">
<source><x id="0" equiv-text="${value.versionLatest}"/> is available!</source>
<target>
<x id="0" equiv-text="${value.versionLatest}"/>is available!</target>
</trans-unit>
<trans-unit id="s713d147e1761d0f0">
<source>Up-to-date!</source>
<target>Up-to-date!</target>
</trans-unit>
<trans-unit id="sf4122b220926be97">
<source>Version</source>
<target>Version</target>
</trans-unit>
<trans-unit id="s0a63a8be0b2b422c">
<source>Workers</source>
<target>Workers</target>
</trans-unit>
<trans-unit id="s341ab68d4130de20">
<source>No workers connected. Background tasks will not run.</source>
<target>No workers connected. Background tasks will not run.</target>
</trans-unit>
<trans-unit id="s2ed8eb02525a920a">
<source><x id="0" equiv-text="${ago}"/> hour(s) ago</source>
<target>
<x id="0" equiv-text="${ago}"/>hour(s) ago</target>
</trans-unit>
<trans-unit id="s1f1c857c0c4250e4">
<source><x id="0" equiv-text="${ago}"/> day(s) ago</source>
<target>
<x id="0" equiv-text="${ago}"/>day(s) ago</target>
</trans-unit>
<trans-unit id="s11bc220e8fa9d797">
<source>Authorizations</source>
<target>Authorizations</target>
</trans-unit>
<trans-unit id="s3ef3c252ada78076">
<source>Failed Logins</source>
<target>Failed Logins</target>
</trans-unit>
<trans-unit id="sc2f1e5dd74c1b7df">
<source>Successful Logins</source>
<target>Successful Logins</target>
</trans-unit>
<trans-unit id="s0382d73823585617">
<source><x id="0" equiv-text="${this.errorMessage}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>
<x id="0" equiv-text="${this.errorMessage}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s2ceb11be2290bb1b">
<source>Cancel</source>
<target>Cancel</target>
</trans-unit>
<trans-unit id="se085f35c8a9203a1">
<source>LDAP Source</source>
<target>LDAP Source</target>
</trans-unit>
<trans-unit id="s477de089b505a6ea">
<source>SCIM Provider</source>
<target>SCIM Provider</target>
</trans-unit>
<trans-unit id="s8a75e83497a183a2">
<source>Healthy</source>
<target>Healthy</target>
</trans-unit>
<trans-unit id="sfeb82261bcf99edd">
<source>Healthy outposts</source>
<target>Healthy outposts</target>
</trans-unit>
<trans-unit id="saae1c70e168b45b4">
<source>Admin</source>
<target>Admin</target>
</trans-unit>
<trans-unit id="s0a11c2ffb8309d1a">
<source>Not found</source>
<target>Not found</target>
</trans-unit>
<trans-unit id="saa0e2675da69651b">
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
<target>The URL "
<x id="0" equiv-text="${this.url}"/>" was not found.</target>
</trans-unit>
<trans-unit id="s58cd9c2fe836d9c6">
<source>Return home</source>
<target>Return home</target>
</trans-unit>
<trans-unit id="s41e035c4bb8d15f2">
<source>General system status</source>
<target>General system status</target>
</trans-unit>
<trans-unit id="s6dfd15978586d05f">
<source>Welcome, <x id="0" equiv-text="${name}"/>.</source>
<target>Welcome,
<x id="0" equiv-text="${name}"/>.</target>
</trans-unit>
<trans-unit id="sc381422c585b867f">
<source>Quick actions</source>
<target>Quick actions</target>
</trans-unit>
<trans-unit id="sfd13ca8ebd857c2e">
<source>Create a new application</source>
<target>Create a new application</target>
</trans-unit>
<trans-unit id="s079d388d3cbfa54f">
<source>Check the logs</source>
<target>Check the logs</target>
</trans-unit>
<trans-unit id="sed8d4c3fd5f60e1f">
<source>Explore integrations</source>
<target>Explore integrations</target>
</trans-unit>
<trans-unit id="sfffb0d0958bfbc42">
<source>Manage users</source>
<target>Manage users</target>
</trans-unit>
<trans-unit id="s8763a33c3d46aaf5">
<source>Outpost status</source>
<target>Outpost status</target>
</trans-unit>
<trans-unit id="scc286303aa9c6cb0">
<source>Sync status</source>
<target>Sync status</target>
</trans-unit>
<trans-unit id="sbdc4a833de9ca502">
<source>Logins and authorizations over the last week (per 8 hours)</source>
<target>Logins and authorizations over the last week (per 8 hours)</target>
</trans-unit>
<trans-unit id="s6e09a19aa3952509">
<source>Apps with most usage</source>
<target>Apps with most usage</target>
</trans-unit>
<trans-unit id="sda5e1499f93146ad">
<source><x id="0" equiv-text="${ago}"/> days ago</source>
<target>
<x id="0" equiv-text="${ago}"/>days ago</target>
</trans-unit>
<trans-unit id="s51ea3a244c781b1f">
<source>Objects created</source>
<target>Objects created</target>
</trans-unit>
<trans-unit id="sfbadb77fbc61efb8">
<source>Users created per day in the last month</source>
<target>Users created per day in the last month</target>
</trans-unit>
<trans-unit id="sb0669da3df95837c">
<source>Logins per day in the last month</source>
<target>Logins per day in the last month</target>
</trans-unit>
<trans-unit id="s835da49b4dc83a51">
<source>Failed Logins per day in the last month</source>
<target>Failed Logins per day in the last month</target>
</trans-unit>
<trans-unit id="s5f4586bc1e2740e6">
<source>Clear search</source>
<target>Clear search</target>
</trans-unit>
<trans-unit id="s3b34d9930e33bd46">
<source>System Tasks</source>
<target>System Tasks</target>
</trans-unit>
<trans-unit id="saaa3abe03c7260f9">
<source>Long-running operations which authentik executes in the background.</source>
<target>Long-running operations which authentik executes in the background.</target>
</trans-unit>
<trans-unit id="s7468e87263dfff7e">
<source>Identifier</source>
<target>Identifier</target>
</trans-unit>
<trans-unit id="s63d894b1ddb06289">
<source>Description</source>
<target>Description</target>
</trans-unit>
<trans-unit id="sa9b2a245441557dc">
<source>Last run</source>
<target>Last run</target>
</trans-unit>
<trans-unit id="sad3e3c8146fc920f">
<source>Status</source>
<target>Status</target>
</trans-unit>
<trans-unit id="s8af61807443f32a4">
<source>Actions</source>
<target>Actions</target>
</trans-unit>
<trans-unit id="sbe9a51f29a4a2c5b">
<source>Successful</source>
<target>Successful</target>
</trans-unit>
<trans-unit id="s5f343a43e7ea9f91">
<source>Error</source>
<target>Error</target>
</trans-unit>
<trans-unit id="sc592307ea80f16b9">
<source>Unknown</source>
<target>Unknown</target>
</trans-unit>
<trans-unit id="s92921878e886e36d">
<source>Duration</source>
<target>Duration</target>
</trans-unit>
<trans-unit id="se7e1ababbc4868b8">
<source><x id="0" equiv-text="${item.taskDuration.toFixed(2)}"/> seconds</source>
<target>
<x id="0" equiv-text="${item.taskDuration.toFixed(2)}"/>seconds</target>
</trans-unit>
<trans-unit id="sc25edca57df81461">
<source>Authentication</source>
<target>Authentication</target>
</trans-unit>
<trans-unit id="s6dfb7283452f78fe">
<source>Authorization</source>
<target>Authorization</target>
</trans-unit>
<trans-unit id="sddcfc6ab24e3a6ed">
<source>Enrollment</source>
<target>Enrollment</target>
</trans-unit>
<trans-unit id="s1fc9c70610c4c67d">
<source>Invalidation</source>
<target>Invalidation</target>
</trans-unit>
<trans-unit id="s6ac670086eb137c6">
<source>Recovery</source>
<target>Recovery</target>
</trans-unit>
<trans-unit id="sdf22dcf939c27cc7">
<source>Stage Configuration</source>
<target>Stage Configuration</target>
</trans-unit>
<trans-unit id="s6d5bce4321f57cda">
<source>Unenrollment</source>
<target>Unenrollment</target>
</trans-unit>
<trans-unit id="sde2bb5418562c5b2">
<source>Unknown designation</source>
<target>Unknown designation</target>
</trans-unit>
<trans-unit id="sb9834316ffd4ae3e">
<source>Stacked</source>
<target>Stacked</target>
</trans-unit>
<trans-unit id="s12146091b2b539a3">
<source>Content left</source>
<target>Content left</target>
</trans-unit>
<trans-unit id="sa800871782eba1ac">
<source>Content right</source>
<target>Content right</target>
</trans-unit>
<trans-unit id="sb4e50ca3cffdbc10">
<source>Sidebar left</source>
<target>Sidebar left</target>
</trans-unit>
<trans-unit id="s745a55f9abf9f2e5">
<source>Sidebar right</source>
<target>Sidebar right</target>
</trans-unit>
<trans-unit id="sb3182a87ded1bc91">
<source>Unknown layout</source>
<target>Unknown layout</target>
</trans-unit>
<trans-unit id="sdfd22a21660f6002">
<source>Successfully updated provider.</source>
<target>Successfully updated provider.</target>
</trans-unit>
<trans-unit id="s457c639088c547c5">
<source>Successfully created provider.</source>
<target>Successfully created provider.</target>
</trans-unit>
<trans-unit id="sff69c1a637f899a6">
<source>Bind flow</source>
<target>Bind flow</target>
</trans-unit>
<trans-unit id="s319040353f479853">
<source>Flow used for users to authenticate.</source>
<target>Flow used for users to authenticate.</target>
</trans-unit>
<trans-unit id="sbc80eab557fbf782">
<source>Search group</source>
<target>Search group</target>
</trans-unit>
<trans-unit id="s04b7f8d6aaef3756">
<source>Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed.</source>
<target>Users in the selected group can do search queries. If no group is selected, no LDAP Searches are allowed.</target>
</trans-unit>
<trans-unit id="se5973e7c8ba0fc71">
<source>Bind mode</source>
<target>Bind mode</target>
</trans-unit>
<trans-unit id="s8915e64b8b999bfe">
<source>Cached binding</source>
<target>Cached binding</target>
</trans-unit>
<trans-unit id="s842d690eb3c11762">
<source>Flow is executed and session is cached in memory. Flow is executed when session expires</source>
<target>Flow is executed and session is cached in memory. Flow is executed when session expires</target>
</trans-unit>
<trans-unit id="s6a66759749bf31ed">
<source>Direct binding</source>
<target>Direct binding</target>
</trans-unit>
<trans-unit id="se0adaf83627104fb">
<source>Always execute the configured bind flow to authenticate the user</source>
<target>Always execute the configured bind flow to authenticate the user</target>
</trans-unit>
<trans-unit id="scef3f4ad80abbd22">
<source>Configure how the outpost authenticates requests.</source>
<target>Configure how the outpost authenticates requests.</target>
</trans-unit>
<trans-unit id="sbcae51a6f06e53d4">
<source>Search mode</source>
<target>Search mode</target>
</trans-unit>
<trans-unit id="s9065fcccd837a679">
<source>Cached querying</source>
<target>Cached querying</target>
</trans-unit>
<trans-unit id="s30d0d0e6c626a234">
<source>The outpost holds all users and groups in-memory and will refresh every 5 Minutes</source>
<target>The outpost holds all users and groups in-memory and will refresh every 5 Minutes</target>
</trans-unit>
<trans-unit id="sffc14b8200a9f938">
<source>Direct querying</source>
<target>Direct querying</target>
</trans-unit>
<trans-unit id="sdce4680288083fe3">
<source>Always returns the latest data, but slower than cached querying</source>
<target>Always returns the latest data, but slower than cached querying</target>
</trans-unit>
<trans-unit id="s8b87df5664de7eb8">
<source>Configure how the outpost queries the core authentik server's users.</source>
<target>Configure how the outpost queries the core authentik server's users.</target>
</trans-unit>
<trans-unit id="sfe388f0313f52da2">
<source>Protocol settings</source>
<target>Protocol settings</target>
</trans-unit>
<trans-unit id="s55d731be1ef66efe">
<source>Base DN</source>
<target>Base DN</target>
</trans-unit>
<trans-unit id="s0b15ff11a0049cfd">
<source>LDAP DN under which bind requests and search requests can be made.</source>
<target>LDAP DN under which bind requests and search requests can be made.</target>
</trans-unit>
<trans-unit id="sb157267c85fdff30">
<source>Certificate</source>
<target>Certificate</target>
</trans-unit>
<trans-unit id="sac43cb9690260b86">
<source>UID start number</source>
<target>UID start number</target>
</trans-unit>
<trans-unit id="s60edbcfac8ed1f90">
<source>The start for uidNumbers, this number is added to the user.Pk to make sure that the numbers aren't too low for POSIX users. Default is 2000 to ensure that we don't collide with local users uidNumber</source>
<target>The start for uidNumbers, this number is added to the user.Pk to make sure that the numbers aren't too low for POSIX users. Default is 2000 to ensure that we don't collide with local users uidNumber</target>
</trans-unit>
<trans-unit id="s5acb607b40356974">
<source>GID start number</source>
<target>GID start number</target>
</trans-unit>
<trans-unit id="s1c8e9816dcae6d9c">
<source>The start for gidNumbers, this number is added to a number generated from the group.Pk to make sure that the numbers aren't too low for POSIX groups. Default is 4000 to ensure that we don't collide with local groups or users primary groups gidNumber</source>
<target>The start for gidNumbers, this number is added to a number generated from the group.Pk to make sure that the numbers aren't too low for POSIX groups. Default is 4000 to ensure that we don't collide with local groups or users primary groups gidNumber</target>
</trans-unit>
<trans-unit id="s2236dc563c2dbf76">
<source>(Format: hours=-1;minutes=-2;seconds=-3).</source>
<target>(Format: hours=-1;minutes=-2;seconds=-3).</target>
</trans-unit>
<trans-unit id="sbec40ef4e6f139b7">
<source>(Format: hours=1;minutes=2;seconds=3).</source>
<target>(Format: hours=1;minutes=2;seconds=3).</target>
</trans-unit>
<trans-unit id="sbb8ad22c83d375b1">
<source>The following keywords are supported:</source>
<target>The following keywords are supported:</target>
</trans-unit>
<trans-unit id="sbb3243352661428f">
<source>Authentication flow</source>
<target>Authentication flow</target>
</trans-unit>
<trans-unit id="sa72a3bd1e7e89926">
<source>Flow used when a user access this provider and is not authenticated.</source>
<target>Flow used when a user access this provider and is not authenticated.</target>
</trans-unit>
<trans-unit id="s62f7c59b0606a8d6">
<source>Authorization flow</source>
<target>Authorization flow</target>
</trans-unit>
<trans-unit id="sfbaeb0de54fbfdbb">
<source>Flow used when authorizing this provider.</source>
<target>Flow used when authorizing this provider.</target>
</trans-unit>
<trans-unit id="sc8de93a7dc0d78ba">
<source>Client type</source>
<target>Client type</target>
</trans-unit>
<trans-unit id="s399cc2d67d92e957">
<source>Confidential</source>
<target>Confidential</target>
</trans-unit>
<trans-unit id="s95f09b229a0a0bb0">
<source>Confidential clients are capable of maintaining the confidentiality of their credentials such as client secrets</source>
<target>Confidential clients are capable of maintaining the confidentiality of their credentials such as client secrets</target>
</trans-unit>
<trans-unit id="sdd1ff479d04ac140">
<source>Public</source>
<target>Public</target>
</trans-unit>
<trans-unit id="s51c6b8403c2dc5d9">
<source>Public clients are incapable of maintaining the confidentiality and should use methods like PKCE. </source>
<target>Public clients are incapable of maintaining the confidentiality and should use methods like PKCE.</target>
</trans-unit>
<trans-unit id="s4d00e5de1c8213b7">
<source>Client ID</source>
<target>Client ID</target>
</trans-unit>
<trans-unit id="s03fb3fa232f0434a">
<source>Client Secret</source>
<target>Client Secret</target>
</trans-unit>
<trans-unit id="sde0ad51b14f77cf6">
<source>Redirect URIs/Origins (RegEx)</source>
<target>Redirect URIs/Origins (RegEx)</target>
</trans-unit>
<trans-unit id="s7f9eb9c8bd26e8fd">
<source>Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows.</source>
<target>Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows.</target>
</trans-unit>
<trans-unit id="s2a369bc2febb5d55">
<source>If no explicit redirect URIs are specified, the first successfully used redirect URI will be saved.</source>
<target>If no explicit redirect URIs are specified, the first successfully used redirect URI will be saved.</target>
</trans-unit>
<trans-unit id="sa8384c9c26731f83">
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
<target>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</target>
</trans-unit>
<trans-unit id="s55787f4dfcdce52b">
<source>Signing Key</source>
<target>Signing Key</target>
</trans-unit>
<trans-unit id="sc6c57419ad3a01a8">
<source>Key used to sign the tokens.</source>
<target>Key used to sign the tokens.</target>
</trans-unit>
<trans-unit id="s124f93a61ee772d6">
<source>Advanced protocol settings</source>
<target>Advanced protocol settings</target>
</trans-unit>
<trans-unit id="s926e0ecf124fb01a">
<source>Access code validity</source>
<target>Access code validity</target>
</trans-unit>
<trans-unit id="sa578033f134a83b6">
<source>Configure how long access codes are valid for.</source>
<target>Configure how long access codes are valid for.</target>
</trans-unit>
<trans-unit id="sbea3db12fd799210">
<source>Access Token validity</source>
<target>Access Token validity</target>
</trans-unit>
<trans-unit id="s72559845d38bf688">
<source>Configure how long access tokens are valid for.</source>
<target>Configure how long access tokens are valid for.</target>
</trans-unit>
<trans-unit id="s821f6014c1a435b9">
<source>Refresh Token validity</source>
<target>Refresh Token validity</target>
</trans-unit>
<trans-unit id="s00c2db16ea9bc263">
<source>Configure how long refresh tokens are valid for.</source>
<target>Configure how long refresh tokens are valid for.</target>
</trans-unit>
<trans-unit id="s2e3ef41a0edd8608">
<source>Scopes</source>
<target>Scopes</target>
</trans-unit>
<trans-unit id="s3a3fae99373ce56b">
<source>Select which scopes can be used by the client. The client still has to specify the scope to access the data.</source>
<target>Select which scopes can be used by the client. The client still has to specify the scope to access the data.</target>
</trans-unit>
<trans-unit id="sffd2e553143d1b0e">
<source>Hold control/command to select multiple items.</source>
<target>Hold control/command to select multiple items.</target>
</trans-unit>
<trans-unit id="s26bf2730430efbea">
<source>Subject mode</source>
<target>Subject mode</target>
</trans-unit>
<trans-unit id="sccc47f82044453f9">
<source>Based on the User's hashed ID</source>
<target>Based on the User's hashed ID</target>
</trans-unit>
<trans-unit id="sbd5be4fb7442a34c">
<source>Based on the User's ID</source>
<target>Based on the User's ID</target>
</trans-unit>
<trans-unit id="sc9cf9ecaf9e5d67e">
<source>Based on the User's UUID</source>
<target>Based on the User's UUID</target>
</trans-unit>
<trans-unit id="s4291727352c4f295">
<source>Based on the User's username</source>
<target>Based on the User's username</target>
</trans-unit>
<trans-unit id="sd62cfc27ad4aa33b">
<source>Based on the User's Email</source>
<target>Based on the User's Email</target>
</trans-unit>
<trans-unit id="s55eb75bedf96be0f">
<source>This is recommended over the UPN mode.</source>
<target>This is recommended over the UPN mode.</target>
</trans-unit>
<trans-unit id="sf80e9547166117e6">
<source>Based on the User's UPN</source>
<target>Based on the User's UPN</target>
</trans-unit>
<trans-unit id="sde949d0ef44572eb">
<source>Requires the user to have a 'upn' attribute set, and falls back to hashed user ID. Use this mode only if you have different UPN and Mail domains.</source>
<target>Requires the user to have a 'upn' attribute set, and falls back to hashed user ID. Use this mode only if you have different UPN and Mail domains.</target>
</trans-unit>
<trans-unit id="s9f23ed1799b4d49a">
<source>Configure what data should be used as unique User Identifier. For most cases, the default should be fine.</source>
<target>Configure what data should be used as unique User Identifier. For most cases, the default should be fine.</target>
</trans-unit>
<trans-unit id="s17d1e337f6c11c1e">
<source>Include claims in id_token</source>
<target>Include claims in id_token</target>
</trans-unit>
<trans-unit id="sbf41e0db12834133">
<source>Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint.</source>
<target>Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint.</target>
</trans-unit>
<trans-unit id="s850a58c683682809">
<source>Issuer mode</source>
<target>Issuer mode</target>
</trans-unit>
<trans-unit id="sde56783222b527d6">
<source>Each provider has a different issuer, based on the application slug</source>
<target>Each provider has a different issuer, based on the application slug</target>
</trans-unit>
<trans-unit id="s8d32d7b9e8ca60b1">
<source>Same identifier is used for all providers</source>
<target>Same identifier is used for all providers</target>
</trans-unit>
<trans-unit id="s37d9155b9f4cc7bd">
<source>Configure how the issuer field of the ID Token should be filled.</source>
<target>Configure how the issuer field of the ID Token should be filled.</target>
</trans-unit>
<trans-unit id="se2adaf0371ffcd65">
<source>Machine-to-Machine authentication settings</source>
<target>Machine-to-Machine authentication settings</target>
</trans-unit>
<trans-unit id="s33318837e6c54a9b">
<source>Trusted OIDC Sources</source>
<target>Trusted OIDC Sources</target>
</trans-unit>
<trans-unit id="s22e566052f7bec81">
<source>JWTs signed by certificates configured in the selected sources can be used to authenticate to this provider.</source>
<target>JWTs signed by certificates configured in the selected sources can be used to authenticate to this provider.</target>
</trans-unit>
<trans-unit id="s072c6d12d3d37501">
<source>HTTP-Basic Username Key</source>
<target>HTTP-Basic Username Key</target>
</trans-unit>
<trans-unit id="sb2bb6f93773a4594">
<source>User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used.</source>
<target>User/Group Attribute used for the user part of the HTTP-Basic Header. If not set, the user's Email address is used.</target>
</trans-unit>
<trans-unit id="s70f6471de355b98c">
<source>HTTP-Basic Password Key</source>
<target>HTTP-Basic Password Key</target>
</trans-unit>
<trans-unit id="sf4de1644dcdb53d5">
<source>User/Group Attribute used for the password part of the HTTP-Basic Header.</source>
<target>User/Group Attribute used for the password part of the HTTP-Basic Header.</target>
</trans-unit>
<trans-unit id="sb8dd788adf7b907b">
<source>Proxy</source>
<target>Proxy</target>
</trans-unit>
<trans-unit id="s7489f76224f8120d">
<source>Forward auth (single application)</source>
<target>Forward auth (single application)</target>
</trans-unit>
<trans-unit id="s25d0cd75377daf75">
<source>Forward auth (domain level)</source>
<target>Forward auth (domain level)</target>
</trans-unit>
<trans-unit id="s93574c03953f25dd">
<source>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.</source>
<target>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.</target>
</trans-unit>
<trans-unit id="sa29b5680cfafacc8">
<source>External host</source>
<target>External host</target>
</trans-unit>
<trans-unit id="s764bccb30868bf62">
<source>The external URL you'll access the application at. Include any non-standard port.</source>
<target>The external URL you'll access the application at. Include any non-standard port.</target>
</trans-unit>
<trans-unit id="scb317851cbcc6b12">
<source>Internal host</source>
<target>Internal host</target>
</trans-unit>
<trans-unit id="sf05e384059a0a7c1">
<source>Upstream host that the requests are forwarded to.</source>
<target>Upstream host that the requests are forwarded to.</target>
</trans-unit>
<trans-unit id="s3d34068a31cab30b">
<source>Internal host SSL Validation</source>
<target>Internal host SSL Validation</target>
</trans-unit>
<trans-unit id="s4a26798e1c3c37dd">
<source>Validate SSL Certificates of upstream servers.</source>
<target>Validate SSL Certificates of upstream servers.</target>
</trans-unit>
<trans-unit id="s44c90273f08fb718">
<source>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.</source>
<target>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.</target>
</trans-unit>
<trans-unit id="sf55d28d4dff0e41b">
<source>An example setup can look like this:</source>
<target>An example setup can look like this:</target>
</trans-unit>
<trans-unit id="sb4a1d1c19438e929">
<source>authentik running on auth.example.com</source>
<target>authentik running on auth.example.com</target>
</trans-unit>
<trans-unit id="s68f935c9ca792016">
<source>app1 running on app1.example.com</source>
<target>app1 running on app1.example.com</target>
</trans-unit>
<trans-unit id="sf813a72d8fadd765">
<source>In this case, you'd set the Authentication URL to auth.example.com and Cookie domain to example.com.</source>
<target>In this case, you'd set the Authentication URL to auth.example.com and Cookie domain to example.com.</target>
</trans-unit>
<trans-unit id="s31d15c6f16951464">
<source>Authentication URL</source>
<target>Authentication URL</target>
</trans-unit>
<trans-unit id="sa03fe48e892df2d8">
<source>The external URL you'll authenticate at. The authentik core server should be reachable under this URL.</source>
<target>The external URL you'll authenticate at. The authentik core server should be reachable under this URL.</target>
</trans-unit>
<trans-unit id="s7def067ed3ad3ad9">
<source>Cookie domain</source>
<target>Cookie domain</target>
</trans-unit>
<trans-unit id="s211b75e868072162">
<source>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'.</source>
<target>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'.</target>
</trans-unit>
<trans-unit id="s2345170f7e272668">
<source>Unknown proxy mode</source>
<target>Unknown proxy mode</target>
</trans-unit>
<trans-unit id="s7c10976de6411844">
<source>Token validity</source>
<target>Token validity</target>
</trans-unit>
<trans-unit id="s3e87ce98ba3c4d80">
<source>Configure how long tokens are valid for.</source>
<target>Configure how long tokens are valid for.</target>
</trans-unit>
<trans-unit id="sd539548ca4c71619">
<source>Additional scopes</source>
<target>Additional scopes</target>
</trans-unit>
<trans-unit id="s8f12575f694e85a2">
<source>Additional scope mappings, which are passed to the proxy.</source>
<target>Additional scope mappings, which are passed to the proxy.</target>
</trans-unit>
<trans-unit id="s93cea6ca1f93349d">
<source>Unauthenticated URLs</source>
<target>Unauthenticated URLs</target>
</trans-unit>
<trans-unit id="sc4508175bf6b09dd">
<source>Unauthenticated Paths</source>
<target>Unauthenticated Paths</target>
</trans-unit>
<trans-unit id="sc9fc206433f67588">
<source>Regular expressions for which authentication is not required. Each new line is interpreted as a new expression.</source>
<target>Regular expressions for which authentication is not required. Each new line is interpreted as a new expression.</target>
</trans-unit>
<trans-unit id="sd503fabef9691134">
<source>When using proxy or forward auth (single application) mode, the requested URL Path is checked against the regular expressions. When using forward auth (domain mode), the full requested URL including scheme and host is matched against the regular expressions.</source>
<target>When using proxy or forward auth (single application) mode, the requested URL Path is checked against the regular expressions. When using forward auth (domain mode), the full requested URL including scheme and host is matched against the regular expressions.</target>
</trans-unit>
<trans-unit id="sb488dee0be434f7e">
<source>Authentication settings</source>
<target>Authentication settings</target>
</trans-unit>
<trans-unit id="s23cee624c735f266">
<source>Intercept header authentication</source>
<target>Intercept header authentication</target>
</trans-unit>
<trans-unit id="sc007cca5af67eae0">
<source>When enabled, authentik will intercept the Authorization header to authenticate the request.</source>
<target>When enabled, authentik will intercept the Authorization header to authenticate the request.</target>
</trans-unit>
<trans-unit id="s36e630ba56617556">
<source>Send HTTP-Basic Authentication</source>
<target>Send HTTP-Basic Authentication</target>
</trans-unit>
<trans-unit id="s9d5796a4b9b7560e">
<source>Send a custom HTTP-Basic Authentication header based on values from authentik.</source>
<target>Send a custom HTTP-Basic Authentication header based on values from authentik.</target>
</trans-unit>
<trans-unit id="s11204eeb1e27ea8f">
<source>ACS URL</source>
<target>ACS URL</target>
</trans-unit>
<trans-unit id="sb7a30abc1dcf6c36">
<source>Issuer</source>
<target>Issuer</target>
</trans-unit>
<trans-unit id="sf54c562d8a10ce77">
<source>Also known as EntityID.</source>
<target>Also known as EntityID.</target>
</trans-unit>
<trans-unit id="s991b750e2d5c4234">
<source>Service Provider Binding</source>
<target>Service Provider Binding</target>
</trans-unit>
<trans-unit id="sd8f220c999726151">
<source>Redirect</source>
<target>Redirect</target>
</trans-unit>
<trans-unit id="sb357ea19a722d827">
<source>Post</source>
<target>Post</target>
</trans-unit>
<trans-unit id="s4e28e2899e08a5f8">
<source>Determines how authentik sends the response back to the Service Provider.</source>
<target>Determines how authentik sends the response back to the Service Provider.</target>
</trans-unit>
<trans-unit id="sd5a4b41c6c883b03">
<source>Audience</source>
<target>Audience</target>
</trans-unit>
<trans-unit id="sc741d9ebe07ad103">
<source>Signing Certificate</source>
<target>Signing Certificate</target>
</trans-unit>
<trans-unit id="sd6c3ddb62de0e8f7">
<source>Certificate used to sign outgoing Responses going to the Service Provider.</source>
<target>Certificate used to sign outgoing Responses going to the Service Provider.</target>
</trans-unit>
<trans-unit id="s5be3b0567172e415">
<source>Verification Certificate</source>
<target>Verification Certificate</target>
</trans-unit>
<trans-unit id="s7c27e113f90a89e0">
<source>When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.</source>
<target>When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default.</target>
</trans-unit>
<trans-unit id="se6d950402810c34f">
<source>Property mappings</source>
<target>Property mappings</target>
</trans-unit>
<trans-unit id="s1a2797874b7fe852">
<source>NameID Property Mapping</source>
<target>NameID Property Mapping</target>
</trans-unit>
<trans-unit id="s256b8452664ccae4">
<source>Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected.</source>
<target>Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected.</target>
</trans-unit>
<trans-unit id="s9f91cc8bcfabb40f">
<source>Assertion valid not before</source>
<target>Assertion valid not before</target>
</trans-unit>
<trans-unit id="s733f83ff9d50da30">
<source>Configure the maximum allowed time drift for an assertion.</source>
<target>Configure the maximum allowed time drift for an assertion.</target>
</trans-unit>
<trans-unit id="s2af5754090898640">
<source>Assertion valid not on or after</source>
<target>Assertion valid not on or after</target>
</trans-unit>
<trans-unit id="s43c1f927936f0a02">
<source>Assertion not valid on or after current time + this value.</source>
<target>Assertion not valid on or after current time + this value.</target>
</trans-unit>
<trans-unit id="sad8550b8731518d8">
<source>Session valid not on or after</source>
<target>Session valid not on or after</target>
</trans-unit>
<trans-unit id="s0dd00fbaba08748a">
<source>Session not valid on or after current time + this value.</source>
<target>Session not valid on or after current time + this value.</target>
</trans-unit>
<trans-unit id="s2a0f60e74b478804">
<source>Digest algorithm</source>
<target>Digest algorithm</target>
</trans-unit>
<trans-unit id="s693d975d38ff0214">
<source>Signature algorithm</source>
<target>Signature algorithm</target>
</trans-unit>
<trans-unit id="sd1a5560fde6f2271">
<source>Successfully imported provider.</source>
<target>Successfully imported provider.</target>
</trans-unit>
<trans-unit id="s252a52330d32b900">
<source>Metadata</source>
<target>Metadata</target>
</trans-unit>
<trans-unit id="s7181a5504472e856">
<source>Apply changes</source>
<target>Apply changes</target>
</trans-unit>
<trans-unit id="s5e8250fb85d64c23">
<source>Close</source>
<target>Close</target>
</trans-unit>
<trans-unit id="sad59707375956ad2">
<source>Finish</source>
<target>Finish</target>
</trans-unit>
<trans-unit id="sc16e00a7a8b2fde2">
<source>Back</source>
<target>Back</target>
</trans-unit>
<trans-unit id="sd5903cc8de68b3fc">
<source>No form found</source>
<target>No form found</target>
</trans-unit>
<trans-unit id="s45935843b1b5b496">
<source>Form didn't return a promise for submitting</source>
<target>Form didn't return a promise for submitting</target>
</trans-unit>
<trans-unit id="s74475586afc1fb0f">
<source>Select type</source>
<target>Select type</target>
</trans-unit>
<trans-unit id="s0b3bf19b31dd6bac">
<source>Try the new application wizard</source>
<target>Try the new application wizard</target>
</trans-unit>
<trans-unit id="sa18e1c6e0e6f16cc">
<source>The new application wizard greatly simplifies the steps required to create applications and providers.</source>
<target>The new application wizard greatly simplifies the steps required to create applications and providers.</target>
</trans-unit>
<trans-unit id="s01ef54f5d7c6ed47">
<source>Try it now</source>
<target>Try it now</target>
</trans-unit>
<trans-unit id="s382a2aa3984474dd">
<source>Create</source>
<target>Create</target>
</trans-unit>
<trans-unit id="s58d1eb482059da12">
<source>New provider</source>
<target>New provider</target>
</trans-unit>
<trans-unit id="sa661ea7d7a50f2e9">
<source>Create a new provider.</source>
<target>Create a new provider.</target>
</trans-unit>
<trans-unit id="s5d6af4c100ad321b">
<source>Create <x id="0" equiv-text="${type.name}"/></source>
<target>Create
<x id="0" equiv-text="${type.name}"/></target>
</trans-unit>
<trans-unit id="sb95baab425322600">
<source>Shared secret</source>
<target>Shared secret</target>
</trans-unit>
<trans-unit id="s9e9316a6b0c16231">
<source>Client Networks</source>
<target>Client Networks</target>
</trans-unit>
<trans-unit id="s7f2dcf01f7a8c0b7">
<source>List of CIDRs (comma-seperated) that clients can connect from. A more specific
CIDR will match before a looser one. Clients connecting from a non-specified CIDR
will be dropped.</source>
</trans-unit>
<trans-unit id="s61eacb19db252f5e">
<source>URL</source>
<target>URL</target>
</trans-unit>
<trans-unit id="sb21f33b039c86322">
<source>SCIM base url, usually ends in /v2.</source>
<target>SCIM base url, usually ends in /v2.</target>
</trans-unit>
<trans-unit id="se68398e3c2c760b2">
<source>Token</source>
<target>Token</target>
</trans-unit>
<trans-unit id="s33ed903c210a6209">
<source>Token to authenticate with. Currently only bearer authentication is supported.</source>
<target>Token to authenticate with. Currently only bearer authentication is supported.</target>
</trans-unit>
<trans-unit id="sfc8bb104e2c05af8">
<source>User filtering</source>
<target>User filtering</target>
</trans-unit>
<trans-unit id="sc0d0890fbd46ef62">
<source>Exclude service accounts</source>
<target>Exclude service accounts</target>
</trans-unit>
<trans-unit id="s98b1cb8fb62909ec">
<source>Group</source>
<target>Group</target>
</trans-unit>
<trans-unit id="s23ab136ad85f0ad2">
<source>Only sync users within the selected group.</source>
<target>Only sync users within the selected group.</target>
</trans-unit>
<trans-unit id="sfdedc3b0b2b7ce3d">
<source>Attribute mapping</source>
<target>Attribute mapping</target>
</trans-unit>
<trans-unit id="saf794c74c9ea731e">
<source>User Property Mappings</source>
<target>User Property Mappings</target>
</trans-unit>
<trans-unit id="s019555b5a442aa00">
<source>Property mappings used to user mapping.</source>
<target>Property mappings used to user mapping.</target>
</trans-unit>
<trans-unit id="s7cb9aa9ee1783f00">
<source>Group Property Mappings</source>
<target>Group Property Mappings</target>
</trans-unit>
<trans-unit id="sa319e3bf44c85963">
<source>Property mappings used to group creation.</source>
<target>Property mappings used to group creation.</target>
</trans-unit>
<trans-unit id="se09ab93d69f7f45b">
<source>Not used by any other object.</source>
<target>Not used by any other object.</target>
</trans-unit>
<trans-unit id="s10922bd0ac765562">
<source>object will be DELETED</source>
<target>object will be DELETED</target>
</trans-unit>
<trans-unit id="sf3981f36525b0dbd">
<source>connection will be deleted</source>
<target>connection will be deleted</target>
</trans-unit>
<trans-unit id="s93cf77a59db53395">
<source>reference will be reset to default value</source>
<target>reference will be reset to default value</target>
</trans-unit>
<trans-unit id="s3e211d29fa10f843">
<source>reference will be set to an empty value</source>
<target>reference will be set to an empty value</target>
</trans-unit>
<trans-unit id="s55fa598b754cc3cc">
<source><x id="0" equiv-text="${ub.name}"/> (<x id="1" equiv-text="${consequence}"/>)</source>
<target>
<x id="0" equiv-text="${ub.name}"/>(
<x id="1" equiv-text="${consequence}"/>)</target>
</trans-unit>
<trans-unit id="s09240e07b5b8d640">
<source>ID</source>
<target>ID</target>
</trans-unit>
<trans-unit id="se33b158a1ec02a09">
<source>Successfully deleted <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/></source>
</trans-unit>
<trans-unit id="sf6eb148db23d19de">
<source>Failed to delete <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Failed to delete
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="s039b6434e8a75560">
<source>Delete <x id="0" equiv-text="${this.objectLabel}"/></source>
<target>Delete
<x id="0" equiv-text="${this.objectLabel}"/></target>
</trans-unit>
<trans-unit id="s5819a49638f6d7cb">
<source>Are you sure you want to delete <x id="0" equiv-text="${this.objects.length} ${this.objectLabel}"/>?</source>
</trans-unit>
<trans-unit id="sdc673e73b5c13aea">
<source>Delete</source>
<target>Delete</target>
</trans-unit>
<trans-unit id="sb0b86b8ca6ab13bd">
<source>Providers</source>
<target>Providers</target>
</trans-unit>
<trans-unit id="s3ffa320128991a45">
<source>Provide support for protocols like SAML and OAuth to assigned applications.</source>
<target>Provide support for protocols like SAML and OAuth to assigned applications.</target>
</trans-unit>
<trans-unit id="sd2223afb7d6b100d">
<source>Type</source>
<target>Type</target>
</trans-unit>
<trans-unit id="s10929ca568ae10bc">
<source>Provider(s)</source>
<target>Provider(s)</target>
</trans-unit>
<trans-unit id="sb2b3b281954752c4">
<source>Assigned to application </source>
<target>Assigned to application</target>
</trans-unit>
<trans-unit id="sa6c0ba4910c7ad7f">
<source>Assigned to application (backchannel) </source>
<target>Assigned to application (backchannel)</target>
</trans-unit>
<trans-unit id="s97f5e0c138eae172">
<source>Warning: Provider not assigned to any application.</source>
<target>Warning: Provider not assigned to any application.</target>
</trans-unit>
<trans-unit id="s8b0432eecbd8b034">
<source>Update</source>
<target>Update</target>
</trans-unit>
<trans-unit id="sc9175cb129fdc306">
<source>Update <x id="0" equiv-text="${item.verboseName}"/></source>
<target>Update
<x id="0" equiv-text="${item.verboseName}"/></target>
</trans-unit>
<trans-unit id="s398f6ba74ba8943a">
<source>Select providers to add to application</source>
<target>Select providers to add to application</target>
</trans-unit>
<trans-unit id="sf9aee319a006c9b4">
<source>Add</source>
<target>Add</target>
</trans-unit>
<trans-unit id="sa90b7809586c35ce">
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
<target>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</target>
</trans-unit>
<trans-unit id="s0410779cb47de312">
<source>Path template for users created. Use placeholders like `%(slug)s` to insert the source slug.</source>
<target>Path template for users created. Use placeholders like `%(slug)s` to insert the source slug.</target>
</trans-unit>
<trans-unit id="s58fd2aafa4261c55">
<source>Successfully updated application.</source>
<target>Successfully updated application.</target>
</trans-unit>
<trans-unit id="s9222ca30ae7786e4">
<source>Successfully created application.</source>
<target>Successfully created application.</target>
</trans-unit>
<trans-unit id="s03907d7a66c6164e">
<source>Application's display Name.</source>
<target>Application's display Name.</target>
</trans-unit>
<trans-unit id="s91f70424f5d5d23e">
<source>Slug</source>
<target>Slug</target>
</trans-unit>
<trans-unit id="sdae55084f6cb2662">
<source>Optionally enter a group name. Applications with identical groups are shown grouped together.</source>
<target>Optionally enter a group name. Applications with identical groups are shown grouped together.</target>
</trans-unit>
<trans-unit id="s7f5869b3d14d7cbc">
<source>Provider</source>
<target>Provider</target>
</trans-unit>
<trans-unit id="s350a616ff5e145ec">
<source>Select a provider that this application should use.</source>
<target>Select a provider that this application should use.</target>
</trans-unit>
<trans-unit id="s4c6534a118f52fdd">
<source>Select backchannel providers which augment the functionality of the main provider.</source>
<target>Select backchannel providers which augment the functionality of the main provider.</target>
</trans-unit>
<trans-unit id="s0639662111324466">
<source>Policy engine mode</source>
<target>Policy engine mode</target>
</trans-unit>
<trans-unit id="s1a0e95458b44d7f8">
<source>Any policy must match to grant access</source>
<target>Any policy must match to grant access</target>
</trans-unit>
<trans-unit id="s7fc1ace65486dc25">
<source>All policies must match to grant access</source>
<target>All policies must match to grant access</target>
</trans-unit>
<trans-unit id="s8be4abc7ca71da6c">
<source>UI settings</source>
<target>UI settings</target>
</trans-unit>
<trans-unit id="s427f788ff333f45b">
<source>Launch URL</source>
<target>Launch URL</target>
</trans-unit>
<trans-unit id="s992f8d1a776e763c">
<source>If left empty, authentik will try to extract the launch URL based on the selected provider.</source>
<target>If left empty, authentik will try to extract the launch URL based on the selected provider.</target>
</trans-unit>
<trans-unit id="s2348f46ebf436671">
<source>Open in new tab</source>
<target>Open in new tab</target>
</trans-unit>
<trans-unit id="s8655c52824caac63">
<source>If checked, the launch URL will open in a new browser tab or window from the user's application library.</source>
<target>If checked, the launch URL will open in a new browser tab or window from the user's application library.</target>
</trans-unit>
<trans-unit id="s068d4dd16d9106d0">
<source>Icon</source>
<target>Icon</target>
</trans-unit>
<trans-unit id="s67e20cd8018d7e3c">
<source>Currently set to:</source>
<target>Currently set to:</target>
</trans-unit>
<trans-unit id="s80e6d6fe5ad458d3">
<source>Clear icon</source>
<target>Clear icon</target>
</trans-unit>
<trans-unit id="s6d3b4d0561ba1cff">
<source>Publisher</source>
<target>Publisher</target>
</trans-unit>
<trans-unit id="sa8c45b6b92a8ba1f">
<source>Create Application</source>
<target>Create Application</target>
</trans-unit>
<trans-unit id="s3d197283cb019b5a">
<source>Overview</source>
<target>Overview</target>
</trans-unit>
<trans-unit id="s6c3daaac4eed12f9">
<source>Changelog</source>
<target>Changelog</target>
</trans-unit>
<trans-unit id="s05e395ff60af047b">
<source>Warning: Provider is not used by any Outpost.</source>
<target>Warning: Provider is not used by any Outpost.</target>
</trans-unit>
<trans-unit id="sccbfc4dec0c8d80c">
<source>Assigned to application</source>
<target>Assigned to application</target>
</trans-unit>
<trans-unit id="s2d46e3a9ee8e0e7e">
<source>Update LDAP Provider</source>
<target>Update LDAP Provider</target>
</trans-unit>
<trans-unit id="s64ef2a6c2dd1d3d1">
<source>Edit</source>
<target>Edit</target>
</trans-unit>
<trans-unit id="saf24e253b3b006d4">
<source>How to connect</source>
<target>How to connect</target>
</trans-unit>
<trans-unit id="s02b3fade1795d03f">
<source>Connect to the LDAP Server on port 389:</source>
<target>Connect to the LDAP Server on port 389:</target>
</trans-unit>
<trans-unit id="sa00cf67b54c44c71">
<source>Check the IP of the Kubernetes service, or</source>
<target>Check the IP of the Kubernetes service, or</target>
</trans-unit>
<trans-unit id="s28f270859c5f4d51">
<source>The Host IP of the docker host</source>
<target>The Host IP of the docker host</target>
</trans-unit>
<trans-unit id="sb7794c2910b1a9ec">
<source>Bind DN</source>
<target>Bind DN</target>
</trans-unit>
<trans-unit id="s5694f9421c428227">
<source>Bind Password</source>
<target>Bind Password</target>
</trans-unit>
<trans-unit id="s086e1bbe7c97ea16">
<source>Search base</source>
<target>Search base</target>
</trans-unit>
<trans-unit id="s417b90913e05bc17">
<source>Preview</source>
<target>Preview</target>
</trans-unit>
<trans-unit id="s17f3eaf3b07ece26">
<source>Warning: Provider is not used by an Application.</source>
<target>Warning: Provider is not used by an Application.</target>
</trans-unit>
<trans-unit id="s56806e9f63efa298">
<source>Redirect URIs</source>
<target>Redirect URIs</target>
</trans-unit>
<trans-unit id="sdbc08adee233f180">
<source>Update OAuth2 Provider</source>
<target>Update OAuth2 Provider</target>
</trans-unit>
<trans-unit id="s9d96eb5ca93e6473">
<source>OpenID Configuration URL</source>
<target>OpenID Configuration URL</target>
</trans-unit>
<trans-unit id="s74f809a69e030351">
<source>OpenID Configuration Issuer</source>
<target>OpenID Configuration Issuer</target>
</trans-unit>
<trans-unit id="s028be8989873f001">
<source>Authorize URL</source>
<target>Authorize URL</target>
</trans-unit>
<trans-unit id="sebda1d54a3f9f967">
<source>Token URL</source>
<target>Token URL</target>
</trans-unit>
<trans-unit id="s2fc3eb68c7ced3af">
<source>Userinfo URL</source>
<target>Userinfo URL</target>
</trans-unit>
<trans-unit id="s145483489b87a622">
<source>Logout URL</source>
<target>Logout URL</target>
</trans-unit>
<trans-unit id="s59f5eda30a904b75">
<source>JWKS URL</source>
<target>JWKS URL</target>
</trans-unit>
<trans-unit id="s453b0c150a7ca58e">
<source>Example JWT payload (for currently authenticated user)</source>
<target>Example JWT payload (for currently authenticated user)</target>
</trans-unit>
<trans-unit id="sc6e8a34361c7c272">
<source>Forward auth (domain-level)</source>
<target>Forward auth (domain-level)</target>
</trans-unit>
<trans-unit id="s6df42b3072a2d7e9">
<source>Nginx (Ingress)</source>
<target>Nginx (Ingress)</target>
</trans-unit>
<trans-unit id="s8e01a852c1db8d29">
<source>Nginx (Proxy Manager)</source>
<target>Nginx (Proxy Manager)</target>
</trans-unit>
<trans-unit id="sabebdc7fa6a5bddb">
<source>Nginx (standalone)</source>
<target>Nginx (standalone)</target>
</trans-unit>
<trans-unit id="s5d9f93f1fe1c19d3">
<source>Traefik (Ingress)</source>
<target>Traefik (Ingress)</target>
</trans-unit>
<trans-unit id="se2b62f7e9017965e">
<source>Traefik (Compose)</source>
<target>Traefik (Compose)</target>
</trans-unit>
<trans-unit id="s4c4c504a48c3b7bd">
<source>Traefik (Standalone)</source>
<target>Traefik (Standalone)</target>
</trans-unit>
<trans-unit id="s7ba9677d069e5f02">
<source>Caddy (Standalone)</source>
<target>Caddy (Standalone)</target>
</trans-unit>
<trans-unit id="s4a1e774ab25aa232">
<source>Internal Host</source>
<target>Internal Host</target>
</trans-unit>
<trans-unit id="sc9c3578cce3cf7a8">
<source>External Host</source>
<target>External Host</target>
</trans-unit>
<trans-unit id="s7a141f1b61074fbe">
<source>Basic-Auth</source>
<target>Basic-Auth</target>
</trans-unit>
<trans-unit id="scb489a1a173ac3f0">
<source>Yes</source>
<target>Yes</target>
</trans-unit>
<trans-unit id="s37cbecaec58e2192">
<source>Mode</source>
<target>Mode</target>
</trans-unit>
<trans-unit id="s4e474b9e2e737dd1">
<source>Update Proxy Provider</source>
<target>Update Proxy Provider</target>
</trans-unit>
<trans-unit id="s37eb2f1b6e3c19c2">
<source>Protocol Settings</source>
<target>Protocol Settings</target>
</trans-unit>
<trans-unit id="s5116b89f7db1fbec">
<source>Allowed Redirect URIs</source>
<target>Allowed Redirect URIs</target>
</trans-unit>
<trans-unit id="saeff3596e1ac31b6">
<source>Setup</source>
<target>Setup</target>
</trans-unit>
<trans-unit id="s1b783856ab4aaaf3">
<source>No additional setup is required.</source>
<target>No additional setup is required.</target>
</trans-unit>
<trans-unit id="s09b671b120443043">
<source>Update Radius Provider</source>
<target>Update Radius Provider</target>
</trans-unit>
<trans-unit id="sd3386a2ef42e80b9">
<source>Download</source>
<target>Download</target>
</trans-unit>
<trans-unit id="sf417c13d7a0f7995">
<source>Copy download URL</source>
<target>Copy download URL</target>
</trans-unit>
<trans-unit id="sc1cfce89ebcf1bf9">
<source>Download signing certificate</source>
<target>Download signing certificate</target>
</trans-unit>
<trans-unit id="s2c0de3d35a7bc784">
<source>Related objects</source>
<target>Related objects</target>
</trans-unit>
<trans-unit id="s803b0621006085be">
<source>Update SAML Provider</source>
<target>Update SAML Provider</target>
</trans-unit>
<trans-unit id="s44b1f042790cd1a2">
<source>SAML Configuration</source>
<target>SAML Configuration</target>
</trans-unit>
<trans-unit id="sba999428083abce3">
<source>EntityID/Issuer</source>
<target>EntityID/Issuer</target>
</trans-unit>
<trans-unit id="scd2984ee5552643a">
<source>SSO URL (Post)</source>
<target>SSO URL (Post)</target>
</trans-unit>
<trans-unit id="saa79b47f60c66458">
<source>SSO URL (Redirect)</source>
<target>SSO URL (Redirect)</target>
</trans-unit>
<trans-unit id="s2da51a6287118ba8">
<source>SSO URL (IdP-initiated Login)</source>
<target>SSO URL (IdP-initiated Login)</target>
</trans-unit>
<trans-unit id="s0a57e911e457302b">
<source>SLO URL (Post)</source>
<target>SLO URL (Post)</target>
</trans-unit>
<trans-unit id="s1e7308bb1ca323e1">
<source>SLO URL (Redirect)</source>
<target>SLO URL (Redirect)</target>
</trans-unit>
<trans-unit id="sd2c58d7c6dddc515">
<source>SAML Metadata</source>
<target>SAML Metadata</target>
</trans-unit>
<trans-unit id="s382b702673776873">
<source>Example SAML attributes</source>
<target>Example SAML attributes</target>
</trans-unit>
<trans-unit id="sea3bfc143ced73db">
<source>NameID attribute</source>
<target>NameID attribute</target>
</trans-unit>
<trans-unit id="s2f0f6691de0b0388">
<source>Warning: Provider is not assigned to an application as backchannel provider.</source>
<target>Warning: Provider is not assigned to an application as backchannel provider.</target>
</trans-unit>
<trans-unit id="sc6c575c5ff64cdb1">
<source>Update SCIM Provider</source>
<target>Update SCIM Provider</target>
</trans-unit>
<trans-unit id="s7da38af36522ff6a">
<source>Sync not run yet.</source>
<target>Sync not run yet.</target>
</trans-unit>
<trans-unit id="sbecf8dc03c978d15">
<source>Run sync again</source>
<target>Run sync again</target>
</trans-unit>
<trans-unit id="sc2cedfb22488ccb2">
<source>Modern applications, APIs and Single-page applications.</source>
<target>Modern applications, APIs and Single-page applications.</target>
</trans-unit>
<trans-unit id="sc3259eb55cf91e8c">
<source>LDAP</source>
<target>LDAP</target>
</trans-unit>
<trans-unit id="sffd5481034a1bd41">
<source>Provide an LDAP interface for applications and users to authenticate against.</source>
<target>Provide an LDAP interface for applications and users to authenticate against.</target>
</trans-unit>
<trans-unit id="s0c9670f429e74283">
<source>New application</source>
<target>New application</target>
</trans-unit>
<trans-unit id="s6ba50bb0842ba1e2">
<source>Applications</source>
<target>Applications</target>
</trans-unit>
<trans-unit id="s96b2fefc550e4b1c">
<source>Provider Type</source>
<target>Provider Type</target>
</trans-unit>
<trans-unit id="sd20f6cd02c90867f">
<source>Application(s)</source>
<target>Application(s)</target>
</trans-unit>
<trans-unit id="sb564f81eb057342e">
<source>Application Icon</source>
<target>Application Icon</target>
</trans-unit>
<trans-unit id="sa347e31efbb60be2">
<source>Update Application</source>
<target>Update Application</target>
</trans-unit>
<trans-unit id="sd9b556a84ae25690">
<source>Successfully sent test-request.</source>
<target>Successfully sent test-request.</target>
</trans-unit>
<trans-unit id="s5deac600e329de1b">
<source>Log messages</source>
<target>Log messages</target>
</trans-unit>
<trans-unit id="s3feea7b49673bef2">
<source>No log messages.</source>
<target>No log messages.</target>
</trans-unit>
<trans-unit id="sa45a194b58837e4f">
<source>Active</source>
<target>Active</target>
</trans-unit>
<trans-unit id="s58c867aac77b9158">
<source>Last login</source>
<target>Last login</target>
</trans-unit>
<trans-unit id="s3e3bb9e7cb1de4fd">
<source>Select users to add</source>
<target>Select users to add</target>
</trans-unit>
<trans-unit id="s75d5ff5dd8d3c6d2">
<source>Successfully updated group.</source>
<target>Successfully updated group.</target>
</trans-unit>
<trans-unit id="s3079ca1184e77573">
<source>Successfully created group.</source>
<target>Successfully created group.</target>
</trans-unit>
<trans-unit id="s63cb05541b294335">
<source>Is superuser</source>
<target>Is superuser</target>
</trans-unit>
<trans-unit id="s29315e374008d0c5">
<source>Users added to this group will be superusers.</source>
<target>Users added to this group will be superusers.</target>
</trans-unit>
<trans-unit id="s4eb514ebcb80553d">
<source>Parent</source>
<target>Parent</target>
</trans-unit>
<trans-unit id="s16b9446e3a70e1f4">
<source>Attributes</source>
<target>Attributes</target>
</trans-unit>
<trans-unit id="sec97cdaf7af8648b">
<source>Set custom attributes using YAML or JSON.</source>
<target>Set custom attributes using YAML or JSON.</target>
</trans-unit>
<trans-unit id="s1e36813d3504ed48">
<source>Successfully updated binding.</source>
<target>Successfully updated binding.</target>
</trans-unit>
<trans-unit id="s1bf56ee106e9e711">
<source>Successfully created binding.</source>
<target>Successfully created binding.</target>
</trans-unit>
<trans-unit id="s042baf59902a711f">
<source>Policy</source>
<target>Policy</target>
</trans-unit>
<trans-unit id="s5f5bf4ef2bd93c04">
<source>Group mappings can only be checked if a user is already logged in when trying to access this source.</source>
<target>Group mappings can only be checked if a user is already logged in when trying to access this source.</target>
</trans-unit>
<trans-unit id="s6c607d74bdfe9f36">
<source>User mappings can only be checked if a user is already logged in when trying to access this source.</source>
<target>User mappings can only be checked if a user is already logged in when trying to access this source.</target>
</trans-unit>
<trans-unit id="s965c503c3e42fdfe">
<source>Enabled</source>
<target>Enabled</target>
</trans-unit>
<trans-unit id="s6b85380416964890">
<source>Negate result</source>
<target>Negate result</target>
</trans-unit>
<trans-unit id="s3bfa0258999fb629">
<source>Negates the outcome of the binding. Messages are unaffected.</source>
<target>Negates the outcome of the binding. Messages are unaffected.</target>
</trans-unit>
<trans-unit id="s2ba5f4d8f3bd7c57">
<source>Order</source>
<target>Order</target>
</trans-unit>
<trans-unit id="se1e040b55319a0e8">
<source>Timeout</source>
<target>Timeout</target>
</trans-unit>
<trans-unit id="s29ec5e7889f4787f">
<source>Successfully updated policy.</source>
<target>Successfully updated policy.</target>
</trans-unit>
<trans-unit id="sfc400b2d71e49d28">
<source>Successfully created policy.</source>
<target>Successfully created policy.</target>
</trans-unit>
<trans-unit id="safc0e0656d572f4e">
<source>A policy used for testing. Always returns the same result as specified below after waiting a random duration.</source>
<target>A policy used for testing. Always returns the same result as specified below after waiting a random duration.</target>
</trans-unit>
<trans-unit id="s9ffa1ac03ce6fd20">
<source>Execution logging</source>
<target>Execution logging</target>
</trans-unit>
<trans-unit id="saf31b3c610036ed6">
<source>When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.</source>
<target>When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged.</target>
</trans-unit>
<trans-unit id="sa879d5ce584875cf">
<source>Policy-specific settings</source>
<target>Policy-specific settings</target>
</trans-unit>
<trans-unit id="s838418d1a0815157">
<source>Pass policy?</source>
<target>Pass policy?</target>
</trans-unit>
<trans-unit id="sd8c5339b82b71507">
<source>Wait (min)</source>
<target>Wait (min)</target>
</trans-unit>
<trans-unit id="sda4e78c19f5b6f35">
<source>The policy takes a random time to execute. This controls the minimum time it will take.</source>
<target>The policy takes a random time to execute. This controls the minimum time it will take.</target>
</trans-unit>
<trans-unit id="s1d30ff9ba938e68d">
<source>Wait (max)</source>
<target>Wait (max)</target>
</trans-unit>
<trans-unit id="s303b5e552246e613">
<source>Matches an event against a set of criteria. If any of the configured values match, the policy passes.</source>
<target>Matches an event against a set of criteria. If any of the configured values match, the policy passes.</target>
</trans-unit>
<trans-unit id="s890810efbe103cbc">
<source>Match created events with this action type. When left empty, all action types will be matched.</source>
<target>Match created events with this action type. When left empty, all action types will be matched.</target>
</trans-unit>
<trans-unit id="sfab527528ea64618">
<source>Matches Event's Client IP (strict matching, for network matching use an Expression Policy.</source>
<target>Matches Event's Client IP (strict matching, for network matching use an Expression Policy.</target>
</trans-unit>
<trans-unit id="s5a15a8f39c699273">
<source>Match events created by selected application. When left empty, all applications are matched.</source>
<target>Match events created by selected application. When left empty, all applications are matched.</target>
</trans-unit>
<trans-unit id="s5a13f4bbe004503f">
<source>Checks if the request's user's password has been changed in the last x days, and denys based on settings.</source>
<target>Checks if the request's user's password has been changed in the last x days, and denys based on settings.</target>
</trans-unit>
<trans-unit id="sfad8af8ce38104a3">
<source>Maximum age (in days)</source>
<target>Maximum age (in days)</target>
</trans-unit>
<trans-unit id="s9307f3dbb07a73b5">
<source>Only fail the policy, don't invalidate user's password</source>
<target>Only fail the policy, don't invalidate user's password</target>
</trans-unit>
<trans-unit id="scea1f16238093e35">
<source>Executes the python snippet to determine whether to allow or deny a request.</source>
<target>Executes the python snippet to determine whether to allow or deny a request.</target>
</trans-unit>
<trans-unit id="sabd1bc9fb7da71e7">
<source>Expression using Python.</source>
<target>Expression using Python.</target>
</trans-unit>
<trans-unit id="s8d08843f397d9e81">
<source>See documentation for a list of all variables.</source>
<target>See documentation for a list of all variables.</target>
</trans-unit>
<trans-unit id="se2cc93bd2647baec">
<source>Static rules</source>
<target>Static rules</target>
</trans-unit>
<trans-unit id="sc96dd9d2e7b05fc5">
<source>Minimum length</source>
<target>Minimum length</target>
</trans-unit>
<trans-unit id="s33d48fb745f4d4ae">
<source>Minimum amount of Uppercase Characters</source>
<target>Minimum amount of Uppercase Characters</target>
</trans-unit>
<trans-unit id="s883b544e2b4aa3b5">
<source>Minimum amount of Lowercase Characters</source>
<target>Minimum amount of Lowercase Characters</target>
</trans-unit>
<trans-unit id="s43be3ce2439ffe9c">
<source>Minimum amount of Digits</source>
<target>Minimum amount of Digits</target>
</trans-unit>
<trans-unit id="sb3651834cca86735">
<source>Minimum amount of Symbols Characters</source>
<target>Minimum amount of Symbols Characters</target>
</trans-unit>
<trans-unit id="sc2f116c0ea77d58a">
<source>Error message</source>
<target>Error message</target>
</trans-unit>
<trans-unit id="s21d0e290c51a8ef9">
<source>Symbol charset</source>
<target>Symbol charset</target>
</trans-unit>
<trans-unit id="s545d99afa61e4095">
<source>Characters which are considered as symbols.</source>
<target>Characters which are considered as symbols.</target>
</trans-unit>
<trans-unit id="s1293ad87acc7a609">
<source>HaveIBeenPwned settings</source>
<target>HaveIBeenPwned settings</target>
</trans-unit>
<trans-unit id="sdf4e1c6a2f072600">
<source>Allowed count</source>
<target>Allowed count</target>
</trans-unit>
<trans-unit id="scd8062ff5e1326d8">
<source>Allow up to N occurrences in the HIBP database.</source>
<target>Allow up to N occurrences in the HIBP database.</target>
</trans-unit>
<trans-unit id="s3fd219b045193507">
<source>zxcvbn settings</source>
<target>zxcvbn settings</target>
</trans-unit>
<trans-unit id="s28d84abfbaf555ea">
<source>Score threshold</source>
<target>Score threshold</target>
</trans-unit>
<trans-unit id="s7b3148ffba9f4527">
<source>If the password's score is less than or equal this value, the policy will fail.</source>
<target>If the password's score is less than or equal this value, the policy will fail.</target>
</trans-unit>
<trans-unit id="sd6cd7ce2310a73a4">
<source>Checks the value from the policy request against several rules, mostly used to ensure password strength.</source>
<target>Checks the value from the policy request against several rules, mostly used to ensure password strength.</target>
</trans-unit>
<trans-unit id="s2a957e843960b604">
<source>Password field</source>
<target>Password field</target>
</trans-unit>
<trans-unit id="se8a81c75b6e30a33">
<source>Field key to check, field keys defined in Prompt stages are available.</source>
<target>Field key to check, field keys defined in Prompt stages are available.</target>
</trans-unit>
<trans-unit id="s2f8c4cf12350a36c">
<source>Check static rules</source>
<target>Check static rules</target>
</trans-unit>
<trans-unit id="sd75a9a71309fb387">
<source>Check haveibeenpwned.com</source>
<target>Check haveibeenpwned.com</target>
</trans-unit>
<trans-unit id="se5cb18408df3284e">
<source>For more info see:</source>
<target>For more info see:</target>
</trans-unit>
<trans-unit id="scef7abb8456b06d6">
<source>Check zxcvbn</source>
<target>Check zxcvbn</target>
</trans-unit>
<trans-unit id="sdfdb58cd232b363d">
<source>Password strength estimator created by Dropbox, see:</source>
<target>Password strength estimator created by Dropbox, see:</target>
</trans-unit>
<trans-unit id="s40b034801fcb843b">
<source>Allows/denys requests based on the users and/or the IPs reputation.</source>
<target>Allows/denys requests based on the users and/or the IPs reputation.</target>
</trans-unit>
<trans-unit id="scf4afecb0f1e69b2">
<source>Invalid login attempts will decrease the score for the client's IP, and the
username they are attempting to login as, by one.</source>
</trans-unit>
<trans-unit id="s8323a9af28e10502">
<source>The policy passes when the reputation score is below the threshold, and
doesn't pass when either or both of the selected options are equal or above the threshold.</source>
</trans-unit>
<trans-unit id="s1828fbfc2c56379c">
<source>Check IP</source>
<target>Check IP</target>
</trans-unit>
<trans-unit id="s4751df77cfd8a5f9">
<source>Check Username</source>
<target>Check Username</target>
</trans-unit>
<trans-unit id="se19cc57dd8675498">
<source>Threshold</source>
<target>Threshold</target>
</trans-unit>
<trans-unit id="sdbccb39a658f0e45">
<source>New policy</source>
<target>New policy</target>
</trans-unit>
<trans-unit id="sf693300708a40d2c">
<source>Create a new policy.</source>
<target>Create a new policy.</target>
</trans-unit>
<trans-unit id="s5b1fb0d4c0daeba8">
<source>Create Binding</source>
<target>Create Binding</target>
</trans-unit>
<trans-unit id="s9fb28be12e2c6317">
<source>Superuser</source>
<target>Superuser</target>
</trans-unit>
<trans-unit id="s9f5a5f23312798f0">
<source>Members</source>
<target>Members</target>
</trans-unit>
<trans-unit id="s7eb3d239e0b491ab">
<source>Select groups to add user to</source>
<target>Select groups to add user to</target>
</trans-unit>
<trans-unit id="sec5cdfa358f9dbf7">
<source>Warning: Adding the user to the selected group(s) will give them superuser permissions.</source>
<target>Warning: Adding the user to the selected group(s) will give them superuser permissions.</target>
</trans-unit>
<trans-unit id="scab2900019953050">
<source>Successfully updated user.</source>
<target>Successfully updated user.</target>
</trans-unit>
<trans-unit id="s9c3c272944dcfca3">
<source>Successfully created user.</source>
<target>Successfully created user.</target>
</trans-unit>
<trans-unit id="s03f42eea72154959">
<source>Username</source>
<target>Username</target>
</trans-unit>
<trans-unit id="s5a802e46a033c8af">
<source>User's primary identifier. 150 characters or fewer.</source>
<target>User's primary identifier. 150 characters or fewer.</target>
</trans-unit>
<trans-unit id="sd34be0d0fcb39971">
<source>User's display name.</source>
<target>User's display name.</target>
</trans-unit>
<trans-unit id="sd1f44f1a8bc20e67">
<source>Email</source>
<target>Email</target>
</trans-unit>
<trans-unit id="sbe3b416a356f1c91">
<source>Is active</source>
<target>Is active</target>
</trans-unit>
<trans-unit id="s35fac2e5677d55cd">
<source>Designates whether this user should be treated as active. Unselect this instead of deleting accounts.</source>
<target>Designates whether this user should be treated as active. Unselect this instead of deleting accounts.</target>
</trans-unit>
<trans-unit id="s2e532e19ed477a56">
<source>Path</source>
<target>Path</target>
</trans-unit>
<trans-unit id="s67560d7e37d984c3">
<source>Policy / User / Group</source>
<target>Policy / User / Group</target>
</trans-unit>
<trans-unit id="s030ac0829bb50a49">
<source>Policy <x id="0" equiv-text="${item.policyObj?.name}"/></source>
<target>Policy
<x id="0" equiv-text="${item.policyObj?.name}"/></target>
</trans-unit>
<trans-unit id="s2a64d2dca3da9b0e">
<source>Group <x id="0" equiv-text="${item.groupObj?.name}"/></source>
<target>Group
<x id="0" equiv-text="${item.groupObj?.name}"/></target>
</trans-unit>
<trans-unit id="se5dc026819a32ff8">
<source>User <x id="0" equiv-text="${item.userObj?.name}"/></source>
<target>User
<x id="0" equiv-text="${item.userObj?.name}"/></target>
</trans-unit>
<trans-unit id="s50c312bea93b6925">
<source>Edit Policy</source>
<target>Edit Policy</target>
</trans-unit>
<trans-unit id="s0b55a57f473ab8af">
<source>Update Group</source>
<target>Update Group</target>
</trans-unit>
<trans-unit id="s494e1ed913d9351a">
<source>Edit Group</source>
<target>Edit Group</target>
</trans-unit>
<trans-unit id="sad130c2d925fb7bf">
<source>Update User</source>
<target>Update User</target>
</trans-unit>
<trans-unit id="s5cd31f4a88adf180">
<source>Edit User</source>
<target>Edit User</target>
</trans-unit>
<trans-unit id="se291dfd2a59d7842">
<source>Policy binding(s)</source>
<target>Policy binding(s)</target>
</trans-unit>
<trans-unit id="s7e87ab366c199345">
<source>Update Binding</source>
<target>Update Binding</target>
</trans-unit>
<trans-unit id="s40b80eb4cc1f0e0c">
<source>Edit Binding</source>
<target>Edit Binding</target>
</trans-unit>
<trans-unit id="sbad5b96fb855ef36">
<source>No Policies bound.</source>
<target>No Policies bound.</target>
</trans-unit>
<trans-unit id="sc15d60377cc8aaac">
<source>No policies are currently bound to this object.</source>
<target>No policies are currently bound to this object.</target>
</trans-unit>
<trans-unit id="sddb040c47daae56b">
<source>Bind existing policy</source>
<target>Bind existing policy</target>
</trans-unit>
<trans-unit id="saa855c61e0403fe6">
<source>Warning: Application is not used by any Outpost.</source>
<target>Warning: Application is not used by any Outpost.</target>
</trans-unit>
<trans-unit id="sb6cbd4f92ebaf5d8">
<source>Related</source>
<target>Related</target>
</trans-unit>
<trans-unit id="sc92ea8fbf9ba06a7">
<source>Backchannel Providers</source>
<target>Backchannel Providers</target>
</trans-unit>
<trans-unit id="sd71081c23d1cd38b">
<source>Check access</source>
<target>Check access</target>
</trans-unit>
<trans-unit id="s42cbd8dca939a9c7">
<source>Check</source>
<target>Check</target>
</trans-unit>
<trans-unit id="sf22f7f8a9309b4ed">
<source>Check Application access</source>
<target>Check Application access</target>
</trans-unit>
<trans-unit id="s2474e7fb1aec9f05">
<source>Test</source>
<target>Test</target>
</trans-unit>
<trans-unit id="s512957aa09384646">
<source>Launch</source>
<target>Launch</target>
</trans-unit>
<trans-unit id="sed02f831e653deb3">
<source>Logins over the last week (per 8 hours)</source>
<target>Logins over the last week (per 8 hours)</target>
</trans-unit>
<trans-unit id="s2b1bc31276c4c477">
<source>Policy / Group / User Bindings</source>
<target>Policy / Group / User Bindings</target>
</trans-unit>
<trans-unit id="s473f0143efa3f706">
<source>These policies control which users can access this application.</source>
<target>These policies control which users can access this application.</target>
</trans-unit>
<trans-unit id="s24875d5475e82526">
<source>Successfully updated source.</source>
<target>Successfully updated source.</target>
</trans-unit>
<trans-unit id="s60d891ed3ee9ebc5">
<source>Successfully created source.</source>
<target>Successfully created source.</target>
</trans-unit>
<trans-unit id="s8af7239354f7e7b6">
<source>Sync users</source>
<target>Sync users</target>
</trans-unit>
<trans-unit id="sd80b0b8aeae3abe3">
<source>User password writeback</source>
<target>User password writeback</target>
</trans-unit>
<trans-unit id="s2b952e9dc99cbded">
<source>Login password is synced from LDAP into authentik automatically. Enable this option only to write password changes in authentik back to LDAP.</source>
<target>Login password is synced from LDAP into authentik automatically. Enable this option only to write password changes in authentik back to LDAP.</target>
</trans-unit>
<trans-unit id="saf7ce4165a1025f6">
<source>Sync groups</source>
<target>Sync groups</target>
</trans-unit>
<trans-unit id="s2035f889f576bca6">
<source>Connection settings</source>
<target>Connection settings</target>
</trans-unit>
<trans-unit id="s0a72e65aef45b1e8">
<source>Server URI</source>
<target>Server URI</target>
</trans-unit>
<trans-unit id="sa599dbe5776897ad">
<source>Specify multiple server URIs by separating them with a comma.</source>
<target>Specify multiple server URIs by separating them with a comma.</target>
</trans-unit>
<trans-unit id="se36b55dfcf5dc80b">
<source>Enable StartTLS</source>
<target>Enable StartTLS</target>
</trans-unit>
<trans-unit id="s33683c3b1dbaf264">
<source>To use SSL instead, use 'ldaps://' and disable this option.</source>
<target>To use SSL instead, use 'ldaps://' and disable this option.</target>
</trans-unit>
<trans-unit id="s2221fef80f4753a2">
<source>TLS Verification Certificate</source>
<target>TLS Verification Certificate</target>
</trans-unit>
<trans-unit id="sb8c13bd58191cea2">
<source>When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate.</source>
<target>When connecting to an LDAP Server with TLS, certificates are not checked by default. Specify a keypair to validate the remote certificate.</target>
</trans-unit>
<trans-unit id="sb7684e2910a33a1f">
<source>Bind CN</source>
<target>Bind CN</target>
</trans-unit>
<trans-unit id="s3de6db803012016a">
<source>LDAP Attribute mapping</source>
<target>LDAP Attribute mapping</target>
</trans-unit>
<trans-unit id="s7c05ee41d634aa45">
<source>Property mappings used to user creation.</source>
<target>Property mappings used to user creation.</target>
</trans-unit>
<trans-unit id="s94333971a07803b9">
<source>Additional settings</source>
<target>Additional settings</target>
</trans-unit>
<trans-unit id="sd14a19a19d507f9e">
<source>Parent group for all the groups imported from LDAP.</source>
<target>Parent group for all the groups imported from LDAP.</target>
</trans-unit>
<trans-unit id="sfbc59ff17a73503d">
<source>User path</source>
<target>User path</target>
</trans-unit>
<trans-unit id="sd18170637295bace">
<source>Addition User DN</source>
<target>Addition User DN</target>
</trans-unit>
<trans-unit id="s9ae089fd248e72db">
<source>Additional user DN, prepended to the Base DN.</source>
<target>Additional user DN, prepended to the Base DN.</target>
</trans-unit>
<trans-unit id="s5944355d69db1fb8">
<source>Addition Group DN</source>
<target>Addition Group DN</target>
</trans-unit>
<trans-unit id="sfae9f4ea5749a36b">
<source>Additional group DN, prepended to the Base DN.</source>
<target>Additional group DN, prepended to the Base DN.</target>
</trans-unit>
<trans-unit id="s66ffc06300964849">
<source>User object filter</source>
<target>User object filter</target>
</trans-unit>
<trans-unit id="s1c2a173db0e1ec61">
<source>Consider Objects matching this filter to be Users.</source>
<target>Consider Objects matching this filter to be Users.</target>
</trans-unit>
<trans-unit id="s2ec94a7c7f5bcd1b">
<source>Group object filter</source>
<target>Group object filter</target>
</trans-unit>
<trans-unit id="saf5eb7596b3a355b">
<source>Consider Objects matching this filter to be Groups.</source>
<target>Consider Objects matching this filter to be Groups.</target>
</trans-unit>
<trans-unit id="sf325a4adba4d6278">
<source>Group membership field</source>
<target>Group membership field</target>
</trans-unit>
<trans-unit id="s76768bebabb7d543">
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
<target>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</target>
</trans-unit>
<trans-unit id="s026555347e589f0e">
<source>Object uniqueness field</source>
<target>Object uniqueness field</target>
</trans-unit>
<trans-unit id="s24211f319e5b7e98">
<source>Field which contains a unique Identifier.</source>
<target>Field which contains a unique Identifier.</target>
</trans-unit>
<trans-unit id="s900b0d85b872d134">
<source>Link users on unique identifier</source>
<target>Link users on unique identifier</target>
</trans-unit>
<trans-unit id="s6c70a73265e14521">
<source>Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses</source>
<target>Link to a user with identical email address. Can have security implications when a source doesn't validate email addresses</target>
</trans-unit>
<trans-unit id="s995535e7af30d754">
<source>Use the user's email address, but deny enrollment when the email address already exists</source>
<target>Use the user's email address, but deny enrollment when the email address already exists</target>
</trans-unit>
<trans-unit id="s542ecb4130f6cea5">
<source>Link to a user with identical username. Can have security implications when a username is used with another source</source>
<target>Link to a user with identical username. Can have security implications when a username is used with another source</target>
</trans-unit>
<trans-unit id="s2a1debf34e5aeba4">
<source>Use the user's username, but deny enrollment when the username already exists</source>
<target>Use the user's username, but deny enrollment when the username already exists</target>
</trans-unit>
<trans-unit id="s81ce0d54727f42d2">
<source>Unknown user matching mode</source>
<target>Unknown user matching mode</target>
</trans-unit>
<trans-unit id="sd04376c4216c921f">
<source>URL settings</source>
<target>URL settings</target>
</trans-unit>
<trans-unit id="s872d0e88ab34ed83">
<source>Authorization URL</source>
<target>Authorization URL</target>
</trans-unit>
<trans-unit id="see3ff55262fd6500">
<source>URL the user is redirect to to consent the authorization.</source>
<target>URL the user is redirect to to consent the authorization.</target>
</trans-unit>
<trans-unit id="sb932dead79567c7b">
<source>Access token URL</source>
<target>Access token URL</target>
</trans-unit>
<trans-unit id="s88b8a2892635a2fc">
<source>URL used by authentik to retrieve tokens.</source>
<target>URL used by authentik to retrieve tokens.</target>
</trans-unit>
<trans-unit id="s69bd313dd12fc2f3">
<source>Profile URL</source>
<target>Profile URL</target>
</trans-unit>
<trans-unit id="sa8d83cd8023e8e4d">
<source>URL used by authentik to get user information.</source>
<target>URL used by authentik to get user information.</target>
</trans-unit>
<trans-unit id="sc7707b3ba3a2a7ca">
<source>Request token URL</source>
<target>Request token URL</target>
</trans-unit>
<trans-unit id="s3926da5b20cdf3b6">
<source>URL used to request the initial token. This URL is only required for OAuth 1.</source>
<target>URL used to request the initial token. This URL is only required for OAuth 1.</target>
</trans-unit>
<trans-unit id="s199b55513a739f43">
<source>OIDC Well-known URL</source>
<target>OIDC Well-known URL</target>
</trans-unit>
<trans-unit id="s8b149b30b5b523ef">
<source>OIDC well-known configuration URL. Can be used to automatically configure the URLs above.</source>
<target>OIDC well-known configuration URL. Can be used to automatically configure the URLs above.</target>
</trans-unit>
<trans-unit id="s9db2c836ade1339c">
<source>OIDC JWKS URL</source>
<target>OIDC JWKS URL</target>
</trans-unit>
<trans-unit id="s4b2a1b657c160f5b">
<source>JSON Web Key URL. Keys from the URL will be used to validate JWTs from this source.</source>
<target>JSON Web Key URL. Keys from the URL will be used to validate JWTs from this source.</target>
</trans-unit>
<trans-unit id="s2df0b65125600de9">
<source>OIDC JWKS</source>
<target>OIDC JWKS</target>
</trans-unit>
<trans-unit id="s02de8d9e8583b480">
<source>Raw JWKS data.</source>
<target>Raw JWKS data.</target>
</trans-unit>
<trans-unit id="s81a87652ade099e4">
<source>User matching mode</source>
<target>User matching mode</target>
</trans-unit>
<trans-unit id="s485c05d34eb00415">
<source>Delete currently set icon.</source>
<target>Delete currently set icon.</target>
</trans-unit>
<trans-unit id="se8987bdfb35e46b2">
<source>Consumer key</source>
<target>Consumer key</target>
</trans-unit>
<trans-unit id="sabaf0061f7e41b0b">
<source>Consumer secret</source>
<target>Consumer secret</target>
</trans-unit>
<trans-unit id="sa61966cd83b4924c">
<source>Additional scopes to be passed to the OAuth Provider, separated by space. To replace existing scopes, prefix with *.</source>
<target>Additional scopes to be passed to the OAuth Provider, separated by space. To replace existing scopes, prefix with *.</target>
</trans-unit>
<trans-unit id="s1cc0e66dbd2b5502">
<source>Flow settings</source>
<target>Flow settings</target>
</trans-unit>
<trans-unit id="sfe6977a3aea3ee6e">
<source>Flow to use when authenticating existing users.</source>
<target>Flow to use when authenticating existing users.</target>
</trans-unit>
<trans-unit id="s2801a48ceac691b3">
<source>Enrollment flow</source>
<target>Enrollment flow</target>
</trans-unit>
<trans-unit id="s5d0a14d29ebad561">
<source>Flow to use when enrolling new users.</source>
<target>Flow to use when enrolling new users.</target>
</trans-unit>
<trans-unit id="s91f389c796720a81">
<source>Load servers</source>
<target>Load servers</target>
</trans-unit>
<trans-unit id="s24f405197ede5ebb">
<source>Re-authenticate with plex</source>
<target>Re-authenticate with plex</target>
</trans-unit>
<trans-unit id="sc297b2e13c28ecf9">
<source>Allow friends to authenticate via Plex, even if you don't share any servers</source>
<target>Allow friends to authenticate via Plex, even if you don't share any servers</target>
</trans-unit>
<trans-unit id="sfee91e08b8b47477">
<source>Allowed servers</source>
<target>Allowed servers</target>
</trans-unit>
<trans-unit id="s216eb300543edd91">
<source>Select which server a user has to be a member of to be allowed to authenticate.</source>
<target>Select which server a user has to be a member of to be allowed to authenticate.</target>
</trans-unit>
<trans-unit id="s31d7f3ba04d306a5">
<source>SSO URL</source>
<target>SSO URL</target>
</trans-unit>
<trans-unit id="s1d9d6c5b424fdc1f">
<source>URL that the initial Login request is sent to.</source>
<target>URL that the initial Login request is sent to.</target>
</trans-unit>
<trans-unit id="sd94db2b8c85d10a6">
<source>SLO URL</source>
<target>SLO URL</target>
</trans-unit>
<trans-unit id="sc764ddf60b5149de">
<source>Optional URL if the IDP supports Single-Logout.</source>
<target>Optional URL if the IDP supports Single-Logout.</target>
</trans-unit>
<trans-unit id="se7430794fa89005a">
<source>Also known as Entity ID. Defaults the Metadata URL.</source>
<target>Also known as Entity ID. Defaults the Metadata URL.</target>
</trans-unit>
<trans-unit id="s5615bb595ad6ded6">
<source>Binding Type</source>
<target>Binding Type</target>
</trans-unit>
<trans-unit id="sa2e4d6830226d3ec">
<source>Redirect binding</source>
<target>Redirect binding</target>
</trans-unit>
<trans-unit id="s6f96a78d81ef277c">
<source>Post-auto binding</source>
<target>Post-auto binding</target>
</trans-unit>
<trans-unit id="sc2c70fd56f5d0b48">
<source>Post binding but the request is automatically sent and the user doesn't have to confirm.</source>
<target>Post binding but the request is automatically sent and the user doesn't have to confirm.</target>
</trans-unit>
<trans-unit id="s968c90258dcf7562">
<source>Post binding</source>
<target>Post binding</target>
</trans-unit>
<trans-unit id="se10bbf4cf861c81b">
<source>Signing keypair</source>
<target>Signing keypair</target>
</trans-unit>
<trans-unit id="s838ed611b533b19e">
<source>Keypair which is used to sign outgoing requests. Leave empty to disable signing.</source>
<target>Keypair which is used to sign outgoing requests. Leave empty to disable signing.</target>
</trans-unit>
<trans-unit id="s39c8c0bf4d927c9f">
<source> Allow IDP-initiated logins</source>
<target>Allow IDP-initiated logins</target>
</trans-unit>
<trans-unit id="s65d507f1513c2f03">
<source>Allows authentication flows initiated by the IdP. This can be a security risk, as no validation of the request ID is done.</source>
<target>Allows authentication flows initiated by the IdP. This can be a security risk, as no validation of the request ID is done.</target>
</trans-unit>
<trans-unit id="s297a2075bd7e40db">
<source>NameID Policy</source>
<target>NameID Policy</target>
</trans-unit>
<trans-unit id="s004e9a2c90f23900">
<source>Persistent</source>
<target>Persistent</target>
</trans-unit>
<trans-unit id="s38887b94b3320533">
<source>Email address</source>
<target>Email address</target>
</trans-unit>
<trans-unit id="s2d34c87f67f66c6a">
<source>Windows</source>
<target>Windows</target>
</trans-unit>
<trans-unit id="s1665454e31e14941">
<source>X509 Subject</source>
<target>X509 Subject</target>
</trans-unit>
<trans-unit id="s0c3ac7f9383a8cfd">
<source>Transient</source>
<target>Transient</target>
</trans-unit>
<trans-unit id="s20a0ce62823bfa97">
<source>Delete temporary users after</source>
<target>Delete temporary users after</target>
</trans-unit>
<trans-unit id="s3198c384c2f68b08">
<source>Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually.</source>
<target>Time offset when temporary users should be deleted. This only applies if your IDP uses the NameID Format 'transient', and the user doesn't log out manually.</target>
</trans-unit>
<trans-unit id="sb32e9c1faa0b8673">
<source>Pre-authentication flow</source>
<target>Pre-authentication flow</target>
</trans-unit>
<trans-unit id="sa3c1f6ac5e63a70f">
<source>Flow used before authentication.</source>
<target>Flow used before authentication.</target>
</trans-unit>
<trans-unit id="se12969ade44cd2b6">
<source>New source</source>
<target>New source</target>
</trans-unit>
<trans-unit id="s19b09f4fc72175d1">
<source>Create a new source.</source>
<target>Create a new source.</target>
</trans-unit>
<trans-unit id="s6152026c364ad974">
<source>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</source>
<target>Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves.</target>
</trans-unit>
<trans-unit id="s0a0ca63b967f1630">
<source>Source(s)</source>
<target>Source(s)</target>
</trans-unit>
<trans-unit id="s66722bc2ea775e05">
<source>Disabled</source>
<target>Disabled</target>
</trans-unit>
<trans-unit id="s4ff2c202b4e5bdc5">
<source>Built-in</source>
<target>Built-in</target>
</trans-unit>
<trans-unit id="s52b500138a2d2b8a">
<source>Update LDAP Source</source>
<target>Update LDAP Source</target>
</trans-unit>
<trans-unit id="s31a2d43bc1cf1790">
<source>Not synced yet.</source>
<target>Not synced yet.</target>
</trans-unit>
<trans-unit id="s388ee787bbf2271b">
<source>Task finished with warnings</source>
<target>Task finished with warnings</target>
</trans-unit>
<trans-unit id="s949826fad0fe0909">
<source>Task finished with errors</source>
<target>Task finished with errors</target>
</trans-unit>
<trans-unit id="sbedb77365a066648">
<source>Last sync: <x id="0" equiv-text="${task.taskFinishTimestamp.toLocaleString()}"/></source>
<target>Last sync:
<x id="0" equiv-text="${task.taskFinishTimestamp.toLocaleString()}"/></target>
</trans-unit>
<trans-unit id="sf3fec8353106ac2f">
<source>OAuth Source <x id="0" equiv-text="${this.source.name}"/></source>
<target>OAuth Source
<x id="0" equiv-text="${this.source.name}"/></target>
</trans-unit>
<trans-unit id="se09d055771f3a11d">
<source>Generic OpenID Connect</source>
<target>Generic OpenID Connect</target>
</trans-unit>
<trans-unit id="s5c1dc164c89ac13e">
<source>Unknown provider type</source>
<target>Unknown provider type</target>
</trans-unit>
<trans-unit id="s355b21b89ce5d9c5">
<source>Details</source>
<target>Details</target>
</trans-unit>
<trans-unit id="s01088b6625d2443b">
<source>Callback URL</source>
<target>Callback URL</target>
</trans-unit>
<trans-unit id="sb6d5146d5efb3058">
<source>Access Key</source>
<target>Access Key</target>
</trans-unit>
<trans-unit id="s065604a41e9d1584">
<source>Update OAuth Source</source>
<target>Update OAuth Source</target>
</trans-unit>
<trans-unit id="s7b576aa71acb36a6">
<source>Diagram</source>
<target>Diagram</target>
</trans-unit>
<trans-unit id="s587ba266269297ab">
<source>Policy Bindings</source>
<target>Policy Bindings</target>
</trans-unit>
<trans-unit id="s2feae323f46479f8">
<source>These bindings control which users can access this source.
You can only use policies here as access is checked before the user is authenticated.</source>
</trans-unit>
<trans-unit id="se17fcb1f159ee382">
<source>Update Plex Source</source>
<target>Update Plex Source</target>
</trans-unit>
<trans-unit id="saa10777250a6deca">
<source>Update SAML Source</source>
<target>Update SAML Source</target>
</trans-unit>
<trans-unit id="s643d8f2e5e5e930d">
<source>Successfully updated mapping.</source>
<target>Successfully updated mapping.</target>
</trans-unit>
<trans-unit id="sffeef5b119d8625c">
<source>Successfully created mapping.</source>
<target>Successfully created mapping.</target>
</trans-unit>
<trans-unit id="s1c33d22492029aba">
<source>Object field</source>
<target>Object field</target>
</trans-unit>
<trans-unit id="s06df3c3b6a503da8">
<source>Field of the user object this value is written to.</source>
<target>Field of the user object this value is written to.</target>
</trans-unit>
<trans-unit id="sd39c5e998efecf93">
<source>SAML Attribute Name</source>
<target>SAML Attribute Name</target>
</trans-unit>
<trans-unit id="scf2790cf3ad89283">
<source>Attribute name used for SAML Assertions. Can be a URN OID, a schema reference, or a any other string. If this property mapping is used for NameID Property, this field is discarded.</source>
<target>Attribute name used for SAML Assertions. Can be a URN OID, a schema reference, or a any other string. If this property mapping is used for NameID Property, this field is discarded.</target>
</trans-unit>
<trans-unit id="sab6d24c5ec8dc361">
<source>Friendly Name</source>
<target>Friendly Name</target>
</trans-unit>
<trans-unit id="s9f8aac89fe318acc">
<source>Optionally set the 'FriendlyName' value of the Assertion attribute.</source>
<target>Optionally set the 'FriendlyName' value of the Assertion attribute.</target>
</trans-unit>
<trans-unit id="s851c108679653d2a">
<source>Scope name</source>
<target>Scope name</target>
</trans-unit>
<trans-unit id="s23fd4411419fca06">
<source>Scope which the client can specify to access these properties.</source>
<target>Scope which the client can specify to access these properties.</target>
</trans-unit>
<trans-unit id="s7754f0e34f27fb6e">
<source>Description shown to the user when consenting. If left empty, the user won't be informed.</source>
<target>Description shown to the user when consenting. If left empty, the user won't be informed.</target>
</trans-unit>
<trans-unit id="sb6c3bf5489d7556e">
<source>Example context data</source>
<target>Example context data</target>
</trans-unit>
<trans-unit id="s4a697f0b36c4fe83">
<source>Active Directory User</source>
<target>Active Directory User</target>
</trans-unit>
<trans-unit id="s9277b90db38e1983">
<source>Active Directory Group</source>
<target>Active Directory Group</target>
</trans-unit>
<trans-unit id="sc2e03590269d5a10">
<source>New property mapping</source>
<target>New property mapping</target>
</trans-unit>
<trans-unit id="s713e8666ed70f8b3">
<source>Create a new property mapping.</source>
<target>Create a new property mapping.</target>
</trans-unit>
<trans-unit id="sce106606ae84d46f">
<source>Property Mappings</source>
<target>Property Mappings</target>
</trans-unit>
<trans-unit id="s271a7e04ff9865b1">
<source>Control how authentik exposes and interprets information.</source>
<target>Control how authentik exposes and interprets information.</target>
</trans-unit>
<trans-unit id="s59dc0eda07f9e2b6">
<source>Property Mapping(s)</source>
<target>Property Mapping(s)</target>
</trans-unit>
<trans-unit id="sa57c393736e2732c">
<source>Test Property Mapping</source>
<target>Test Property Mapping</target>
</trans-unit>
<trans-unit id="sc39fb3ff3753d5ab">
<source>Hide managed mappings</source>
<target>Hide managed mappings</target>
</trans-unit>
<trans-unit id="s476ffc07e6d66f18">
<source>Successfully updated token.</source>
<target>Successfully updated token.</target>
</trans-unit>
<trans-unit id="s93c1e5fbe8184895">
<source>Successfully created token.</source>
<target>Successfully created token.</target>
</trans-unit>
<trans-unit id="s5fc4269c2addee61">
<source>Unique identifier the token is referenced by.</source>
<target>Unique identifier the token is referenced by.</target>
</trans-unit>
<trans-unit id="sb8bc2b8376c96a6b">
<source>Intent</source>
<target>Intent</target>
</trans-unit>
<trans-unit id="sbd34d118bcb1aaf2">
<source>API Token</source>
<target>API Token</target>
</trans-unit>
<trans-unit id="se31d92bea7f3a186">
<source>Used to access the API programmatically</source>
<target>Used to access the API programmatically</target>
</trans-unit>
<trans-unit id="sfd586951c75eb291">
<source>App password.</source>
<target>App password.</target>
</trans-unit>
<trans-unit id="s59bf194136d0d13a">
<source>Used to login using a flow executor</source>
<target>Used to login using a flow executor</target>
</trans-unit>
<trans-unit id="s1b14062c44e5ef45">
<source>Expiring</source>
<target>Expiring</target>
</trans-unit>
<trans-unit id="safcc54b2aedb1a17">
<source>If this is selected, the token will expire. Upon expiration, the token will be rotated.</source>
<target>If this is selected, the token will expire. Upon expiration, the token will be rotated.</target>
</trans-unit>
<trans-unit id="s4165cd175bc4c0c4">
<source>Expires on</source>
<target>Expires on</target>
</trans-unit>
<trans-unit id="s1cd198d689c66e4b">
<source>API Access</source>
<target>API Access</target>
</trans-unit>
<trans-unit id="sf29883ac9ec43085">
<source>App password</source>
<target>App password</target>
</trans-unit>
<trans-unit id="sfe211545fd02f73e">
<source>Verification</source>
<target>Verification</target>
</trans-unit>
<trans-unit id="sd73b202ec04eefd9">
<source>Unknown intent</source>
<target>Unknown intent</target>
</trans-unit>
<trans-unit id="s78fd8c03f8c967f3">
<source>Tokens</source>
<target>Tokens</target>
</trans-unit>
<trans-unit id="sdcc7b2c109ce9775">
<source>Tokens are used throughout authentik for Email validation stages, Recovery keys and API access.</source>
<target>Tokens are used throughout authentik for Email validation stages, Recovery keys and API access.</target>
</trans-unit>
<trans-unit id="sf71dba2c30283a54">
<source>Expires?</source>
<target>Expires?</target>
</trans-unit>
<trans-unit id="sc7be80a7f8ec597e">
<source>Expiry date</source>
<target>Expiry date</target>
</trans-unit>
<trans-unit id="s71dcd9cf808449aa">
<source>Token(s)</source>
<target>Token(s)</target>
</trans-unit>
<trans-unit id="sb15e8daacf26bdfc">
<source>Create Token</source>
<target>Create Token</target>
</trans-unit>
<trans-unit id="s8d7ecd944ebe834b">
<source>Token is managed by authentik.</source>
<target>Token is managed by authentik.</target>
</trans-unit>
<trans-unit id="sd1288ca57e221cf9">
<source>Update Token</source>
<target>Update Token</target>
</trans-unit>
<trans-unit id="s0af6301e76e2a2a5">
<source>Successfully updated tenant.</source>
<target>Successfully updated tenant.</target>
</trans-unit>
<trans-unit id="sf55c7c06dbc2c8c6">
<source>Successfully created tenant.</source>
<target>Successfully created tenant.</target>
</trans-unit>
<trans-unit id="s41706a202b6c40f1">
<source>Domain</source>
<target>Domain</target>
</trans-unit>
<trans-unit id="se74ce42d41e392ba">
<source>Matching is done based on domain suffix, so if you enter domain.tld, foo.domain.tld will still match.</source>
<target>Matching is done based on domain suffix, so if you enter domain.tld, foo.domain.tld will still match.</target>
</trans-unit>
<trans-unit id="s11326fd2590f4e5e">
<source>Default</source>
<target>Default</target>
</trans-unit>
<trans-unit id="se1c85959463f53df">
<source>Use this tenant for each domain that doesn't have a dedicated tenant.</source>
<target>Use this tenant for each domain that doesn't have a dedicated tenant.</target>
</trans-unit>
<trans-unit id="sc19838ca8c135c1b">
<source>Branding settings</source>
<target>Branding settings</target>
</trans-unit>
<trans-unit id="s99f110d27e30b289">
<source>Title</source>
<target>Title</target>
</trans-unit>
<trans-unit id="sab6bad52985c6676">
<source>Branding shown in page title and several other places.</source>
<target>Branding shown in page title and several other places.</target>
</trans-unit>
<trans-unit id="s4f1af2b48a5e249a">
<source>Logo</source>
<target>Logo</target>
</trans-unit>
<trans-unit id="sd6b8b4156f7df696">
<source>Icon shown in sidebar/header and flow executor.</source>
<target>Icon shown in sidebar/header and flow executor.</target>
</trans-unit>
<trans-unit id="s3626433940124897">
<source>Favicon</source>
<target>Favicon</target>
</trans-unit>
<trans-unit id="se99efc0873031976">
<source>Icon shown in the browser tab.</source>
<target>Icon shown in the browser tab.</target>
</trans-unit>
<trans-unit id="s10356fd921037fbf">
<source>Default flows</source>
<target>Default flows</target>
</trans-unit>
<trans-unit id="sd216b08bafb297ee">
<source>Flow used to authenticate users. If left empty, the first applicable flow sorted by the slug is used.</source>
<target>Flow used to authenticate users. If left empty, the first applicable flow sorted by the slug is used.</target>
</trans-unit>
<trans-unit id="s35e6e60e83a8c003">
<source>Invalidation flow</source>
<target>Invalidation flow</target>
</trans-unit>
<trans-unit id="s7989db5f4819af89">
<source>Flow used to logout. If left empty, the first applicable flow sorted by the slug is used.</source>
<target>Flow used to logout. If left empty, the first applicable flow sorted by the slug is used.</target>
</trans-unit>
<trans-unit id="sfeb779d4ccbc5a0e">
<source>Recovery flow</source>
<target>Recovery flow</target>
</trans-unit>
<trans-unit id="s1c2fd8097e14a608">
<source>Recovery flow. If left empty, the first applicable flow sorted by the slug is used.</source>
<target>Recovery flow. If left empty, the first applicable flow sorted by the slug is used.</target>
</trans-unit>
<trans-unit id="s836aa192b30c21da">
<source>Unenrollment flow</source>
<target>Unenrollment flow</target>
</trans-unit>
<trans-unit id="s081d3c4b47a6ff83">
<source>If set, users are able to unenroll themselves using this flow. If no flow is set, option is not shown.</source>
<target>If set, users are able to unenroll themselves using this flow. If no flow is set, option is not shown.</target>
</trans-unit>
<trans-unit id="secbfd13bdae95a59">
<source>User settings flow</source>
<target>User settings flow</target>
</trans-unit>
<trans-unit id="s523160b433311521">
<source>If set, users are able to configure details of their profile.</source>
<target>If set, users are able to configure details of their profile.</target>
</trans-unit>
<trans-unit id="s134177568525dbc8">
<source>Device code flow</source>
<target>Device code flow</target>
</trans-unit>
<trans-unit id="s7b298427bdea81ae">
<source>If set, the OAuth Device Code profile can be used, and the selected flow will be used to enter the code.</source>
<target>If set, the OAuth Device Code profile can be used, and the selected flow will be used to enter the code.</target>
</trans-unit>
<trans-unit id="s7f4e4054fbe132e1">
<source>Other global settings</source>
<target>Other global settings</target>
</trans-unit>
<trans-unit id="sbadde673052efc02">
<source>Web Certificate</source>
<target>Web Certificate</target>
</trans-unit>
<trans-unit id="s84c5a011acd608c9">
<source>Event retention</source>
<target>Event retention</target>
</trans-unit>
<trans-unit id="s2536ac8d32d2e63f">
<source>Duration after which events will be deleted from the database.</source>
<target>Duration after which events will be deleted from the database.</target>
</trans-unit>
<trans-unit id="s7b1fba26d245cb1c">
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
<target>When using an external logging solution for archiving, this can be set to "minutes=5".</target>
</trans-unit>
<trans-unit id="s44536d20bb5c8257">
<source>This setting only affects new Events, as the expiration is saved per-event.</source>
<target>This setting only affects new Events, as the expiration is saved per-event.</target>
</trans-unit>
<trans-unit id="s3bb51cabb02b997e">
<source>Format: "weeks=3;days=2;hours=3,seconds=2".</source>
<target>Format: "weeks=3;days=2;hours=3,seconds=2".</target>
</trans-unit>
<trans-unit id="s04bfd02201db5ab8">
<source>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</source>
<target>Set custom attributes using YAML or JSON. Any attributes set here will be inherited by users, if the request is handled by this tenant.</target>
</trans-unit>
<trans-unit id="s7f9e79189a3d19e2">
<source>Tenants</source>
<target>Tenants</target>
</trans-unit>
<trans-unit id="s164be9a7537b99f6">
<source>Configure visual settings and defaults for different domains.</source>
<target>Configure visual settings and defaults for different domains.</target>
</trans-unit>
<trans-unit id="s4802636d55022ed3">
<source>Default?</source>
<target>Default?</target>
</trans-unit>
<trans-unit id="s69a56a3022c4be7f">
<source>Tenant(s)</source>
<target>Tenant(s)</target>
</trans-unit>
<trans-unit id="s1b606acd76ba2c4c">
<source>Update Tenant</source>
<target>Update Tenant</target>
</trans-unit>
<trans-unit id="s773aa6621d7e37b7">
<source>Create Tenant</source>
<target>Create Tenant</target>
</trans-unit>
<trans-unit id="s8cb7bb82e96d5d77">
<source>Policies</source>
<target>Policies</target>
</trans-unit>
<trans-unit id="sec1808532fe107b9">
<source>Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages.</source>
<target>Allow users to use Applications based on properties, enforce Password Criteria and selectively apply Stages.</target>
</trans-unit>
<trans-unit id="se16ac750b81fa93d">
<source>Assigned to <x id="0" equiv-text="${item.boundTo}"/> object(s).</source>
<target>Assigned to
<x id="0" equiv-text="${item.boundTo}"/>object(s).</target>
</trans-unit>
<trans-unit id="s5a48d5171e1a1522">
<source>Warning: Policy is not assigned.</source>
<target>Warning: Policy is not assigned.</target>
</trans-unit>
<trans-unit id="s544142ce35050751">
<source>Test Policy</source>
<target>Test Policy</target>
</trans-unit>
<trans-unit id="s00c8354318addfa0">
<source>Policy / Policies</source>
<target>Policy / Policies</target>
</trans-unit>
<trans-unit id="s76da2c978dcc5ef4">
<source>Successfully cleared policy cache</source>
<target>Successfully cleared policy cache</target>
</trans-unit>
<trans-unit id="sa717841a602fe7d8">
<source>Failed to delete policy cache</source>
<target>Failed to delete policy cache</target>
</trans-unit>
<trans-unit id="s3ed5607ad78d4224">
<source>Clear cache</source>
<target>Clear cache</target>
</trans-unit>
<trans-unit id="s1b07757762cda372">
<source>Clear Policy cache</source>
<target>Clear Policy cache</target>
</trans-unit>
<trans-unit id="s15b46b78edebb20a">
<source>Are you sure you want to clear the policy cache? This will cause all policies to be re-evaluated on their next usage.</source>
</trans-unit>
<trans-unit id="s62ddcbaaa91d120d">
<source>Reputation scores</source>
<target>Reputation scores</target>
</trans-unit>
<trans-unit id="sd080b2370aa82967">
<source>Reputation for IP and user identifiers. Scores are decreased for each failed login and increased for each successful login.</source>
<target>Reputation for IP and user identifiers. Scores are decreased for each failed login and increased for each successful login.</target>
</trans-unit>
<trans-unit id="s09242207b5b8f83c">
<source>IP</source>
<target>IP</target>
</trans-unit>
<trans-unit id="s7d684b6257284e55">
<source>Score</source>
<target>Score</target>
</trans-unit>
<trans-unit id="s10d2dbc4613397f0">
<source>Updated</source>
<target>Updated</target>
</trans-unit>
<trans-unit id="sa33d061d2ade20aa">
<source>Reputation</source>
<target>Reputation</target>
</trans-unit>
<trans-unit id="s9f26843287bb592d">
<source>Groups</source>
<target>Groups</target>
</trans-unit>
<trans-unit id="s4dcb9288f7e9e4d7">
<source>Group users together and give them permissions based on the membership.</source>
<target>Group users together and give them permissions based on the membership.</target>
</trans-unit>
<trans-unit id="s62f93cfcb45d5a06">
<source>Superuser privileges?</source>
<target>Superuser privileges?</target>
</trans-unit>
<trans-unit id="s9fdda7ea4642306c">
<source>Group(s)</source>
<target>Group(s)</target>
</trans-unit>
<trans-unit id="s416a540b16275f2e">
<source>Create Group</source>
<target>Create Group</target>
</trans-unit>
<trans-unit id="s7c5774fad9d050ce">
<source>Create group</source>
<target>Create group</target>
</trans-unit>
<trans-unit id="s2a12e0b5527ff99a">
<source>Enabling this toggle will create a group named after the user, with the user as member.</source>
<target>Enabling this toggle will create a group named after the user, with the user as member.</target>
</trans-unit>
<trans-unit id="s6b6e6eb037aef7da">
<source>Use the username and password below to authenticate. The password can be retrieved later on the Tokens page.</source>
<target>Use the username and password below to authenticate. The password can be retrieved later on the Tokens page.</target>
</trans-unit>
<trans-unit id="sf6e1665c7022a1f8">
<source>Password</source>
<target>Password</target>
</trans-unit>
<trans-unit id="sbb57cd8a3ed12915">
<source>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</source>
<target>Valid for 360 days, after which the password will automatically rotate. You can copy the password from the Token List.</target>
</trans-unit>
<trans-unit id="s4414164d120de61a">
<source>The following objects use <x id="0" equiv-text="${objName}"/></source>
<target>The following objects use
<x id="0" equiv-text="${objName}"/></target>
</trans-unit>
<trans-unit id="s92e241c9f3c101a2">
<source>connecting object will be deleted</source>
<target>connecting object will be deleted</target>
</trans-unit>
<trans-unit id="se6a13beff646557b">
<source>Successfully updated <x id="0" equiv-text="${this.objectLabel} ${this.obj?.name}"/></source>
</trans-unit>
<trans-unit id="s14401ff4a0cba208">
<source>Failed to update <x id="0" equiv-text="${this.objectLabel}"/>: <x id="1" equiv-text="${e.toString()}"/></source>
<target>Failed to update
<x id="0" equiv-text="${this.objectLabel}"/>:
<x id="1" equiv-text="${e.toString()}"/></target>
</trans-unit>
<trans-unit id="sa95a538bfbb86111">
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
<target>Are you sure you want to update
<x id="0" equiv-text="${this.objectLabel}"/>"
<x id="1" equiv-text="${this.obj?.name}"/>"?</target>
</trans-unit>
<trans-unit id="sc92d7cfb6ee1fec6">
<source>Successfully updated password.</source>
<target>Successfully updated password.</target>
</trans-unit>
<trans-unit id="se5498954255620b4">
<source>Successfully sent email.</source>
<target>Successfully sent email.</target>
</trans-unit>
<trans-unit id="s44ea4e9a81ce730d">
<source>Email stage</source>
<target>Email stage</target>
</trans-unit>
<trans-unit id="sdb53ccdd6174e6e3">
<source>Successfully added user(s).</source>
<target>Successfully added user(s).</target>
</trans-unit>
<trans-unit id="s306a35df5d0d38bb">
<source>Users to add</source>
<target>Users to add</target>
</trans-unit>
<trans-unit id="s7d499be3b781a3ca">
<source>User(s)</source>
<target>User(s)</target>
</trans-unit>
<trans-unit id="s7220fcf4fec4e0df">
<source>Remove Users(s)</source>
<target>Remove Users(s)</target>
</trans-unit>
<trans-unit id="s5d7748b1d2363478">
<source>Are you sure you want to remove the selected users from the group <x id="0" equiv-text="${this.targetGroup?.name}"/>?</source>
<target>Are you sure you want to remove the selected users from the group
<x id="0" equiv-text="${this.targetGroup?.name}"/>?</target>
</trans-unit>
<trans-unit id="sea4f08110bb8f15d">
<source>Remove</source>
<target>Remove</target>
</trans-unit>
<trans-unit id="sf466142da6a65052">
<source>Impersonate</source>
<target>Impersonate</target>
</trans-unit>
<trans-unit id="s58888ef1ee9b5bb8">
<source>User status</source>
<target>User status</target>
</trans-unit>
<trans-unit id="sf9e61f4f8e90f0f1">
<source>Change status</source>
<target>Change status</target>
</trans-unit>
<trans-unit id="sf56998949bdf6b33">
<source>Deactivate</source>
<target>Deactivate</target>
</trans-unit>
<trans-unit id="s3794c596ee7964ad">
<source>Update password</source>
<target>Update password</target>
</trans-unit>
<trans-unit id="sce8d867ca5f35304">
<source>Set password</source>
<target>Set password</target>
</trans-unit>
<trans-unit id="s0ae3395d8f48e624">
<source>Successfully generated recovery link</source>
<target>Successfully generated recovery link</target>
</trans-unit>
<trans-unit id="s8ca0dbaec5d48563">
<source>No recovery flow is configured.</source>
<target>No recovery flow is configured.</target>
</trans-unit>
<trans-unit id="sb69119c9f0547bed">
<source>Copy recovery link</source>
<target>Copy recovery link</target>
</trans-unit>
<trans-unit id="s7fa236d26b798301">
<source>Send link</source>
<target>Send link</target>
</trans-unit>
<trans-unit id="sa9dbe2fb284e26fe">
<source>Send recovery link to user</source>
<target>Send recovery link to user</target>
</trans-unit>
<trans-unit id="s03fd2c252ad7972a">
<source>Email recovery link</source>
<target>Email recovery link</target>
</trans-unit>
<trans-unit id="sd7fa99e4d82b374a">
<source>Recovery link cannot be emailed, user has no email address saved.</source>
<target>Recovery link cannot be emailed, user has no email address saved.</target>
</trans-unit>
<trans-unit id="s63d89a6ae0969c30">
<source>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</source>
<target>To let a user directly reset a their password, configure a recovery flow on the currently active tenant.</target>
</trans-unit>
<trans-unit id="s720594461542943f">
<source>Add User</source>
<target>Add User</target>
</trans-unit>
<trans-unit id="s4c41f3f4c23e8eaa">
<source>Warning: This group is configured with superuser access. Added users will have superuser access.</source>
<target>Warning: This group is configured with superuser access. Added users will have superuser access.</target>
</trans-unit>
<trans-unit id="scee721983b1c28d0">
<source>Add existing user</source>
<target>Add existing user</target>
</trans-unit>
<trans-unit id="sd600334ec2c39b74">
<source>Create user</source>
<target>Create user</target>
</trans-unit>
<trans-unit id="s53ad3455d9523b54">
<source>Create User</source>
<target>Create User</target>
</trans-unit>
<trans-unit id="s06c163334767a381">
<source>Create Service account</source>
<target>Create Service account</target>
</trans-unit>
<trans-unit id="sc744f3691efe310d">
<source>Hide service-accounts</source>
<target>Hide service-accounts</target>
</trans-unit>
<trans-unit id="secdb4b4c4e66aa38">
<source>Group Info</source>
<target>Group Info</target>
</trans-unit>
<trans-unit id="s005053d82b712e0a">
<source>Notes</source>
<target>Notes</target>
</trans-unit>
<trans-unit id="s634448e4942cf452">
<source>Edit the notes attribute of this group to add notes here.</source>
<target>Edit the notes attribute of this group to add notes here.</target>
</trans-unit>
<trans-unit id="s586d6bd2eca2da93">
<source>Users</source>
<target>Users</target>
</trans-unit>
<trans-unit id="sca7cfe2bef51b2a5">
<source>Root</source>
<target>Root</target>
</trans-unit>
<trans-unit id="s3616cc78631f5893">
<source>Warning: You're about to delete the user you're logged in as (<x id="0" equiv-text="${shouldShowWarning.username}"/>). Proceed at your own risk.</source>
<target>Warning: You're about to delete the user you're logged in as (
<x id="0" equiv-text="${shouldShowWarning.username}"/>). Proceed at your own risk.</target>
</trans-unit>
<trans-unit id="s510c7add9e24c306">
<source>Hide deactivated user</source>
<target>Hide deactivated user</target>
</trans-unit>
<trans-unit id="s94055b4eb957dc8f">
<source>User folders</source>
<target>User folders</target>
</trans-unit>
<trans-unit id="sa982875b258fea07">
<source>Successfully added user to group(s).</source>
<target>Successfully added user to group(s).</target>
</trans-unit>
<trans-unit id="s1bd5920d8adf2bd5">
<source>Groups to add</source>
<target>Groups to add</target>
</trans-unit>
<trans-unit id="s5f71fa3c53828e30">
<source>Remove from Group(s)</source>
<target>Remove from Group(s)</target>
</trans-unit>
<trans-unit id="sb4c9ed2a487b238f">
<source>Are you sure you want to remove user <x id="0" equiv-text="${this.targetUser?.username}"/> from the following groups?</source>
<target>Are you sure you want to remove user
<x id="0" equiv-text="${this.targetUser?.username}"/>from the following groups?</target>
</trans-unit>
<trans-unit id="s964f6725aeb7662f">
<source>Add Group</source>
<target>Add Group</target>
</trans-unit>
<trans-unit id="s65ca2f256ea09c11">
<source>Add to existing group</source>
<target>Add to existing group</target>
</trans-unit>
<trans-unit id="s505fbbdcbc6aa921">
<source>Add new group</source>
<target>Add new group</target>
</trans-unit>
<trans-unit id="s506beb486fa41241">
<source>Application authorizations</source>
<target>Application authorizations</target>
</trans-unit>
<trans-unit id="s7301a7069b7bc83e">
<source>Revoked?</source>
<target>Revoked?</target>
</trans-unit>
<trans-unit id="sd924045605feea63">
<source>Expires</source>
<target>Expires</target>
</trans-unit>
<trans-unit id="s1c8916418c334935">
<source>ID Token</source>
<target>ID Token</target>
</trans-unit>
<trans-unit id="s90760e5e02e95dfe">
<source>Refresh Tokens(s)</source>
<target>Refresh Tokens(s)</target>
</trans-unit>
<trans-unit id="s1b88fa3df4423292">
<source>Last IP</source>
<target>Last IP</target>
</trans-unit>
<trans-unit id="se63f9d833700af49">
<source>Session(s)</source>
<target>Session(s)</target>
</trans-unit>
<trans-unit id="sf679b7a62808287e">
<source>Expiry</source>
<target>Expiry</target>
</trans-unit>
<trans-unit id="sde1907073fd96017">
<source>(Current session)</source>
<target>(Current session)</target>
</trans-unit>
<trans-unit id="se8dca0132c66ae03">
<source>Permissions</source>
<target>Permissions</target>
</trans-unit>
<trans-unit id="s76881c01b6a3a8c7">
<source>Consent(s)</source>
<target>Consent(s)</target>
</trans-unit>
<trans-unit id="sea2f00b34b385a43">
<source>Successfully updated device.</source>
<target>Successfully updated device.</target>
</trans-unit>
<trans-unit id="s858e7ac4b3cf955f">
<source>Static tokens</source>
<target>Static tokens</target>
</trans-unit>
<trans-unit id="sfcfcf85a57eea78a">
<source>TOTP Device</source>
<target>TOTP Device</target>
</trans-unit>
<trans-unit id="s6a406aecb2c0e5c5">
<source>Enroll</source>
<target>Enroll</target>
</trans-unit>
<trans-unit id="sa0b01f479f40c52d">
<source>Device(s)</source>
<target>Device(s)</target>
</trans-unit>
<trans-unit id="sabb56f74492e7e96">
<source>Update Device</source>
<target>Update Device</target>
</trans-unit>
<trans-unit id="sf05c700a1250824e">
<source>Confirmed</source>
<target>Confirmed</target>
</trans-unit>
<trans-unit id="s64a33dcdaf90af26">
<source>User Info</source>
<target>User Info</target>
</trans-unit>
<trans-unit id="sc44bae5cde0083fa">
<source>Actions over the last week (per 8 hours)</source>
<target>Actions over the last week (per 8 hours)</target>
</trans-unit>
<trans-unit id="sb57dbcda1929c642">
<source>Edit the notes attribute of this user to add notes here.</source>
<target>Edit the notes attribute of this user to add notes here.</target>
</trans-unit>
<trans-unit id="s5c18cae48b93138c">
<source>Sessions</source>
<target>Sessions</target>
</trans-unit>
<trans-unit id="s27586544c447d9e3">
<source>User events</source>
<target>User events</target>
</trans-unit>
<trans-unit id="s4d31797d81e9cea3">
<source>Explicit Consent</source>
<target>Explicit Consent</target>
</trans-unit>
<trans-unit id="sb6770fa90be6d8b3">
<source>OAuth Refresh Tokens</source>
<target>OAuth Refresh Tokens</target>
</trans-unit>
<trans-unit id="s28b3de1561da72b3">
<source>MFA Authenticators</source>
<target>MFA Authenticators</target>
</trans-unit>
<trans-unit id="s7a322c89298dd27c">
<source>Successfully updated invitation.</source>
<target>Successfully updated invitation.</target>
</trans-unit>
<trans-unit id="sc554339ffc7b04e7">
<source>Successfully created invitation.</source>
<target>Successfully created invitation.</target>
</trans-unit>
<trans-unit id="sfcebd18506f1e535">
<source>Flow</source>
<target>Flow</target>
</trans-unit>
<trans-unit id="sa84a7fd11ba85e88">
<source>When selected, the invite will only be usable with the flow. By default the invite is accepted on all flows with invitation stages.</source>
<target>When selected, the invite will only be usable with the flow. By default the invite is accepted on all flows with invitation stages.</target>
</trans-unit>
<trans-unit id="s7520286c8419a266">
<source>Optional data which is loaded into the flow's 'prompt_data' context variable. YAML or JSON.</source>
<target>Optional data which is loaded into the flow's 'prompt_data' context variable. YAML or JSON.</target>
</trans-unit>
<trans-unit id="sb8795b799c70776a">
<source>Single use</source>
<target>Single use</target>
</trans-unit>
<trans-unit id="sf232d42142eacc23">
<source>When enabled, the invitation will be deleted after usage.</source>
<target>When enabled, the invitation will be deleted after usage.</target>
</trans-unit>
<trans-unit id="sa4a8086275475714">
<source>Select an enrollment flow</source>
<target>Select an enrollment flow</target>
</trans-unit>
<trans-unit id="s839cb09cb2193da9">
<source>Link to use the invitation.</source>
<target>Link to use the invitation.</target>
</trans-unit>
<trans-unit id="s8226f48cb1a80997">
<source>Invitations</source>
<target>Invitations</target>
</trans-unit>
<trans-unit id="s57448f10eb973100">
<source>Create Invitation Links to enroll Users, and optionally force specific attributes of their account.</source>
<target>Create Invitation Links to enroll Users, and optionally force specific attributes of their account.</target>
</trans-unit>
<trans-unit id="s4aee34a672e5cfc0">
<source>Created by</source>
<target>Created by</target>
</trans-unit>
<trans-unit id="sd5ba2d61ee4796fe">
<source>Invitation(s)</source>
<target>Invitation(s)</target>
</trans-unit>
<trans-unit id="s96dcf7ec8342c335">
<source>Invitation not limited to any flow, and can be used with any enrollment flow.</source>
<target>Invitation not limited to any flow, and can be used with any enrollment flow.</target>
</trans-unit>
<trans-unit id="s1b42b49e7b392013">
<source>Update Invitation</source>
<target>Update Invitation</target>
</trans-unit>
<trans-unit id="s38c72e1cf120b8d8">
<source>Create Invitation</source>
<target>Create Invitation</target>
</trans-unit>
<trans-unit id="s802826db4e2c852e">
<source>Warning: No invitation stage is bound to any flow. Invitations will not work as expected.</source>
<target>Warning: No invitation stage is bound to any flow. Invitations will not work as expected.</target>
</trans-unit>
<trans-unit id="s2f995efbb1e46b18">
<source>Auto-detect (based on your browser)</source>
<target>Auto-detect (based on your browser)</target>
</trans-unit>
<trans-unit id="s296fbffaaa7c910a">
<source>Required.</source>
<target>Required.</target>
</trans-unit>
<trans-unit id="s81ecf2d4386b8e84">
<source>Continue</source>
<target>Continue</target>
</trans-unit>
<trans-unit id="s8b2b2a43fcf688a3">
<source>Successfully updated prompt.</source>
<target>Successfully updated prompt.</target>
</trans-unit>
<trans-unit id="s5572ac4d2208f5ec">
<source>Successfully created prompt.</source>
<target>Successfully created prompt.</target>
</trans-unit>
<trans-unit id="s54e7a23a95d99649">
<source>Text: Simple Text input</source>
<target>Text: Simple Text input</target>
</trans-unit>
<trans-unit id="s63e54b86e2a2cc43">
<source>Text Area: Multiline text input</source>
<target>Text Area: Multiline text input</target>
</trans-unit>
<trans-unit id="s12de1c06a1e18cc5">
<source>Text (read-only): Simple Text input, but cannot be edited.</source>
<target>Text (read-only): Simple Text input, but cannot be edited.</target>
</trans-unit>
<trans-unit id="s4e5646b23e41231f">
<source>Text Area (read-only): Multiline text input, but cannot be edited.</source>
<target>Text Area (read-only): Multiline text input, but cannot be edited.</target>
</trans-unit>
<trans-unit id="s1e4c3de6e12cd87b">
<source>Username: Same as Text input, but checks for and prevents duplicate usernames.</source>
<target>Username: Same as Text input, but checks for and prevents duplicate usernames.</target>
</trans-unit>
<trans-unit id="s5462c7f56ed65e6c">
<source>Email: Text field with Email type.</source>
<target>Email: Text field with Email type.</target>
</trans-unit>
<trans-unit id="s1c5574968b29ab1c">
<source>Password: Masked input, multiple inputs of this type on the same prompt need to be identical.</source>
<target>Password: Masked input, multiple inputs of this type on the same prompt need to be identical.</target>
</trans-unit>
<trans-unit id="sbbb97b1c63507dc0">
<source>Number</source>
<target>Number</target>
</trans-unit>
<trans-unit id="sdae649fae731e838">
<source>Checkbox</source>
<target>Checkbox</target>
</trans-unit>
<trans-unit id="s34edeb18f887161d">
<source>Radio Button Group (fixed choice)</source>
<target>Radio Button Group (fixed choice)</target>
</trans-unit>
<trans-unit id="s57730b6870e8916c">
<source>Dropdown (fixed choice)</source>
<target>Dropdown (fixed choice)</target>
</trans-unit>
<trans-unit id="sac8252732f2edb19">
<source>Date</source>
<target>Date</target>
</trans-unit>
<trans-unit id="s45960273852a61b2">
<source>Date Time</source>
<target>Date Time</target>
</trans-unit>
<trans-unit id="sd1f81284eeb7b503">
<source>File</source>
<target>File</target>
</trans-unit>
<trans-unit id="s21e3c227cc2c5873">
<source>Separator: Static Separator Line</source>
<target>Separator: Static Separator Line</target>
</trans-unit>
<trans-unit id="s706af57c1af42c6d">
<source>Hidden: Hidden field, can be used to insert data into form.</source>
<target>Hidden: Hidden field, can be used to insert data into form.</target>
</trans-unit>
<trans-unit id="s40e2c72dae905a50">
<source>Static: Static value, displayed as-is.</source>
<target>Static: Static value, displayed as-is.</target>
</trans-unit>
<trans-unit id="sdd4bd4224c4e943d">
<source>authentik: Locale: Displays a list of locales authentik supports.</source>
<target>authentik: Locale: Displays a list of locales authentik supports.</target>
</trans-unit>
<trans-unit id="saf84e7732a9e1336">
<source>Preview errors</source>
<target>Preview errors</target>
</trans-unit>
<trans-unit id="sb71ace8e9b35c749">
<source>Data preview</source>
<target>Data preview</target>
</trans-unit>
<trans-unit id="s4d53f4b7ff33bedd">
<source>Unique name of this field, used for selecting fields in prompt stages.</source>
<target>Unique name of this field, used for selecting fields in prompt stages.</target>
</trans-unit>
<trans-unit id="s3b58f8d2155ae90c">
<source>Field Key</source>
<target>Field Key</target>
</trans-unit>
<trans-unit id="s2b088ba65eb69b7e">
<source>Name of the form field, also used to store the value.</source>
<target>Name of the form field, also used to store the value.</target>
</trans-unit>
<trans-unit id="s662fcb3761ad9df7">
<source>When used in conjunction with a User Write stage, use attributes.foo to write attributes.</source>
<target>When used in conjunction with a User Write stage, use attributes.foo to write attributes.</target>
</trans-unit>
<trans-unit id="s5590dbf7e425789d">
<source>Label</source>
<target>Label</target>
</trans-unit>
<trans-unit id="s0c135eba6017d94f">
<source>Label shown next to/above the prompt.</source>
<target>Label shown next to/above the prompt.</target>
</trans-unit>
<trans-unit id="sae5d87e99fe081e0">
<source>Required</source>
<target>Required</target>
</trans-unit>
<trans-unit id="s37dbfe2133b74d2d">
<source>Interpret placeholder as expression</source>
<target>Interpret placeholder as expression</target>
</trans-unit>
<trans-unit id="s4a953e6234cb4808">
<source>When checked, the placeholder will be evaluated in the same way a property mapping is.
If the evaluation fails, the placeholder itself is returned.</source>
</trans-unit>
<trans-unit id="sf90be97cb08f3d5a">
<source>Placeholder</source>
<target>Placeholder</target>
</trans-unit>
<trans-unit id="sf76ead4c4708dd06">
<source>Optionally provide a short hint that describes the expected input value.
When creating a fixed choice field, enable interpreting as expression and return a
list to return multiple choices.</source>
</trans-unit>
<trans-unit id="saa7ba2057bd524a1">
<source>Interpret initial value as expression</source>
<target>Interpret initial value as expression</target>
</trans-unit>
<trans-unit id="sd60415c7666859f0">
<source>When checked, the initial value will be evaluated in the same way a property mapping is.
If the evaluation fails, the initial value itself is returned.</source>
</trans-unit>
<trans-unit id="sa9c7044d9fd1f3e6">
<source>Initial value</source>
<target>Initial value</target>
</trans-unit>
<trans-unit id="seab35681cbf36755">
<source>Optionally pre-fill the input with an initial value.
When creating a fixed choice field, enable interpreting as expression and
return a list to return multiple default choices.</source>
</trans-unit>
<trans-unit id="s72c1c17a9bdc76ad">
<source>Help text</source>
<target>Help text</target>
</trans-unit>
<trans-unit id="s584d1c38ad20d560">
<source>Any HTML can be used.</source>
<target>Any HTML can be used.</target>
</trans-unit>
<trans-unit id="s2be6121210e2a2f8">
<source>Prompts</source>
<target>Prompts</target>
</trans-unit>
<trans-unit id="s42fc6f4b64eff5d9">
<source>Single Prompts that can be used for Prompt Stages.</source>
<target>Single Prompts that can be used for Prompt Stages.</target>
</trans-unit>
<trans-unit id="s42a1ebe17efda727">
<source>Field</source>
<target>Field</target>
</trans-unit>
<trans-unit id="s41b105819b67ee7a">
<source>Stages</source>
<target>Stages</target>
</trans-unit>
<trans-unit id="sec7443a45fd141e5">
<source>Prompt(s)</source>
<target>Prompt(s)</target>
</trans-unit>
<trans-unit id="scc733ba98740038a">
<source>Update Prompt</source>
<target>Update Prompt</target>
</trans-unit>
<trans-unit id="s61b6f3e6bc59c6dd">
<source>Create Prompt</source>
<target>Create Prompt</target>
</trans-unit>
<trans-unit id="sff5bb7742c2896c8">
<source>Target</source>
<target>Target</target>
</trans-unit>
<trans-unit id="sae5da213b7f896ed">
<source>Stage</source>
<target>Stage</target>
</trans-unit>
<trans-unit id="s0a61796c1956d32c">
<source>Evaluate when flow is planned</source>
<target>Evaluate when flow is planned</target>
</trans-unit>
<trans-unit id="sf533f13321fee530">
<source>Evaluate policies during the Flow planning process.</source>
<target>Evaluate policies during the Flow planning process.</target>
</trans-unit>
<trans-unit id="s6336fa345e96dde9">
<source>Evaluate when stage is run</source>
<target>Evaluate when stage is run</target>
</trans-unit>
<trans-unit id="sff3b708e23bb96b2">
<source>Evaluate policies before the Stage is present to the user.</source>
<target>Evaluate policies before the Stage is present to the user.</target>
</trans-unit>
<trans-unit id="s0dc46deb8f181baf">
<source>Invalid response behavior</source>
<target>Invalid response behavior</target>
</trans-unit>
<trans-unit id="seb0805249661d15b">
<source>Returns the error message and a similar challenge to the executor</source>
<target>Returns the error message and a similar challenge to the executor</target>
</trans-unit>
<trans-unit id="sd891d8463d0ebace">
<source>Restarts the flow from the beginning</source>
<target>Restarts the flow from the beginning</target>
</trans-unit>
<trans-unit id="s6b9a1dd402750a8a">
<source>Restarts the flow from the beginning, while keeping the flow context</source>
<target>Restarts the flow from the beginning, while keeping the flow context</target>
</trans-unit>
<trans-unit id="sbc88fb27a4c3b894">
<source>Configure how the flow executor should handle an invalid response to a challenge given by this bound stage.</source>
<target>Configure how the flow executor should handle an invalid response to a challenge given by this bound stage.</target>
</trans-unit>
<trans-unit id="s916b32ac64ea2b05">
<source>Successfully updated stage.</source>
<target>Successfully updated stage.</target>
</trans-unit>
<trans-unit id="s14c8f36e180d6bbc">
<source>Successfully created stage.</source>
<target>Successfully created stage.</target>
</trans-unit>
<trans-unit id="sf22a28f83cc45fcc">
<source>Stage used to configure a duo-based authenticator. This stage should be used for configuration flows.</source>
<target>Stage used to configure a duo-based authenticator. This stage should be used for configuration flows.</target>
</trans-unit>
<trans-unit id="s5adafce329aaa853">
<source>Authenticator type name</source>
<target>Authenticator type name</target>
</trans-unit>
<trans-unit id="s23e6a57201fba25e">
<source>Display name of this authenticator, used by users when they enroll an authenticator.</source>
<target>Display name of this authenticator, used by users when they enroll an authenticator.</target>
</trans-unit>
<trans-unit id="s276d751eb7a186cc">
<source>API Hostname</source>
<target>API Hostname</target>
</trans-unit>
<trans-unit id="s5b6b6e2cb884d59f">
<source>Duo Auth API</source>
<target>Duo Auth API</target>
</trans-unit>
<trans-unit id="s240ff02ce3a53dee">
<source>Integration key</source>
<target>Integration key</target>
</trans-unit>
<trans-unit id="s56fd9ed596c724fa">
<source>Secret key</source>
<target>Secret key</target>
</trans-unit>
<trans-unit id="s88870d7e499e848b">
<source>Duo Admin API (optional)</source>
<target>Duo Admin API (optional)</target>
</trans-unit>
<trans-unit id="s7f13f4a2d0370cf6">
<source>When using a Duo MFA, Access or Beyond plan, an Admin API application can be created.
This will allow authentik to import devices automatically.</source>
</trans-unit>
<trans-unit id="s9a34d1520e320465">
<source>Stage-specific settings</source>
<target>Stage-specific settings</target>
</trans-unit>
<trans-unit id="s0dfc6838c9d07677">
<source>Configuration flow</source>
<target>Configuration flow</target>
</trans-unit>
<trans-unit id="sebf44d2471b608ad">
<source>Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage.</source>
<target>Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage.</target>
</trans-unit>
<trans-unit id="s3baf512851453712">
<source>Twilio Account SID</source>
<target>Twilio Account SID</target>
</trans-unit>
<trans-unit id="sa738ce390bc24875">
<source>Get this value from https://console.twilio.com</source>
<target>Get this value from https://console.twilio.com</target>
</trans-unit>
<trans-unit id="sa7b56a80ab1801f0">
<source>Twilio Auth Token</source>
<target>Twilio Auth Token</target>
</trans-unit>
<trans-unit id="sfe99a8caa70232ab">
<source>Authentication Type</source>
<target>Authentication Type</target>
</trans-unit>
<trans-unit id="safd0363143a46a91">
<source>Basic Auth</source>
<target>Basic Auth</target>
</trans-unit>
<trans-unit id="sd06b47084fec0ec5">
<source>Bearer Token</source>
<target>Bearer Token</target>
</trans-unit>
<trans-unit id="sb1751a1411d6874f">
<source>External API URL</source>
<target>External API URL</target>
</trans-unit>
<trans-unit id="sbdc1176ff9f93da2">
<source>This is the full endpoint to send POST requests to.</source>
<target>This is the full endpoint to send POST requests to.</target>
</trans-unit>
<trans-unit id="s51da4de00984fe51">
<source>API Auth Username</source>
<target>API Auth Username</target>
</trans-unit>
<trans-unit id="s293ab4331c1dd387">
<source>This is the username to be used with basic auth or the token when used with bearer token</source>
<target>This is the username to be used with basic auth or the token when used with bearer token</target>
</trans-unit>
<trans-unit id="s634d041fd954ab20">
<source>API Auth password</source>
<target>API Auth password</target>
</trans-unit>
<trans-unit id="sb635ad3c2e357d3c">
<source>This is the password to be used with basic auth</source>
<target>This is the password to be used with basic auth</target>
</trans-unit>
<trans-unit id="sa92398dba8b12d85">
<source>Mapping</source>
<target>Mapping</target>
</trans-unit>
<trans-unit id="s38162f615710c7b4">
<source>Modify the payload sent to the custom provider.</source>
<target>Modify the payload sent to the custom provider.</target>
</trans-unit>
<trans-unit id="s5e830ae7688d1219">
<source>Stage used to configure an SMS-based TOTP authenticator.</source>
<target>Stage used to configure an SMS-based TOTP authenticator.</target>
</trans-unit>
<trans-unit id="s0d5d05bf3d122ced">
<source>Twilio</source>
<target>Twilio</target>
</trans-unit>
<trans-unit id="sc3c74f5273df459a">
<source>Generic</source>
<target>Generic</target>
</trans-unit>
<trans-unit id="sbbb2180b6aed196e">
<source>From number</source>
<target>From number</target>
</trans-unit>
<trans-unit id="sc647dcb91f6958dd">
<source>Number the SMS will be sent from.</source>
<target>Number the SMS will be sent from.</target>
</trans-unit>
<trans-unit id="s0ae0072614320ae2">
<source>Hash phone number</source>
<target>Hash phone number</target>
</trans-unit>
<trans-unit id="s9ca3310e1999fd5b">
<source>If enabled, only a hash of the phone number will be saved. This can be done for data-protection reasons. Devices created from a stage with this enabled cannot be used with the authenticator validation stage.</source>
<target>If enabled, only a hash of the phone number will be saved. This can be done for data-protection reasons. Devices created from a stage with this enabled cannot be used with the authenticator validation stage.</target>
</trans-unit>
<trans-unit id="s128e7f5f34bfa155">
<source>Stage used to configure a static authenticator (i.e. static tokens). This stage should be used for configuration flows.</source>
<target>Stage used to configure a static authenticator (i.e. static tokens). This stage should be used for configuration flows.</target>
</trans-unit>
<trans-unit id="sabf67834e35dede5">
<source>Token count</source>
<target>Token count</target>
</trans-unit>
<trans-unit id="sc5a4711395ffb043">
<source>Stage used to configure a TOTP authenticator (i.e. Authy/Google Authenticator).</source>
<target>Stage used to configure a TOTP authenticator (i.e. Authy/Google Authenticator).</target>
</trans-unit>
<trans-unit id="s9d8ad4b85287131f">
<source>Digits</source>
<target>Digits</target>
</trans-unit>
<trans-unit id="sc04e92d753742189">
<source>6 digits, widely compatible</source>
<target>6 digits, widely compatible</target>
</trans-unit>
<trans-unit id="sdc70195469e83e3f">
<source>8 digits, not compatible with apps like Google Authenticator</source>
<target>8 digits, not compatible with apps like Google Authenticator</target>
</trans-unit>
<trans-unit id="s0e15f678445dfc45">
<source>Stage used to validate any authenticator. This stage should be used during authentication or authorization flows.</source>
<target>Stage used to validate any authenticator. This stage should be used during authentication or authorization flows.</target>
</trans-unit>
<trans-unit id="s73c13e5a6f5e38a3">
<source>Device classes</source>
<target>Device classes</target>
</trans-unit>
<trans-unit id="s97d1b0070f50c07f">
<source>Static Tokens</source>
<target>Static Tokens</target>
</trans-unit>
<trans-unit id="sb8168ae309c66abc">
<source>TOTP Authenticators</source>
<target>TOTP Authenticators</target>
</trans-unit>
<trans-unit id="sde47e4d8b9b21b59">
<source>WebAuthn Authenticators</source>
<target>WebAuthn Authenticators</target>
</trans-unit>
<trans-unit id="s8da88a8a5750bce1">
<source>Duo Authenticators</source>
<target>Duo Authenticators</target>
</trans-unit>
<trans-unit id="s4d182bae8a578010">
<source>SMS-based Authenticators</source>
<target>SMS-based Authenticators</target>
</trans-unit>
<trans-unit id="sd8d9451f86502d1a">
<source>Device classes which can be used to authenticate.</source>
<target>Device classes which can be used to authenticate.</target>
</trans-unit>
<trans-unit id="se2e9f5a32c93e5f7">
<source>Last validation threshold</source>
<target>Last validation threshold</target>
</trans-unit>
<trans-unit id="s951281efc92b03fc">
<source>If any of the devices user of the types selected above have been used within this duration, this stage will be skipped.</source>
<target>If any of the devices user of the types selected above have been used within this duration, this stage will be skipped.</target>
</trans-unit>
<trans-unit id="s681074b6c1f19c08">
<source>Not configured action</source>
<target>Not configured action</target>
</trans-unit>
<trans-unit id="sa2c29dc5ed47b26d">
<source>Force the user to configure an authenticator</source>
<target>Force the user to configure an authenticator</target>
</trans-unit>
<trans-unit id="sa30c58514a3dc0fb">
<source>Deny the user access</source>
<target>Deny the user access</target>
</trans-unit>
<trans-unit id="s1e0de9c4f66dc371">
<source>WebAuthn User verification</source>
<target>WebAuthn User verification</target>
</trans-unit>
<trans-unit id="sdb7b2173869822bc">
<source>User verification must occur.</source>
<target>User verification must occur.</target>
</trans-unit>
<trans-unit id="s7683363cdf78cf31">
<source>User verification is preferred if available, but not required.</source>
<target>User verification is preferred if available, but not required.</target>
</trans-unit>
<trans-unit id="scb43f5faeb6a7ca9">
<source>User verification should not occur.</source>
<target>User verification should not occur.</target>
</trans-unit>
<trans-unit id="scae166352a31032c">
<source>Configuration stages</source>
<target>Configuration stages</target>
</trans-unit>
<trans-unit id="s6941a67f0038ba4c">
<source>Stages used to configure Authenticator when user doesn't have any compatible devices. After this configuration Stage passes, the user is not prompted again.</source>
<target>Stages used to configure Authenticator when user doesn't have any compatible devices. After this configuration Stage passes, the user is not prompted again.</target>
</trans-unit>
<trans-unit id="s7e5af9c6ba6f5cc6">
<source>When multiple stages are selected, the user can choose which one they want to enroll.</source>
<target>When multiple stages are selected, the user can choose which one they want to enroll.</target>
</trans-unit>
<trans-unit id="s34b23ebbac9f6ab9">
<source>User verification</source>
<target>User verification</target>
</trans-unit>
<trans-unit id="s9ea472b555374771">
<source>Resident key requirement</source>
<target>Resident key requirement</target>
</trans-unit>
<trans-unit id="s5fbaeb14f42815e5">
<source>Authenticator Attachment</source>
<target>Authenticator Attachment</target>
</trans-unit>
<trans-unit id="s502d2473587032e1">
<source>No preference is sent</source>
<target>No preference is sent</target>
</trans-unit>
<trans-unit id="s60cc554fde2676cb">
<source>A non-removable authenticator, like TouchID or Windows Hello</source>
<target>A non-removable authenticator, like TouchID or Windows Hello</target>
</trans-unit>
<trans-unit id="sdf1d8edef27236f0">
<source>A "roaming" authenticator, like a YubiKey</source>
<target>A "roaming" authenticator, like a YubiKey</target>
</trans-unit>
<trans-unit id="sfffba7b23d8fb40c">
<source>This stage checks the user's current session against the Google reCaptcha (or compatible) service.</source>
<target>This stage checks the user's current session against the Google reCaptcha (or compatible) service.</target>
</trans-unit>
<trans-unit id="sfd1af96798dd8a5f">
<source>Public Key</source>
<target>Public Key</target>
</trans-unit>
<trans-unit id="sf339673f0f76a8bd">
<source>Public key, acquired from https://www.google.com/recaptcha/intro/v3.html.</source>
<target>Public key, acquired from https://www.google.com/recaptcha/intro/v3.html.</target>
</trans-unit>
<trans-unit id="s83d0f62ad1731a03">
<source>Private Key</source>
<target>Private Key</target>
</trans-unit>
<trans-unit id="s892d2731a6f22e59">
<source>Private key, acquired from https://www.google.com/recaptcha/intro/v3.html.</source>
<target>Private key, acquired from https://www.google.com/recaptcha/intro/v3.html.</target>
</trans-unit>
<trans-unit id="scb6620fcd5bff04c">
<source>Advanced settings</source>
<target>Advanced settings</target>
</trans-unit>
<trans-unit id="s39e436de1dc4df4f">
<source>JS URL</source>
<target>JS URL</target>
</trans-unit>
<trans-unit id="s170b705c55ecb2ae">
<source>URL to fetch JavaScript from, defaults to recaptcha. Can be replaced with any compatible alternative.</source>
<target>URL to fetch JavaScript from, defaults to recaptcha. Can be replaced with any compatible alternative.</target>
</trans-unit>
<trans-unit id="s275021658614ce9e">
<source>API URL</source>
<target>API URL</target>
</trans-unit>
<trans-unit id="sc8a79fddea3ab4a9">
<source>URL used to validate captcha response, defaults to recaptcha. Can be replaced with any compatible alternative.</source>
<target>URL used to validate captcha response, defaults to recaptcha. Can be replaced with any compatible alternative.</target>
</trans-unit>
<trans-unit id="s1cd617e7bbe278d0">
<source>Prompt for the user's consent. The consent can either be permanent or expire in a defined amount of time.</source>
<target>Prompt for the user's consent. The consent can either be permanent or expire in a defined amount of time.</target>
</trans-unit>
<trans-unit id="s26513c9dd154f041">
<source>Always require consent</source>
<target>Always require consent</target>
</trans-unit>
<trans-unit id="s8ce8bdc9cc9c8604">
<source>Consent given last indefinitely</source>
<target>Consent given last indefinitely</target>
</trans-unit>
<trans-unit id="sb986f15fa9b17805">
<source>Consent expires.</source>
<target>Consent expires.</target>
</trans-unit>
<trans-unit id="s6f328f2d8382d998">
<source>Consent expires in</source>
<target>Consent expires in</target>
</trans-unit>
<trans-unit id="se0c660020d9cf5b7">
<source>Offset after which consent expires.</source>
<target>Offset after which consent expires.</target>
</trans-unit>
<trans-unit id="s22b10ed263b96194">
<source>Dummy stage used for testing. Shows a simple continue button and always passes.</source>
<target>Dummy stage used for testing. Shows a simple continue button and always passes.</target>
</trans-unit>
<trans-unit id="sdb861d9906f18ac2">
<source>Throw error?</source>
<target>Throw error?</target>
</trans-unit>
<trans-unit id="s31ebc5431d677f5d">
<source>SMTP Host</source>
<target>SMTP Host</target>
</trans-unit>
<trans-unit id="s289fce7e694b98ac">
<source>SMTP Port</source>
<target>SMTP Port</target>
</trans-unit>
<trans-unit id="se4a9da0295597e73">
<source>SMTP Username</source>
<target>SMTP Username</target>
</trans-unit>
<trans-unit id="s593db2c00d6516a2">
<source>SMTP Password</source>
<target>SMTP Password</target>
</trans-unit>
<trans-unit id="s0d4268408182491d">
<source>Use TLS</source>
<target>Use TLS</target>
</trans-unit>
<trans-unit id="s480c6c40a248f7d2">
<source>Use SSL</source>
<target>Use SSL</target>
</trans-unit>
<trans-unit id="sc1feadd25659c94d">
<source>From address</source>
<target>From address</target>
</trans-unit>
<trans-unit id="sa248e1021d2c27b5">
<source>Verify the user's email address by sending them a one-time-link. Can also be used for recovery to verify the user's authenticity.</source>
<target>Verify the user's email address by sending them a one-time-link. Can also be used for recovery to verify the user's authenticity.</target>
</trans-unit>
<trans-unit id="s87b7e3bc944c728c">
<source>Activate pending user on success</source>
<target>Activate pending user on success</target>
</trans-unit>
<trans-unit id="s9e9c8d99f4c26baf">
<source>When a user returns from the email successfully, their account will be activated.</source>
<target>When a user returns from the email successfully, their account will be activated.</target>
</trans-unit>
<trans-unit id="s618d4e53f455c834">
<source>Use global settings</source>
<target>Use global settings</target>
</trans-unit>
<trans-unit id="sae1e1a59d22609c4">
<source>When enabled, global Email connection settings will be used and connection settings below will be ignored.</source>
<target>When enabled, global Email connection settings will be used and connection settings below will be ignored.</target>
</trans-unit>
<trans-unit id="sb1fe947f9ad27b9d">
<source>Token expiry</source>
<target>Token expiry</target>
</trans-unit>
<trans-unit id="s1c6ba8d100453392">
<source>Time in minutes the token sent is valid.</source>
<target>Time in minutes the token sent is valid.</target>
</trans-unit>
<trans-unit id="se47baf2fd16b9d2b">
<source>Template</source>
<target>Template</target>
</trans-unit>
<trans-unit id="s4af8a3ce5a600855">
<source>Let the user identify themselves with their username or Email address.</source>
<target>Let the user identify themselves with their username or Email address.</target>
</trans-unit>
<trans-unit id="s592ab7d2bc1b8973">
<source>User fields</source>
<target>User fields</target>
</trans-unit>
<trans-unit id="s61e48919db20538a">
<source>UPN</source>
<target>UPN</target>
</trans-unit>
<trans-unit id="s4cdae7635e757555">
<source>Fields a user can identify themselves with. If no fields are selected, the user will only be able to use sources.</source>
<target>Fields a user can identify themselves with. If no fields are selected, the user will only be able to use sources.</target>
</trans-unit>
<trans-unit id="s3380d7cbcebe50f6">
<source>Password stage</source>
<target>Password stage</target>
</trans-unit>
<trans-unit id="s08c91cb1a2cd3d97">
<source>When selected, a password field is shown on the same page instead of a separate page. This prevents username enumeration attacks.</source>
<target>When selected, a password field is shown on the same page instead of a separate page. This prevents username enumeration attacks.</target>
</trans-unit>
<trans-unit id="sd97d8d0906e6cc47">
<source>Case insensitive matching</source>
<target>Case insensitive matching</target>
</trans-unit>
<trans-unit id="s8aaad223e954f9ca">
<source>When enabled, user fields are matched regardless of their casing.</source>
<target>When enabled, user fields are matched regardless of their casing.</target>
</trans-unit>
<trans-unit id="sbab723b98dcfe23f">
<source>Show matched user</source>
<target>Show matched user</target>
</trans-unit>
<trans-unit id="se50a08ab71bb96ed">
<source>When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown.</source>
<target>When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown.</target>
</trans-unit>
<trans-unit id="s0295ce5d6f635d75">
<source>Source settings</source>
<target>Source settings</target>
</trans-unit>
<trans-unit id="s91e3a47599412f51">
<source>Sources</source>
<target>Sources</target>
</trans-unit>
<trans-unit id="s17a679298216aca9">
<source>Select sources should be shown for users to authenticate with. This only affects web-based sources, not LDAP.</source>
<target>Select sources should be shown for users to authenticate with. This only affects web-based sources, not LDAP.</target>
</trans-unit>
<trans-unit id="sa41aee3ae04c9216">
<source>Show sources' labels</source>
<target>Show sources' labels</target>
</trans-unit>
<trans-unit id="s54cd35e6224ba65d">
<source>By default, only icons are shown for sources. Enable this to show their full names.</source>
<target>By default, only icons are shown for sources. Enable this to show their full names.</target>
</trans-unit>
<trans-unit id="s9ee20003cb116abf">
<source>Passwordless flow</source>
<target>Passwordless flow</target>
</trans-unit>
<trans-unit id="s0c8c4d2bb0a9162a">
<source>Optional passwordless flow, which is linked at the bottom of the page. When configured, users can use this flow to authenticate with a WebAuthn authenticator, without entering any details.</source>
<target>Optional passwordless flow, which is linked at the bottom of the page. When configured, users can use this flow to authenticate with a WebAuthn authenticator, without entering any details.</target>
</trans-unit>
<trans-unit id="s01a3a7f48ee4edaf">
<source>Optional enrollment flow, which is linked at the bottom of the page.</source>
<target>Optional enrollment flow, which is linked at the bottom of the page.</target>
</trans-unit>
<trans-unit id="s82188c9542510212">
<source>Optional recovery flow, which is linked at the bottom of the page.</source>
<target>Optional recovery flow, which is linked at the bottom of the page.</target>
</trans-unit>
<trans-unit id="s3e59b8b2debf0209">
<source>This stage can be included in enrollment flows to accept invitations.</source>
<target>This stage can be included in enrollment flows to accept invitations.</target>
</trans-unit>
<trans-unit id="s79ad406777feab1f">
<source>Continue flow without invitation</source>
<target>Continue flow without invitation</target>
</trans-unit>
<trans-unit id="s61ccefd661ac2296">
<source>If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given.</source>
<target>If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given.</target>
</trans-unit>
<trans-unit id="sdc30bddeda2f0225">
<source>Validate the user's password against the selected backend(s).</source>
<target>Validate the user's password against the selected backend(s).</target>
</trans-unit>
<trans-unit id="sb8d4f44a1d5b9a14">
<source>Backends</source>
<target>Backends</target>
</trans-unit>
<trans-unit id="sba42248f3f27955c">
<source>User database + standard password</source>
<target>User database + standard password</target>
</trans-unit>
<trans-unit id="s3330adb3f0922f7b">
<source>User database + app passwords</source>
<target>User database + app passwords</target>
</trans-unit>
<trans-unit id="sc10db51c9bb77d5c">
<source>User database + LDAP password</source>
<target>User database + LDAP password</target>
</trans-unit>
<trans-unit id="sd35ae4be63df1f9f">
<source>Selection of backends to test the password against.</source>
<target>Selection of backends to test the password against.</target>
</trans-unit>
<trans-unit id="s482ae78809a6822b">
<source>Flow used by an authenticated user to configure their password. If empty, user will not be able to configure change their password.</source>
<target>Flow used by an authenticated user to configure their password. If empty, user will not be able to configure change their password.</target>
</trans-unit>
<trans-unit id="s77994108c886b965">
<source>Failed attempts before cancel</source>
<target>Failed attempts before cancel</target>
</trans-unit>
<trans-unit id="sa9020b93c3bd7235">
<source>How many attempts a user has before the flow is canceled. To lock the user out, use a reputation policy and a user_write stage.</source>
<target>How many attempts a user has before the flow is canceled. To lock the user out, use a reputation policy and a user_write stage.</target>
</trans-unit>
<trans-unit id="s5170f9ef331949c0">
<source>Show arbitrary input fields to the user, for example during enrollment. Data is saved in the flow context under the 'prompt_data' variable.</source>
<target>Show arbitrary input fields to the user, for example during enrollment. Data is saved in the flow context under the 'prompt_data' variable.</target>
</trans-unit>
<trans-unit id="s36cb242ac90353bc">
<source>Fields</source>
<target>Fields</target>
</trans-unit>
<trans-unit id="s2d5f69929bb7221d">
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
<target>
<x id="0" equiv-text="${prompt.name}"/>("
<x id="1" equiv-text="${prompt.fieldKey}"/>", of type
<x id="2" equiv-text="${prompt.type}"/>)</target>
</trans-unit>
<trans-unit id="s3b7b519444181264">
<source>Validation Policies</source>
<target>Validation Policies</target>
</trans-unit>
<trans-unit id="s59691290a232c687">
<source>Selected policies are executed when the stage is submitted to validate the data.</source>
<target>Selected policies are executed when the stage is submitted to validate the data.</target>
</trans-unit>
<trans-unit id="sbf4ef82e04772a4e">
<source>Delete the currently pending user. CAUTION, this stage does not ask for confirmation. Use a consent stage to ensure the user is aware of their actions.</source>
</trans-unit>
<trans-unit id="s8cc920e6a8430a0d">
<source>Log the currently pending user in.</source>
<target>Log the currently pending user in.</target>
</trans-unit>
<trans-unit id="sb85ffe141d7c229d">
<source>Session duration</source>
<target>Session duration</target>
</trans-unit>
<trans-unit id="sece294cd51a85745">
<source>Determines how long a session lasts. Default of 0 seconds means that the sessions lasts until the browser is closed.</source>
<target>Determines how long a session lasts. Default of 0 seconds means that the sessions lasts until the browser is closed.</target>
</trans-unit>
<trans-unit id="sf7949fbbab2eb566">
<source>Different browsers handle session cookies differently, and might not remove them even when the browser is closed.</source>
<target>Different browsers handle session cookies differently, and might not remove them even when the browser is closed.</target>
</trans-unit>
<trans-unit id="s53bbc3ae4b5fa1d0">
<source>See here.</source>
<target>See here.</target>
</trans-unit>
<trans-unit id="s2512334108f06a5a">
<source>Stay signed in offset</source>
<target>Stay signed in offset</target>
</trans-unit>
<trans-unit id="s1608b2f94fa0dbd4">
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
<target>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</target>
</trans-unit>
<trans-unit id="s542a71bb8f41e057">
<source>Terminate other sessions</source>
<target>Terminate other sessions</target>
</trans-unit>
<trans-unit id="sa920231366378c90">
<source>When enabled, all previous sessions of the user will be terminated.</source>
<target>When enabled, all previous sessions of the user will be terminated.</target>
</trans-unit>
<trans-unit id="sfee06600c15082a9">
<source>Remove the user from the current session.</source>
<target>Remove the user from the current session.</target>
</trans-unit>
<trans-unit id="s927398c400970760">
<source>Write any data from the flow's context's 'prompt_data' to the currently pending user. If no user
is pending, a new user is created, and data is written to them.</source>
</trans-unit>
<trans-unit id="sb379d861cbed0b47">
<source>Never create users</source>
<target>Never create users</target>
</trans-unit>
<trans-unit id="s81d673755a86a4f0">
<source>When no user is present in the flow context, the stage will fail.</source>
<target>When no user is present in the flow context, the stage will fail.</target>
</trans-unit>
<trans-unit id="s9940e3f073fbdbd4">
<source>Create users when required</source>
<target>Create users when required</target>
</trans-unit>
<trans-unit id="s5414356cc10e80fe">
<source>When no user is present in the the flow context, a new user is created.</source>
<target>When no user is present in the the flow context, a new user is created.</target>
</trans-unit>
<trans-unit id="s57337099d96ce6d2">
<source>Always create new users</source>
<target>Always create new users</target>
</trans-unit>
<trans-unit id="se80dd66f23b4fc39">
<source>Create a new user even if a user is in the flow context.</source>
<target>Create a new user even if a user is in the flow context.</target>
</trans-unit>
<trans-unit id="sed3512fe4560c7f4">
<source>Create users as inactive</source>
<target>Create users as inactive</target>
</trans-unit>
<trans-unit id="s9193ef1a39a6c872">
<source>Mark newly created users as inactive.</source>
<target>Mark newly created users as inactive.</target>
</trans-unit>
<trans-unit id="s89d1847b5e4ad225">
<source>User path template</source>
<target>User path template</target>
</trans-unit>
<trans-unit id="s18269e3889d6fa54">
<source>Path new users will be created under. If left blank, the default path will be used.</source>
<target>Path new users will be created under. If left blank, the default path will be used.</target>
</trans-unit>
<trans-unit id="sc1cb0eef9ed94e6a">
<source>Newly created users are added to this group, if a group is selected.</source>
<target>Newly created users are added to this group, if a group is selected.</target>
</trans-unit>
<trans-unit id="sd8417b41ca27bc8f">
<source>New stage</source>
<target>New stage</target>
</trans-unit>
<trans-unit id="s293801033f9fc0d0">
<source>Create a new stage.</source>
<target>Create a new stage.</target>
</trans-unit>
<trans-unit id="s71633a67e0d7c0e4">
<source>Successfully imported device.</source>
<target>Successfully imported device.</target>
</trans-unit>
<trans-unit id="s7d61705dfb120d7b">
<source>The user in authentik this device will be assigned to.</source>
<target>The user in authentik this device will be assigned to.</target>
</trans-unit>
<trans-unit id="s5eaf1d304e03ed4b">
<source>Duo User ID</source>
<target>Duo User ID</target>
</trans-unit>
<trans-unit id="s003847d8bc01c676">
<source>The user ID in Duo, can be found in the URL after clicking on a user.</source>
<target>The user ID in Duo, can be found in the URL after clicking on a user.</target>
</trans-unit>
<trans-unit id="sbbc806ea3987c781">
<source>Automatic import</source>
<target>Automatic import</target>
</trans-unit>
<trans-unit id="s77299a9d3dd932cd">
<source>Successfully imported <x id="0" equiv-text="${res.count}"/> devices.</source>
<target>Successfully imported
<x id="0" equiv-text="${res.count}"/>devices.</target>
</trans-unit>
<trans-unit id="s6a615f6165ef01c9">
<source>Start automatic import</source>
<target>Start automatic import</target>
</trans-unit>
<trans-unit id="s9f83d7768aea548a">
<source>Or manually import</source>
<target>Or manually import</target>
</trans-unit>
<trans-unit id="sddc8efe94cb8c210">
<source>Stages are single steps of a Flow that a user is guided through. A stage can only be executed from within a flow.</source>
<target>Stages are single steps of a Flow that a user is guided through. A stage can only be executed from within a flow.</target>
</trans-unit>
<trans-unit id="sb69a4b0acd0895f2">
<source>Flows</source>
<target>Flows</target>
</trans-unit>
<trans-unit id="s0eaf755fa88c8d97">
<source>Stage(s)</source>
<target>Stage(s)</target>
</trans-unit>
<trans-unit id="s3914cb410fca44d4">
<source>Import</source>
<target>Import</target>
</trans-unit>
<trans-unit id="s8a67b33a0d70d322">
<source>Import Duo device</source>
<target>Import Duo device</target>
</trans-unit>
<trans-unit id="s48cf8fd56b1237ed">
<source>Successfully updated flow.</source>
<target>Successfully updated flow.</target>
</trans-unit>
<trans-unit id="sc3e0c240b159fbce">
<source>Successfully created flow.</source>
<target>Successfully created flow.</target>
</trans-unit>
<trans-unit id="s925936f647ae52cc">
<source>Shown as the Title in Flow pages.</source>
<target>Shown as the Title in Flow pages.</target>
</trans-unit>
<trans-unit id="s50719dda8f90abf4">
<source>Visible in the URL.</source>
<target>Visible in the URL.</target>
</trans-unit>
<trans-unit id="s0f4c6540c30bd8b4">
<source>Designation</source>
<target>Designation</target>
</trans-unit>
<trans-unit id="sb25d9afe10941425">
<source>Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik.</source>
<target>Decides what this Flow is used for. For example, the Authentication flow is redirect to when an un-authenticated user visits authentik.</target>
</trans-unit>
<trans-unit id="sb36e4c05244278c1">
<source>No requirement</source>
<target>No requirement</target>
</trans-unit>
<trans-unit id="s7b105164d209f670">
<source>Require authentication</source>
<target>Require authentication</target>
</trans-unit>
<trans-unit id="s239c2a351cde6d39">
<source>Require no authentication.</source>
<target>Require no authentication.</target>
</trans-unit>
<trans-unit id="s98beadfeeb3acb66">
<source>Require superuser.</source>
<target>Require superuser.</target>
</trans-unit>
<trans-unit id="sfad9279cc42c6b61">
<source>Required authentication level for this flow.</source>
<target>Required authentication level for this flow.</target>
</trans-unit>
<trans-unit id="sb56674c9ea4f0588">
<source>Behavior settings</source>
<target>Behavior settings</target>
</trans-unit>
<trans-unit id="sb6d7d58cb0a1544e">
<source>Compatibility mode</source>
<target>Compatibility mode</target>
</trans-unit>
<trans-unit id="s14ace18ccf4fb86d">
<source>Increases compatibility with password managers and mobile devices.</source>
<target>Increases compatibility with password managers and mobile devices.</target>
</trans-unit>
<trans-unit id="scfbc2f1396ee8550">
<source>Denied action</source>
<target>Denied action</target>
</trans-unit>
<trans-unit id="sff38031cf061e3ae">
<source>Will follow the ?next parameter if set, otherwise show a message</source>
<target>Will follow the ?next parameter if set, otherwise show a message</target>
</trans-unit>
<trans-unit id="s936bf4342b182ad4">
<source>Will either follow the ?next parameter or redirect to the default interface</source>
<target>Will either follow the ?next parameter or redirect to the default interface</target>
</trans-unit>
<trans-unit id="s22b0e8c5277dd5a9">
<source>Will notify the user the flow isn't applicable</source>
<target>Will notify the user the flow isn't applicable</target>
</trans-unit>
<trans-unit id="s2eeca5cfc99ef19b">
<source>Decides the response when a policy denies access to this flow for a user.</source>
<target>Decides the response when a policy denies access to this flow for a user.</target>
</trans-unit>
<trans-unit id="sbaf20067de176c90">
<source>Appearance settings</source>
<target>Appearance settings</target>
</trans-unit>
<trans-unit id="s2e4818861000b13f">
<source>Layout</source>
<target>Layout</target>
</trans-unit>
<trans-unit id="s1efbfc3937d565bd">
<source>Background</source>
<target>Background</target>
</trans-unit>
<trans-unit id="s374abf1a54d87b67">
<source>Background shown during execution.</source>
<target>Background shown during execution.</target>
</trans-unit>
<trans-unit id="s3ebf4c166058afce">
<source>Clear background</source>
<target>Clear background</target>
</trans-unit>
<trans-unit id="sb24755ea94bef31d">
<source>Delete currently set background image.</source>
<target>Delete currently set background image.</target>
</trans-unit>
<trans-unit id="sb904f23f17b60c3a">
<source>Successfully imported flow.</source>
<target>Successfully imported flow.</target>
</trans-unit>
<trans-unit id="s344c4a2a48997e18">
<source>.yaml files, which can be found on goauthentik.io and can be exported by authentik.</source>
<target>.yaml files, which can be found on goauthentik.io and can be exported by authentik.</target>
</trans-unit>
<trans-unit id="sc816360d6f5a1eeb">
<source>Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them.</source>
<target>Flows describe a chain of Stages to authenticate, enroll or recover a user. Stages are chosen based on policies applied to them.</target>
</trans-unit>
<trans-unit id="s6f857299d5db1ecf">
<source>Flow(s)</source>
<target>Flow(s)</target>
</trans-unit>
<trans-unit id="s9e830cbc0b42a514">
<source>Update Flow</source>
<target>Update Flow</target>
</trans-unit>
<trans-unit id="s2f1bcfcc5cae94c3">
<source>Create Flow</source>
<target>Create Flow</target>
</trans-unit>
<trans-unit id="s832282d415294df4">
<source>Import Flow</source>
<target>Import Flow</target>
</trans-unit>
<trans-unit id="s098237f7ccb4dc4a">
<source>Successfully cleared flow cache</source>
<target>Successfully cleared flow cache</target>
</trans-unit>
<trans-unit id="s59572c1be31a812e">
<source>Failed to delete flow cache</source>
<target>Failed to delete flow cache</target>
</trans-unit>
<trans-unit id="sa2b727168b090d34">
<source>Clear Flow cache</source>
<target>Clear Flow cache</target>
</trans-unit>
<trans-unit id="sf12d588a76ba7e51">
<source>Are you sure you want to clear the flow cache?
This will cause all flows to be re-evaluated on their next usage.</source>
</trans-unit>
<trans-unit id="sbe47a5bdeec19ab0">
<source>Stage binding(s)</source>
<target>Stage binding(s)</target>
</trans-unit>
<trans-unit id="sfa88f413e287bb0f">
<source>Stage type</source>
<target>Stage type</target>
</trans-unit>
<trans-unit id="s04440099d97c0bef">
<source>Edit Stage</source>
<target>Edit Stage</target>
</trans-unit>
<trans-unit id="s980270d0fab7ecb3">
<source>Update Stage binding</source>
<target>Update Stage binding</target>
</trans-unit>
<trans-unit id="sfe938c1585e0bf68">
<source>These bindings control if this stage will be applied to the flow.</source>
<target>These bindings control if this stage will be applied to the flow.</target>
</trans-unit>
<trans-unit id="sfac6f995c7670559">
<source>No Stages bound</source>
<target>No Stages bound</target>
</trans-unit>
<trans-unit id="s955c1fec1c6fb970">
<source>No stages are currently bound to this flow.</source>
<target>No stages are currently bound to this flow.</target>
</trans-unit>
<trans-unit id="s9a393a04eaf1eb0e">
<source>Create Stage binding</source>
<target>Create Stage binding</target>
</trans-unit>
<trans-unit id="s207e8b106806d7e4">
<source>Bind stage</source>
<target>Bind stage</target>
</trans-unit>
<trans-unit id="scc2e420c54dc8089">
<source>Bind existing stage</source>
<target>Bind existing stage</target>
</trans-unit>
<trans-unit id="s30d1f50f476c3f48">
<source>Flow Overview</source>
<target>Flow Overview</target>
</trans-unit>
<trans-unit id="s77099d752f1ab773">
<source>Related actions</source>
<target>Related actions</target>
</trans-unit>
<trans-unit id="sd07866d9f38b2c50">
<source>Execute flow</source>
<target>Execute flow</target>
</trans-unit>
<trans-unit id="s9ff3121d30f88d52">
<source>Normal</source>
<target>Normal</target>
</trans-unit>
<trans-unit id="s6e4c997a101b6abf">
<source>with current user</source>
<target>with current user</target>
</trans-unit>
<trans-unit id="s8ecdbff1a7329b64">
<source>with inspector</source>
<target>with inspector</target>
</trans-unit>
<trans-unit id="s3576aead3e68c5c9">
<source>Export flow</source>
<target>Export flow</target>
</trans-unit>
<trans-unit id="s293aa6a6446fb153">
<source>Export</source>
<target>Export</target>
</trans-unit>
<trans-unit id="se2c3cbf2ed1403f1">
<source>Stage Bindings</source>
<target>Stage Bindings</target>
</trans-unit>
<trans-unit id="s78c08391ffbfb8c0">
<source>These bindings control which users can access this flow.</source>
<target>These bindings control which users can access this flow.</target>
</trans-unit>
<trans-unit id="sc1a1ff47c058bb09">
<source>Event Log</source>
<target>Event Log</target>
</trans-unit>
<trans-unit id="s65d67612999165e9">
<source>Event <x id="0" equiv-text="${this.event.pk}"/></source>
<target>Event
<x id="0" equiv-text="${this.event.pk}"/></target>
</trans-unit>
<trans-unit id="s455de2f740b073fd">
<source>Event info</source>
<target>Event info</target>
</trans-unit>
<trans-unit id="sb41b2cfbbc52565b">
<source>Created</source>
<target>Created</target>
</trans-unit>
<trans-unit id="s037bc6d25a03c3c8">
<source>Successfully updated transport.</source>
<target>Successfully updated transport.</target>
</trans-unit>
<trans-unit id="s1575a15cee001915">
<source>Successfully created transport.</source>
<target>Successfully created transport.</target>
</trans-unit>
<trans-unit id="s4acf840bc792c3ae">
<source>Local (notifications will be created within authentik)</source>
<target>Local (notifications will be created within authentik)</target>
</trans-unit>
<trans-unit id="sede0abbf2b612812">
<source>Webhook (generic)</source>
<target>Webhook (generic)</target>
</trans-unit>
<trans-unit id="s76f5dca6404a1210">
<source>Webhook (Slack/Discord)</source>
<target>Webhook (Slack/Discord)</target>
</trans-unit>
<trans-unit id="s6873bdbfa24615fb">
<source>Webhook URL</source>
<target>Webhook URL</target>
</trans-unit>
<trans-unit id="s25ec2846f6b88214">
<source>Webhook Mapping</source>
<target>Webhook Mapping</target>
</trans-unit>
<trans-unit id="sca2879d96f58a39c">
<source>Send once</source>
<target>Send once</target>
</trans-unit>
<trans-unit id="s2430e000b7cfefd0">
<source>Only send notification once, for example when sending a webhook into a chat channel.</source>
<target>Only send notification once, for example when sending a webhook into a chat channel.</target>
</trans-unit>
<trans-unit id="s819509c33a7534ac">
<source>Notification Transports</source>
<target>Notification Transports</target>
</trans-unit>
<trans-unit id="s57072ffb92b6c9c8">
<source>Define how notifications are sent to users, like Email or Webhook.</source>
<target>Define how notifications are sent to users, like Email or Webhook.</target>
</trans-unit>
<trans-unit id="s624256f8a4bb4c89">
<source>Notification transport(s)</source>
<target>Notification transport(s)</target>
</trans-unit>
<trans-unit id="sac1332e6f421526e">
<source>Update Notification Transport</source>
<target>Update Notification Transport</target>
</trans-unit>
<trans-unit id="s6b5002c605b39d6d">
<source>Create Notification Transport</source>
<target>Create Notification Transport</target>
</trans-unit>
<trans-unit id="s0a39e4f61ccafacb">
<source>Successfully updated rule.</source>
<target>Successfully updated rule.</target>
</trans-unit>
<trans-unit id="s72e102414fec81a4">
<source>Successfully created rule.</source>
<target>Successfully created rule.</target>
</trans-unit>
<trans-unit id="sa55ee64c5c51df0f">
<source>Select the group of users which the alerts are sent to. If no group is selected the rule is disabled.</source>
<target>Select the group of users which the alerts are sent to. If no group is selected the rule is disabled.</target>
</trans-unit>
<trans-unit id="sffa171e11d4ae513">
<source>Transports</source>
<target>Transports</target>
</trans-unit>
<trans-unit id="s7b18721be331241e">
<source>Select which transports should be used to notify the user. If none are selected, the notification will only be shown in the authentik UI.</source>
<target>Select which transports should be used to notify the user. If none are selected, the notification will only be shown in the authentik UI.</target>
</trans-unit>
<trans-unit id="scd0cfe87af6f2ff2">
<source>Severity</source>
<target>Severity</target>
</trans-unit>
<trans-unit id="s98c3bdf4fd5cdf65">
<source>Notification Rules</source>
<target>Notification Rules</target>
</trans-unit>
<trans-unit id="s107bf77afb93c9b8">
<source>Send notifications whenever a specific Event is created and matched by policies.</source>
<target>Send notifications whenever a specific Event is created and matched by policies.</target>
</trans-unit>
<trans-unit id="sf3f9a0feaf083207">
<source>Sent to group</source>
<target>Sent to group</target>
</trans-unit>
<trans-unit id="sc92ed9d5e01d3f24">
<source>Notification rule(s)</source>
<target>Notification rule(s)</target>
</trans-unit>
<trans-unit id="s5140d157642d7362">
<source>None (rule disabled)</source>
<target>None (rule disabled)</target>
</trans-unit>
<trans-unit id="sd1146418b344f81f">
<source>Update Notification Rule</source>
<target>Update Notification Rule</target>
</trans-unit>
<trans-unit id="sbbc1de43ab6c1f76">
<source>Create Notification Rule</source>
<target>Create Notification Rule</target>
</trans-unit>
<trans-unit id="s5795b310ab271d20">
<source>These bindings control upon which events this rule triggers.
Bindings to groups/users are checked against the user of the event.</source>
</trans-unit>
<trans-unit id="s90c3b62194fe8508">
<source>Outpost Deployment Info</source>
<target>Outpost Deployment Info</target>
</trans-unit>
<trans-unit id="s35f9df7668d5fa79">
<source>View deployment documentation</source>
<target>View deployment documentation</target>
</trans-unit>
<trans-unit id="sad09c62cb4ebae68">
<source>Click to copy token</source>
<target>Click to copy token</target>
</trans-unit>
<trans-unit id="s0e03fe2dc5b9164b">
<source>If your authentik Instance is using a self-signed certificate, set this value.</source>
<target>If your authentik Instance is using a self-signed certificate, set this value.</target>
</trans-unit>
<trans-unit id="sc21032b0d37882a0">
<source>If your authentik_host setting does not match the URL you want to login with, add this setting.</source>
<target>If your authentik_host setting does not match the URL you want to login with, add this setting.</target>
</trans-unit>
<trans-unit id="s6f270e1668c036e9">
<source>Successfully updated outpost.</source>
<target>Successfully updated outpost.</target>
</trans-unit>
<trans-unit id="s79aed8154d7c472c">
<source>Successfully created outpost.</source>
<target>Successfully created outpost.</target>
</trans-unit>
<trans-unit id="s8afc8c5aafb392d3">
<source>Radius</source>
<target>Radius</target>
</trans-unit>
<trans-unit id="s03970aa76a09982d">
<source>Integration</source>
<target>Integration</target>
</trans-unit>
<trans-unit id="s9c29565c5ae1cc92">
<source>Selecting an integration enables the management of the outpost by authentik.</source>
<target>Selecting an integration enables the management of the outpost by authentik.</target>
</trans-unit>
<trans-unit id="s554ce268e9727e79">
<source>You can only select providers that match the type of the outpost.</source>
<target>You can only select providers that match the type of the outpost.</target>
</trans-unit>
<trans-unit id="sf9b1c0661a02d9f9">
<source>Configuration</source>
<target>Configuration</target>
</trans-unit>
<trans-unit id="s3abecf1e778c9625">
<source>See more here:</source>
<target>See more here:</target>
</trans-unit>
<trans-unit id="s74cb3d66f6a668e1">
<source>Documentation</source>
<target>Documentation</target>
</trans-unit>
<trans-unit id="saa8939ac88a76f98">
<source>Last seen</source>
<target>Last seen</target>
</trans-unit>
<trans-unit id="s1ac2653a6492b435">
<source><x id="0" equiv-text="${this.outpostHealth.version}"/>, should be <x id="1" equiv-text="${this.outpostHealth.versionShould}"/></source>
<target>
<x id="0" equiv-text="${this.outpostHealth.version}"/>, should be
<x id="1" equiv-text="${this.outpostHealth.versionShould}"/></target>
</trans-unit>
<trans-unit id="s1e176e35c828318c">
<source>Hostname</source>
<target>Hostname</target>
</trans-unit>
<trans-unit id="s322e34cfcba47155">
<source>Not available</source>
<target>Not available</target>
</trans-unit>
<trans-unit id="s02b632a9ac24a824">
<source>Last seen: <x id="0" equiv-text="${this.outpostHealth.lastSeen?.toLocaleTimeString()}"/></source>
<target>Last seen:
<x id="0" equiv-text="${this.outpostHealth.lastSeen?.toLocaleTimeString()}"/></target>
</trans-unit>
<trans-unit id="sa43153d53ae65063">
<source>Unknown type</source>
<target>Unknown type</target>
</trans-unit>
<trans-unit id="s5e169e1bac20b4a6">
<source>Outposts</source>
<target>Outposts</target>
</trans-unit>
<trans-unit id="s8802553bc57617ee">
<source>Outposts are deployments of authentik components to support different environments and protocols, like reverse proxies.</source>
<target>Outposts are deployments of authentik components to support different environments and protocols, like reverse proxies.</target>
</trans-unit>
<trans-unit id="s84d7d6ebbedcb586">
<source>Health and Version</source>
<target>Health and Version</target>
</trans-unit>
<trans-unit id="s9bf48a89367282cd">
<source>Warning: authentik Domain is not configured, authentication will not work.</source>
<target>Warning: authentik Domain is not configured, authentication will not work.</target>
</trans-unit>
<trans-unit id="sbf5f4c5ba679e847">
<source>Logging in via <x id="0" equiv-text="${item.config.authentik_host}"/>.</source>
<target>Logging in via
<x id="0" equiv-text="${item.config.authentik_host}"/>.</target>
</trans-unit>
<trans-unit id="s59b6028f19d15cda">
<source>No integration active</source>
<target>No integration active</target>
</trans-unit>
<trans-unit id="s9bd59e0ea70a3e4a">
<source>Update Outpost</source>
<target>Update Outpost</target>
</trans-unit>
<trans-unit id="sc8f286ac783c385d">
<source>View Deployment Info</source>
<target>View Deployment Info</target>
</trans-unit>
<trans-unit id="s9ee92717d7f63247">
<source>Detailed health (one instance per column, data is cached so may be out of date)</source>
<target>Detailed health (one instance per column, data is cached so may be out of date)</target>
</trans-unit>
<trans-unit id="s1d49ec5030447643">
<source>Outpost(s)</source>
<target>Outpost(s)</target>
</trans-unit>
<trans-unit id="s1a2f8f4b3861583b">
<source>Create Outpost</source>
<target>Create Outpost</target>
</trans-unit>
<trans-unit id="sdc1ef94016f0d855">
<source>Successfully updated integration.</source>
<target>Successfully updated integration.</target>
</trans-unit>
<trans-unit id="sc2a1a40a1b4b0170">
<source>Successfully created integration.</source>
<target>Successfully created integration.</target>
</trans-unit>
<trans-unit id="se9b1fec72ffd8f48">
<source>Local</source>
<target>Local</target>
</trans-unit>
<trans-unit id="sc1231049879b8d33">
<source>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</source>
<target>If enabled, use the local connection. Required Docker socket/Kubernetes Integration.</target>
</trans-unit>
<trans-unit id="s13de04774ff0f210">
<source>Docker URL</source>
<target>Docker URL</target>
</trans-unit>
<trans-unit id="sa7fcf026bd25f231">
<source>Can be in the format of 'unix://' when connecting to a local docker daemon, using 'ssh://' to connect via SSH, or 'https://:2376' when connecting to a remote system.</source>
<target>Can be in the format of 'unix://' when connecting to a local docker daemon, using 'ssh://' to connect via SSH, or 'https://:2376' when connecting to a remote system.</target>
</trans-unit>
<trans-unit id="saf1d289e3137c2ea">
<source>CA which the endpoint's Certificate is verified against. Can be left empty for no validation.</source>
<target>CA which the endpoint's Certificate is verified against. Can be left empty for no validation.</target>
</trans-unit>
<trans-unit id="s0f2e070d38cd36df">
<source>TLS Authentication Certificate/SSH Keypair</source>
<target>TLS Authentication Certificate/SSH Keypair</target>
</trans-unit>
<trans-unit id="s2f58bb9905d2b76f">
<source>Certificate/Key used for authentication. Can be left empty for no authentication.</source>
<target>Certificate/Key used for authentication. Can be left empty for no authentication.</target>
</trans-unit>
<trans-unit id="s8b33660e2ed7212c">
<source>When connecting via SSH, this keypair is used for authentication.</source>
<target>When connecting via SSH, this keypair is used for authentication.</target>
</trans-unit>
<trans-unit id="sa668bd79645c3e06">
<source>Kubeconfig</source>
<target>Kubeconfig</target>
</trans-unit>
<trans-unit id="sa85cfb884c17d85d">
<source>Verify Kubernetes API SSL Certificate</source>
<target>Verify Kubernetes API SSL Certificate</target>
</trans-unit>
<trans-unit id="se78364ee913ae2bd">
<source>New outpost integration</source>
<target>New outpost integration</target>
</trans-unit>
<trans-unit id="s68d69ad0271c8ef6">
<source>Create a new outpost integration.</source>
<target>Create a new outpost integration.</target>
</trans-unit>
<trans-unit id="sae239213b7c70376">
<source>State</source>
<target>State</target>
</trans-unit>
<trans-unit id="sb96629f50f2e7fab">
<source>Unhealthy</source>
<target>Unhealthy</target>
</trans-unit>
<trans-unit id="sa8e255492bb6ae0d">
<source>Outpost integration(s)</source>
<target>Outpost integration(s)</target>
</trans-unit>
<trans-unit id="s9d18948d25c68d66">
<source>Successfully generated certificate-key pair.</source>
<target>Successfully generated certificate-key pair.</target>
</trans-unit>
<trans-unit id="sd4ac926e4ebb1cd7">
<source>Common Name</source>
<target>Common Name</target>
</trans-unit>
<trans-unit id="s592425143c4f5834">
<source>Subject-alt name</source>
<target>Subject-alt name</target>
</trans-unit>
<trans-unit id="se9d0f12f95b14095">
<source>Optional, comma-separated SubjectAlt Names.</source>
<target>Optional, comma-separated SubjectAlt Names.</target>
</trans-unit>
<trans-unit id="s7609ee54e8a7b05a">
<source>Validity days</source>
<target>Validity days</target>
</trans-unit>
<trans-unit id="s4c24b2baa377e870">
<source>Successfully updated certificate-key pair.</source>
<target>Successfully updated certificate-key pair.</target>
</trans-unit>
<trans-unit id="s122f308b5f198ba7">
<source>Successfully created certificate-key pair.</source>
<target>Successfully created certificate-key pair.</target>
</trans-unit>
<trans-unit id="s08a8716c214a0efb">
<source>PEM-encoded Certificate data.</source>
<target>PEM-encoded Certificate data.</target>
</trans-unit>
<trans-unit id="s6e612e5a6a359bbb">
<source>Optional Private Key. If this is set, you can use this keypair for encryption.</source>
<target>Optional Private Key. If this is set, you can use this keypair for encryption.</target>
</trans-unit>
<trans-unit id="s27ac7a47b390e3cb">
<source>Certificate-Key Pairs</source>
<target>Certificate-Key Pairs</target>
</trans-unit>
<trans-unit id="sb72ebab438cb2983">
<source>Import certificates of external providers or create certificates to sign requests with.</source>
<target>Import certificates of external providers or create certificates to sign requests with.</target>
</trans-unit>
<trans-unit id="s4b5af7736aedd6c1">
<source>Private key available?</source>
<target>Private key available?</target>
</trans-unit>
<trans-unit id="s1d6e16d86961c782">
<source>Certificate-Key Pair(s)</source>
<target>Certificate-Key Pair(s)</target>
</trans-unit>
<trans-unit id="sc1ce2f758935ff48">
<source>Managed by authentik</source>
<target>Managed by authentik</target>
</trans-unit>
<trans-unit id="sf53a78d889b6c775">
<source>Managed by authentik (Discovered)</source>
<target>Managed by authentik (Discovered)</target>
</trans-unit>
<trans-unit id="sef50d248448e0df1">
<source>Yes (<x id="0" equiv-text="${item.privateKeyType?.toUpperCase()}"/>)</source>
<target>Yes (
<x id="0" equiv-text="${item.privateKeyType?.toUpperCase()}"/>)</target>
</trans-unit>
<trans-unit id="s09205907b5b56cda">
<source>No</source>
<target>No</target>
</trans-unit>
<trans-unit id="s33aa05f435c29753">
<source>Update Certificate-Key Pair</source>
<target>Update Certificate-Key Pair</target>
</trans-unit>
<trans-unit id="seffdf887fed7f668">
<source>Certificate Fingerprint (SHA1)</source>
<target>Certificate Fingerprint (SHA1)</target>
</trans-unit>
<trans-unit id="sdd6b8b56a811080e">
<source>Certificate Fingerprint (SHA256)</source>
<target>Certificate Fingerprint (SHA256)</target>
</trans-unit>
<trans-unit id="s2a2d3e7c379e9518">
<source>Certificate Subject</source>
<target>Certificate Subject</target>
</trans-unit>
<trans-unit id="s351246c52548086a">
<source>Download Certificate</source>
<target>Download Certificate</target>
</trans-unit>
<trans-unit id="s47bd537a3bcebf19">
<source>Download Private key</source>
<target>Download Private key</target>
</trans-unit>
<trans-unit id="s3a5fec3d73ac9edc">
<source>Create Certificate-Key Pair</source>
<target>Create Certificate-Key Pair</target>
</trans-unit>
<trans-unit id="s45cb501abd43ba52">
<source>Generate</source>
<target>Generate</target>
</trans-unit>
<trans-unit id="sf9bddaf910f4eea5">
<source>Generate Certificate-Key Pair</source>
<target>Generate Certificate-Key Pair</target>
</trans-unit>
<trans-unit id="see2bcbc11bb91960">
<source>Successfully updated instance.</source>
<target>Successfully updated instance.</target>
</trans-unit>
<trans-unit id="s9e51d6de369f320b">
<source>Successfully created instance.</source>
<target>Successfully created instance.</target>
</trans-unit>
<trans-unit id="s92e91071c6a45eb4">
<source>Disabled blueprints are never applied.</source>
<target>Disabled blueprints are never applied.</target>
</trans-unit>
<trans-unit id="sf63c89c0604c288f">
<source>Local path</source>
<target>Local path</target>
</trans-unit>
<trans-unit id="sd6422f7004036cdd">
<source>OCI Registry</source>
<target>OCI Registry</target>
</trans-unit>
<trans-unit id="se2d65e13768468e0">
<source>Internal</source>
<target>Internal</target>
</trans-unit>
<trans-unit id="scbb7d3154da629f3">
<source>OCI URL, in the format of oci://registry.domain.tld/path/to/manifest.</source>
<target>OCI URL, in the format of oci://registry.domain.tld/path/to/manifest.</target>
</trans-unit>
<trans-unit id="s0195c0df7294228a">
<source>See more about OCI support here:</source>
<target>See more about OCI support here:</target>
</trans-unit>
<trans-unit id="sfae395b94a5a0040">
<source>Blueprint</source>
<target>Blueprint</target>
</trans-unit>
<trans-unit id="s7e1342d37124b65b">
<source>Configure the blueprint context, used for templating.</source>
<target>Configure the blueprint context, used for templating.</target>
</trans-unit>
<trans-unit id="s6ec8c9d11310300a">
<source>Orphaned</source>
<target>Orphaned</target>
</trans-unit>
<trans-unit id="saab79cd956ee56a9">
<source>Blueprints</source>
<target>Blueprints</target>
</trans-unit>
<trans-unit id="s6835db03209b4f94">
<source>Automate and template configuration within authentik.</source>
<target>Automate and template configuration within authentik.</target>
</trans-unit>
<trans-unit id="s23de62f931f7d754">
<source>Last applied</source>
<target>Last applied</target>
</trans-unit>
<trans-unit id="s2708cac1f4942708">
<source>Blueprint(s)</source>
<target>Blueprint(s)</target>
</trans-unit>
<trans-unit id="s880b8b70b22f9977">
<source>Update Blueprint</source>
<target>Update Blueprint</target>
</trans-unit>
<trans-unit id="sef3d102324bf8561">
<source>Create Blueprint Instance</source>
<target>Create Blueprint Instance</target>
</trans-unit>
<trans-unit id="s32a3efa23718e713">
<source>API Requests</source>
<target>API Requests</target>
</trans-unit>
<trans-unit id="sddb3b0176f437721">
<source>Open API Browser</source>
<target>Open API Browser</target>
</trans-unit>
<trans-unit id="s5be3c6d61cd9182f">
<source>Notifications</source>
<target>Notifications</target>
</trans-unit>
<trans-unit id="sa3438c7bb4e9cce8">
<source><x id="0" equiv-text="${this.unread}"/> unread</source>
<target>
<x id="0" equiv-text="${this.unread}"/>unread</target>
</trans-unit>
<trans-unit id="s6e6e737601f44b2c">
<source>Successfully cleared notifications</source>
<target>Successfully cleared notifications</target>
</trans-unit>
<trans-unit id="s8cda828dac449ea5">
<source>Clear all</source>
<target>Clear all</target>
</trans-unit>
<trans-unit id="s4207178ba0b99418">
<source>A newer version of the frontend is available.</source>
<target>A newer version of the frontend is available.</target>
</trans-unit>
<trans-unit id="s96b3cddf33e1c853">
web: refactor sidebar capabilities for categorical subsections (#7482) * web: break circular dependency between AKElement & Interface. This commit changes the way the root node of the web application shell is discovered by child components, such that the base class shared by both no longer results in a circular dependency between the two models. I've run this in isolation and have seen no failures of discovery; the identity token exists as soon as the Interface is constructed and is found by every item on the page. * web: fix broken typescript references This built... and then it didn't? Anyway, the current fix is to provide type information the AkInterface for the data that consumers require. * web: rollback dependabot's upgrade of context The most frustrating part of this is that I RAN THIS, dammit, with the updated context and the current Wizard, and it finished the End-to-End tests without complaint. * Due for amendment * Revert "Due for amendment" This reverts commit 829ad5d3f214fa163958593636b28300d010da42. * web: refactor sidebar capabilities for categorical subsections The project "Change Admin UI lists to have sublists per type" requires some initial changes to the UI to facilitate this request. The AdminSidebar is the principle target of this project, and it is embedded in the AdminInterface. To facilitate editing the AdminSidebar as an independent entity, AdminInterface has been moved into its own folder and the AdminSidebar extracted as a standalone Web Component. This removes, oh, about half the code from AdminInterface. A little cleanup with `classMap` was also committed. The rollup config was adjusted to find the new AdminInterface location. The Sidebar uses the global `config: Config` object to check for Enterprise capabilities. Rather than plumb all the way down through the Interface => AdminInterface -> AdminSidebar, I chose to make provide an alternative way of reaching the `config` object, as a *context*. Other configuration objects (Me, UiConfig, Tenant) interfaces will be contextualized as demand warrants. Demand will warrant. Just not yet. <sup>1</sup> The Sidebar has been refactored only slightly; the renderers are entirely the same as they were prior to extraction. What has been changed is the source of information: when we retrieve the current version we story *only* the information, and use type information to ensure that the version we store is the version we care about. The same is true of `impersonation`; we care only about the name of the person being impersonated being present, so we don't store anything else. Fetches have been moved from `firstUpdated` to the constructor. No reason to have the sidebar render twice if the network returns before the render is scheduled. Because the path used to identify the user being impersonated has changed, the `str()` references in the XLIFF files had to be adjusted. **This change is to a variable only and does not require translation.** --- <sup>1</sup> The code is littered with checks to `me()?`, `uiConfig?`, `config?`, etc. In the *context* of being logged in as an administrator those should never be in doubt. I intend to make our interfaces not have any doubt. * Function to help generate sizing solutions across Javascript and CSS. * web: refactor sidebar capabilities for categorical subsections Move open/close logic into the ak-admin-sidebar itself. This commit removes the responsibility for opening/closing the sidebar from the interface parent code and places it inside the sidebar entirely. Since the Django invocation passes none of the properties ak-interface-admin is capable of receiving, this seems like a safe operation. The sidebar now assumes the responsibility for hooking up the window event listeners for open/close and resize. On connection to the DOM, and on resize, the sidebar checks to see if the viewport width meets the criteria for a behavioral change (slide-overlay vs slide-push), and on slide-push automatically opens the sidebar on the assumption that there's plenty of room. In order to support more dynamic styling going forward, I've substituted the 1280px with 80rem, which is the same, but allows for some better styling if someone with older eyes needs to "zoom in" on the whole thing with a larger font size. The hide/show code involves "reaching up" to touch the host's classList. There's a comment indicating that this is a slightly fragile thing to do, but in a well-known way.
2023-11-20 18:24:59 +00:00
<source>You're currently impersonating <x id="0" equiv-text="${this.impersonation}"/>. Click to stop.</source>
web: Replace lingui.js with lit-localize (#5761) * \#\# Details web: replace lingui with lit/localize \#\# Changes This rather massive shift replaces the lingui and `t()` syntax with lit-localize, XLIFF, and the `msg()` syntax used by lit-localize. 90% of this work was mechanized; simple perl scripts found and replaced all uses of `t()` with the appropriate corresponding syntax for `msg()` and `msg(str())`. The XLIFF files were auto-generated from the PO files. They have not been audited, and they should be checked over by professional translators. The actual _strings_ have not been changed, but as this was a mechanized change there is always the possibility of mis-translation-- not by the translator, but by the script. * web: revise lit/localize: fix two installation issues. * web: revise localization TL;DR: - Replaced all of Lingui's `t()` syntax with `msg()` syntax. - Mechanically (i.e with a script) converted all of the PO files to XLIFF files - Refactored the localization code to be a bit smarter: - the function `getBestMatchLocale` takes the locale lists and a requested locale, and returns the first match of: - The locale's code exactly matches the requested locale - The locale code exactly matches the prefix of the requested locale (i.e the "en" part of "en-US") - the locale code's prefix exactly matches the prefix of the requested locale This function is passed to lit-locate's `loadLocale()`. - `activateLocale()` just calls `loadLocale()` now. - `autodetectLanguage` searches the following, and picks the first that returns a valid locale object, before passing it to `loadLocale()`: - The User's settings - A `?locale=` component found in `window.location.search` - The `window.navigator.language` field - English The `msg()` only runs when it's run. This seems obvious, but it means that you cannot cache strings at load time; they must be kept inside functions that are re-run so that the `msg()` engine can look up the strings in the preferred language of the user at that moment. You can use thunks-of-strings if you really need them that way. * Including the 'xliff-converter' in case anyone wants to review it. * The xliff-converter is tagged as 'xliff-converter', but has been deleted. \#\# Details - Resolves #5171 \#\# Changes \#\#\# New Features - Adds a "Add an Application" to the LibraryView if there are no applications and the user is an administrator. \#\#\# Breaking Changes - Adds breaking change which causes \<issue\>. \#\# Checklist - [ ] Local tests pass (`ak test authentik/`) - [ ] The code has been formatted (`make lint-fix`) If an API change has been made - [ ] The API schema has been updated (`make gen-build`) If changes to the frontend have been made - [ ] The code has been formatted (`make web`) - [ ] The translation files have been updated (`make i18n-extract`) If applicable - [ ] The documentation has been updated - [ ] The documentation has been formatted (`make website`) * web: fix redundant locales for zh suite. * web: prettier pass for locale update * web: localization moderization Changed the names of the lit-localize commands to make it clear they're part of the localization effort, and not just "build" and "extract". * update transifex config Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix package lock? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use build not compile Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: conversion to lit-localize The CI produced a list of problems that I hadn't caught earlier, due to a typo ("localize build" is correct, "localize compile" is not) I had left in package.json. They were minor and linty, but it was still wise to fix them. * web: replace lingui with lit/locale This commit fixes some minor linting issues that were hidden by a typo in package.json. The issues were not apparently problematic from a Javascript point of view, but they pointed to sloppy thinking in the progression of types through the system, so I cleaned them up and formalized the types from LocaleModule to AkLocale. * web: replace lingui with lit/localize One problem that has repeatedly come up is that localize's templates do not produce JavaScript that conforms with our shop style. I've replaced `build-locale` with a two-step that builds the locale *and* ensures that it conforms to the shop style via `prettier` every time. * web: replace lingui with lit-locale This commit applies the most recent bundle of translations to the new lit-locale aspect component. It also revises the algorithm for *finding* the correct locale, replacing the complex fall-back with some rather straightforward regular expressions. In the case of Chinese, the fallback comes at the end of the selection list, which may not be, er, politically valuable (since Taiwan and Hong Kong come before, being exceptions that need to be tested). If we need a different order for presentation, that'll be a future feature. * web: replace lingui with lit/locale Well, that was embarassing. --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-06-02 15:08:36 +00:00
<target>You're currently impersonating
web: refactor sidebar capabilities for categorical subsections (#7482) * web: break circular dependency between AKElement & Interface. This commit changes the way the root node of the web application shell is discovered by child components, such that the base class shared by both no longer results in a circular dependency between the two models. I've run this in isolation and have seen no failures of discovery; the identity token exists as soon as the Interface is constructed and is found by every item on the page. * web: fix broken typescript references This built... and then it didn't? Anyway, the current fix is to provide type information the AkInterface for the data that consumers require. * web: rollback dependabot's upgrade of context The most frustrating part of this is that I RAN THIS, dammit, with the updated context and the current Wizard, and it finished the End-to-End tests without complaint. * Due for amendment * Revert "Due for amendment" This reverts commit 829ad5d3f214fa163958593636b28300d010da42. * web: refactor sidebar capabilities for categorical subsections The project "Change Admin UI lists to have sublists per type" requires some initial changes to the UI to facilitate this request. The AdminSidebar is the principle target of this project, and it is embedded in the AdminInterface. To facilitate editing the AdminSidebar as an independent entity, AdminInterface has been moved into its own folder and the AdminSidebar extracted as a standalone Web Component. This removes, oh, about half the code from AdminInterface. A little cleanup with `classMap` was also committed. The rollup config was adjusted to find the new AdminInterface location. The Sidebar uses the global `config: Config` object to check for Enterprise capabilities. Rather than plumb all the way down through the Interface => AdminInterface -> AdminSidebar, I chose to make provide an alternative way of reaching the `config` object, as a *context*. Other configuration objects (Me, UiConfig, Tenant) interfaces will be contextualized as demand warrants. Demand will warrant. Just not yet. <sup>1</sup> The Sidebar has been refactored only slightly; the renderers are entirely the same as they were prior to extraction. What has been changed is the source of information: when we retrieve the current version we story *only* the information, and use type information to ensure that the version we store is the version we care about. The same is true of `impersonation`; we care only about the name of the person being impersonated being present, so we don't store anything else. Fetches have been moved from `firstUpdated` to the constructor. No reason to have the sidebar render twice if the network returns before the render is scheduled. Because the path used to identify the user being impersonated has changed, the `str()` references in the XLIFF files had to be adjusted. **This change is to a variable only and does not require translation.** --- <sup>1</sup> The code is littered with checks to `me()?`, `uiConfig?`, `config?`, etc. In the *context* of being logged in as an administrator those should never be in doubt. I intend to make our interfaces not have any doubt. * Function to help generate sizing solutions across Javascript and CSS. * web: refactor sidebar capabilities for categorical subsections Move open/close logic into the ak-admin-sidebar itself. This commit removes the responsibility for opening/closing the sidebar from the interface parent code and places it inside the sidebar entirely. Since the Django invocation passes none of the properties ak-interface-admin is capable of receiving, this seems like a safe operation. The sidebar now assumes the responsibility for hooking up the window event listeners for open/close and resize. On connection to the DOM, and on resize, the sidebar checks to see if the viewport width meets the criteria for a behavioral change (slide-overlay vs slide-push), and on slide-push automatically opens the sidebar on the assumption that there's plenty of room. In order to support more dynamic styling going forward, I've substituted the 1280px with 80rem, which is the same, but allows for some better styling if someone with older eyes needs to "zoom in" on the whole thing with a larger font size. The hide/show code involves "reaching up" to touch the host's classList. There's a comment indicating that this is a slightly fragile thing to do, but in a well-known way.
2023-11-20 18:24:59 +00:00
<x id="0" equiv-text="${this.impersonation}"/>. Click to stop.</target>
web: Replace lingui.js with lit-localize (#5761) * \#\# Details web: replace lingui with lit/localize \#\# Changes This rather massive shift replaces the lingui and `t()` syntax with lit-localize, XLIFF, and the `msg()` syntax used by lit-localize. 90% of this work was mechanized; simple perl scripts found and replaced all uses of `t()` with the appropriate corresponding syntax for `msg()` and `msg(str())`. The XLIFF files were auto-generated from the PO files. They have not been audited, and they should be checked over by professional translators. The actual _strings_ have not been changed, but as this was a mechanized change there is always the possibility of mis-translation-- not by the translator, but by the script. * web: revise lit/localize: fix two installation issues. * web: revise localization TL;DR: - Replaced all of Lingui's `t()` syntax with `msg()` syntax. - Mechanically (i.e with a script) converted all of the PO files to XLIFF files - Refactored the localization code to be a bit smarter: - the function `getBestMatchLocale` takes the locale lists and a requested locale, and returns the first match of: - The locale's code exactly matches the requested locale - The locale code exactly matches the prefix of the requested locale (i.e the "en" part of "en-US") - the locale code's prefix exactly matches the prefix of the requested locale This function is passed to lit-locate's `loadLocale()`. - `activateLocale()` just calls `loadLocale()` now. - `autodetectLanguage` searches the following, and picks the first that returns a valid locale object, before passing it to `loadLocale()`: - The User's settings - A `?locale=` component found in `window.location.search` - The `window.navigator.language` field - English The `msg()` only runs when it's run. This seems obvious, but it means that you cannot cache strings at load time; they must be kept inside functions that are re-run so that the `msg()` engine can look up the strings in the preferred language of the user at that moment. You can use thunks-of-strings if you really need them that way. * Including the 'xliff-converter' in case anyone wants to review it. * The xliff-converter is tagged as 'xliff-converter', but has been deleted. \#\# Details - Resolves #5171 \#\# Changes \#\#\# New Features - Adds a "Add an Application" to the LibraryView if there are no applications and the user is an administrator. \#\#\# Breaking Changes - Adds breaking change which causes \<issue\>. \#\# Checklist - [ ] Local tests pass (`ak test authentik/`) - [ ] The code has been formatted (`make lint-fix`) If an API change has been made - [ ] The API schema has been updated (`make gen-build`) If changes to the frontend have been made - [ ] The code has been formatted (`make web`) - [ ] The translation files have been updated (`make i18n-extract`) If applicable - [ ] The documentation has been updated - [ ] The documentation has been formatted (`make website`) * web: fix redundant locales for zh suite. * web: prettier pass for locale update * web: localization moderization Changed the names of the lit-localize commands to make it clear they're part of the localization effort, and not just "build" and "extract". * update transifex config Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix package lock? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use build not compile Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: conversion to lit-localize The CI produced a list of problems that I hadn't caught earlier, due to a typo ("localize build" is correct, "localize compile" is not) I had left in package.json. They were minor and linty, but it was still wise to fix them. * web: replace lingui with lit/locale This commit fixes some minor linting issues that were hidden by a typo in package.json. The issues were not apparently problematic from a Javascript point of view, but they pointed to sloppy thinking in the progression of types through the system, so I cleaned them up and formalized the types from LocaleModule to AkLocale. * web: replace lingui with lit/localize One problem that has repeatedly come up is that localize's templates do not produce JavaScript that conforms with our shop style. I've replaced `build-locale` with a two-step that builds the locale *and* ensures that it conforms to the shop style via `prettier` every time. * web: replace lingui with lit-locale This commit applies the most recent bundle of translations to the new lit-locale aspect component. It also revises the algorithm for *finding* the correct locale, replacing the complex fall-back with some rather straightforward regular expressions. In the case of Chinese, the fallback comes at the end of the selection list, which may not be, er, politically valuable (since Taiwan and Hong Kong come before, being exceptions that need to be tested). If we need a different order for presentation, that'll be a future feature. * web: replace lingui with lit/locale Well, that was embarassing. --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-06-02 15:08:36 +00:00
</trans-unit>
<trans-unit id="s7031e6928c44cedd">
<source>User interface</source>
<target>User interface</target>
</trans-unit>
<trans-unit id="s8849ece8c65e3a18">
<source>Dashboards</source>
<target>Dashboards</target>
</trans-unit>
<trans-unit id="sc265a3e29e1206e4">
<source>Events</source>
<target>Events</target>
</trans-unit>
<trans-unit id="s4f1ad6b48a5df506">
<source>Logs</source>
<target>Logs</target>
</trans-unit>
<trans-unit id="s1823625e6f831d73">
<source>Customisation</source>
<target>Customisation</target>
</trans-unit>
<trans-unit id="sc0829ee663ced008">
<source>Directory</source>
<target>Directory</target>
</trans-unit>
<trans-unit id="sa81e2cdaf6921adc">
<source>System</source>
<target>System</target>
</trans-unit>
<trans-unit id="s5515a897ae98bed9">
<source>Certificates</source>
<target>Certificates</target>
</trans-unit>
<trans-unit id="s6b79e73ca77148a0">
<source>Outpost Integrations</source>
<target>Outpost Integrations</target>
</trans-unit>
<trans-unit id="sab85321d3b0840b7">
<source>API request failed</source>
<target>API request failed</target>
</trans-unit>
<trans-unit id="sa3599457b9418bc5">
<source>User's avatar</source>
<target>User's avatar</target>
</trans-unit>
<trans-unit id="s9bd9ba84819493d4">
<source>Something went wrong! Please try again later.</source>
<target>Something went wrong! Please try again later.</target>
</trans-unit>
<trans-unit id="s4090dd0c0e45988b">
<source>Request ID</source>
<target>Request ID</target>
</trans-unit>
<trans-unit id="s4d7fe7be1c49896c">
<source>You may close this page now.</source>
<target>You may close this page now.</target>
</trans-unit>
<trans-unit id="sf8c76d5fb408de7b">
<source>You're about to be redirect to the following URL.</source>
<target>You're about to be redirect to the following URL.</target>
</trans-unit>
<trans-unit id="s197420b40df164f8">
<source>Follow redirect</source>
<target>Follow redirect</target>
</trans-unit>
<trans-unit id="sa11e92683c5860c7">
<source>Request has been denied.</source>
<target>Request has been denied.</target>
</trans-unit>
<trans-unit id="s8939f574b096054a">
<source>Not you?</source>
<target>Not you?</target>
</trans-unit>
<trans-unit id="sc4eedb434536bdb4">
<source>Need an account?</source>
<target>Need an account?</target>
</trans-unit>
<trans-unit id="s38f774cd7e9b9dad">
<source>Sign up.</source>
<target>Sign up.</target>
</trans-unit>
<trans-unit id="sa03aa46068460c95">
<source>Forgot username or password?</source>
<target>Forgot username or password?</target>
</trans-unit>
<trans-unit id="s4a87445f3108db7c">
<source>Select one of the sources below to login.</source>
<target>Select one of the sources below to login.</target>
</trans-unit>
<trans-unit id="s091d5407b5b32e84">
<source>Or</source>
<target>Or</target>
</trans-unit>
<trans-unit id="se5fd752dbbc3cd28">
<source>Use a security key</source>
<target>Use a security key</target>
</trans-unit>
<trans-unit id="s670ad066cc0e50a3">
<source>Login to continue to <x id="0" equiv-text="${this.challenge.applicationPre}"/>.</source>
<target>Login to continue to
<x id="0" equiv-text="${this.challenge.applicationPre}"/>.</target>
</trans-unit>
<trans-unit id="scf5ce91bfba10a61">
<source>Please enter your password</source>
<target>Please enter your password</target>
</trans-unit>
<trans-unit id="s85366fac18679f28">
<source>Forgot password?</source>
<target>Forgot password?</target>
</trans-unit>
<trans-unit id="s14c552fb0a4c0186">
<source>Application requires following permissions:</source>
<target>Application requires following permissions:</target>
</trans-unit>
<trans-unit id="s7073489bb01b3c24">
<source>Application already has access to the following permissions:</source>
<target>Application already has access to the following permissions:</target>
</trans-unit>
<trans-unit id="s98dc556f8bf707dc">
<source>Application requires following new permissions:</source>
<target>Application requires following new permissions:</target>
</trans-unit>
<trans-unit id="sbd19064fc3f405c1">
<source>Check your Inbox for a verification email.</source>
<target>Check your Inbox for a verification email.</target>
</trans-unit>
<trans-unit id="s8aff572e64b7936b">
<source>Send Email again.</source>
<target>Send Email again.</target>
</trans-unit>
<trans-unit id="sdc323c6af4ae9f01">
<source>Successfully copied TOTP Config.</source>
<target>Successfully copied TOTP Config.</target>
</trans-unit>
<trans-unit id="s3687049d1af562c4">
<source>Copy</source>
<target>Copy</target>
</trans-unit>
<trans-unit id="s3643189d1abbb7f4">
<source>Code</source>
<target>Code</target>
</trans-unit>
<trans-unit id="sfe1c86b42ba13376">
<source>Please enter your TOTP Code</source>
<target>Please enter your TOTP Code</target>
</trans-unit>
<trans-unit id="sc2ec367e3108fe65">
<source>Duo activation QR code</source>
<target>Duo activation QR code</target>
</trans-unit>
<trans-unit id="sc5668cb23167e9bb">
<source>Alternatively, if your current device has Duo installed, click on this link:</source>
<target>Alternatively, if your current device has Duo installed, click on this link:</target>
</trans-unit>
<trans-unit id="s721d94ae700b5dfd">
<source>Duo activation</source>
<target>Duo activation</target>
</trans-unit>
<trans-unit id="s708d9a4a0db0be8f">
<source>Check status</source>
<target>Check status</target>
</trans-unit>
<trans-unit id="s31fba571065f2c87">
<source>Make sure to keep these tokens in a safe place.</source>
<target>Make sure to keep these tokens in a safe place.</target>
</trans-unit>
<trans-unit id="sc0a0c87d5c556c38">
<source>Phone number</source>
<target>Phone number</target>
</trans-unit>
<trans-unit id="s04c1210202f48dc9">
<source>Please enter your Phone number.</source>
<target>Please enter your Phone number.</target>
</trans-unit>
<trans-unit id="seb0c08d9f233bbfe">
<source>Please enter the code you received via SMS</source>
<target>Please enter the code you received via SMS</target>
</trans-unit>
<trans-unit id="s2b7dbba348234a36">
<source>A code has been sent to you via SMS.</source>
<target>A code has been sent to you via SMS.</target>
</trans-unit>
<trans-unit id="sa84adff85b5e505c">
<source>Open your two-factor authenticator app to view your authentication code.</source>
<target>Open your two-factor authenticator app to view your authentication code.</target>
</trans-unit>
<trans-unit id="s7abc9d08b0f70fd6">
<source>Static token</source>
<target>Static token</target>
</trans-unit>
<trans-unit id="s844fea0bfb10a72a">
<source>Authentication code</source>
<target>Authentication code</target>
</trans-unit>
<trans-unit id="s3cd84e82e83e35ad">
<source>Please enter your code</source>
<target>Please enter your code</target>
</trans-unit>
<trans-unit id="s18b910437b73e8e8">
<source>Return to device picker</source>
<target>Return to device picker</target>
</trans-unit>
<trans-unit id="sbcf8604929b6a27a">
<source>Sending Duo push notification</source>
<target>Sending Duo push notification</target>
</trans-unit>
<trans-unit id="s3b68883dda2682ed">
<source>Assertions is empty</source>
<target>Assertions is empty</target>
</trans-unit>
<trans-unit id="sbbb7318812d64e51">
<source>Error when creating credential: <x id="0" equiv-text="${err}"/></source>
<target>Error when creating credential:
<x id="0" equiv-text="${err}"/></target>
</trans-unit>
<trans-unit id="sfe199b2564b66054">
<source>Error when validating assertion on server: <x id="0" equiv-text="${err}"/></source>
<target>Error when validating assertion on server:
<x id="0" equiv-text="${err}"/></target>
</trans-unit>
<trans-unit id="se409d01b52c4e12f">
<source>Retry authentication</source>
<target>Retry authentication</target>
</trans-unit>
<trans-unit id="s8d857061510fe794">
<source>Duo push-notifications</source>
<target>Duo push-notifications</target>
</trans-unit>
<trans-unit id="s47490298c17b753a">
<source>Receive a push notification on your device.</source>
<target>Receive a push notification on your device.</target>
</trans-unit>
<trans-unit id="s16bc281dce5685e8">
<source>Authenticator</source>
<target>Authenticator</target>
</trans-unit>
<trans-unit id="sdefec5401bf67eba">
<source>Use a security key to prove your identity.</source>
<target>Use a security key to prove your identity.</target>
</trans-unit>
<trans-unit id="sd6a025d66f2637d1">
<source>Traditional authenticator</source>
<target>Traditional authenticator</target>
</trans-unit>
<trans-unit id="sb25e689e00c61829">
<source>Use a code-based authenticator.</source>
<target>Use a code-based authenticator.</target>
</trans-unit>
<trans-unit id="s9e568afec3810bfe">
<source>Recovery keys</source>
<target>Recovery keys</target>
</trans-unit>
<trans-unit id="sb17e8c70f9a05c77">
<source>In case you can't access any other method.</source>
<target>In case you can't access any other method.</target>
</trans-unit>
<trans-unit id="s97f2dc19fa556a6a">
<source>SMS</source>
<target>SMS</target>
</trans-unit>
<trans-unit id="s0e516232f2ab4e04">
<source>Tokens sent via SMS.</source>
<target>Tokens sent via SMS.</target>
</trans-unit>
<trans-unit id="s6ae0d087036e6d6d">
<source>Select an authentication method.</source>
<target>Select an authentication method.</target>
</trans-unit>
<trans-unit id="sac17f177f884e238">
<source>Stay signed in?</source>
<target>Stay signed in?</target>
</trans-unit>
<trans-unit id="s859b2e00391da380">
<source>Select Yes to reduce the number of times you're asked to sign in.</source>
<target>Select Yes to reduce the number of times you're asked to sign in.</target>
</trans-unit>
<trans-unit id="s420d2cdedcaf8cd0">
<source>Authenticating with Plex...</source>
<target>Authenticating with Plex...</target>
</trans-unit>
<trans-unit id="s2ddbebcb8a49b005">
<source>Waiting for authentication...</source>
<target>Waiting for authentication...</target>
</trans-unit>
<trans-unit id="sb15fe7b9d09bb419">
<source>If no Plex popup opens, click the button below.</source>
<target>If no Plex popup opens, click the button below.</target>
</trans-unit>
<trans-unit id="sbc625b4c669b9ce8">
<source>Open login</source>
<target>Open login</target>
</trans-unit>
<trans-unit id="sd766cdc29b25ff95">
<source>Authenticating with Apple...</source>
<target>Authenticating with Apple...</target>
</trans-unit>
<trans-unit id="s2c8189544e3ea679">
<source>Retry</source>
<target>Retry</target>
</trans-unit>
<trans-unit id="sc1589121ae2f5f92">
<source>Enter the code shown on your device.</source>
<target>Enter the code shown on your device.</target>
</trans-unit>
<trans-unit id="s67664f8ee9aea98d">
<source>Please enter your Code</source>
<target>Please enter your Code</target>
</trans-unit>
<trans-unit id="s455a8fc21077e7f9">
<source>You've successfully authenticated your device.</source>
<target>You've successfully authenticated your device.</target>
</trans-unit>
<trans-unit id="s3ab772345f78aee0">
<source>Flow inspector</source>
<target>Flow inspector</target>
</trans-unit>
<trans-unit id="s502884e1977b2c06">
<source>Next stage</source>
<target>Next stage</target>
</trans-unit>
<trans-unit id="sb3fa80ccfa97ee54">
<source>Stage name</source>
<target>Stage name</target>
</trans-unit>
<trans-unit id="sbea3c1e4f2fd623d">
<source>Stage kind</source>
<target>Stage kind</target>
</trans-unit>
<trans-unit id="s2bc8aa1740d3da34">
<source>Stage object</source>
<target>Stage object</target>
</trans-unit>
<trans-unit id="sc3e1c4f1fff8e1ca">
<source>This flow is completed.</source>
<target>This flow is completed.</target>
</trans-unit>
<trans-unit id="s342eccabf83c9bde">
<source>Plan history</source>
<target>Plan history</target>
</trans-unit>
<trans-unit id="sb2f307e79d20bb56">
<source>Current plan context</source>
<target>Current plan context</target>
</trans-unit>
<trans-unit id="sa13e6c8310000e30">
<source>Session ID</source>
<target>Session ID</target>
</trans-unit>
<trans-unit id="s6fe64b4625517333">
<source>Powered by authentik</source>
<target>Powered by authentik</target>
</trans-unit>
<trans-unit id="sdf34a5599d66f85c">
<source>Background image</source>
<target>Background image</target>
</trans-unit>
<trans-unit id="s7fa4e5e409d43573">
<source>Error creating credential: <x id="0" equiv-text="${err}"/></source>
<target>Error creating credential:
<x id="0" equiv-text="${err}"/></target>
</trans-unit>
<trans-unit id="s9d95f09deb601f34">
<source>Server validation of credential failed: <x id="0" equiv-text="${err}"/></source>
<target>Server validation of credential failed:
<x id="0" equiv-text="${err}"/></target>
</trans-unit>
<trans-unit id="s6c8f05e3be04f62a">
<source>Register device</source>
<target>Register device</target>
</trans-unit>
<trans-unit id="s3fb39fc45e840f78">
<source>Refer to documentation</source>
</trans-unit>
<trans-unit id="sc741dfb09d3395f0">
<source>No Applications available.</source>
<target>No Applications available.</target>
</trans-unit>
<trans-unit id="sf34026321b35315c">
<source>Either no applications are defined, or you dont have access to any.</source>
</trans-unit>
<trans-unit id="s1cf2298d92c327a6">
<source>My Applications</source>
<target>My Applications</target>
</trans-unit>
<trans-unit id="s2656433a3b1f7e86">
<source>My applications</source>
<target>My applications</target>
</trans-unit>
<trans-unit id="s06c92148da82be0d">
<source>Change your password</source>
<target>Change your password</target>
</trans-unit>
<trans-unit id="sff50532a2d85e32e">
<source>Change password</source>
<target>Change password</target>
</trans-unit>
<trans-unit id="saf63d34c8601dd41">
<source><x id="0" equiv-text="${prompt.label}"/></source>
<target>
<x id="0" equiv-text="${prompt.label}"/>
</target>
</trans-unit>
<trans-unit id="s33f85f24c0f5f008">
<source>Save</source>
<target>Save</target>
</trans-unit>
<trans-unit id="s045c3b86aae073c1">
<source>Delete account</source>
<target>Delete account</target>
</trans-unit>
<trans-unit id="s4a6aa26413287069">
<source>Successfully updated details</source>
<target>Successfully updated details</target>
</trans-unit>
<trans-unit id="s6fcd9b5a87ceccd6">
<source>Open settings</source>
<target>Open settings</target>
</trans-unit>
<trans-unit id="s8c05cccd470f6b5f">
<source>No settings flow configured.</source>
<target>No settings flow configured.</target>
</trans-unit>
<trans-unit id="sb546eb04425e07fa">
<source>Update details</source>
<target>Update details</target>
</trans-unit>
<trans-unit id="s30205d424e710818">
<source>Successfully disconnected source</source>
<target>Successfully disconnected source</target>
</trans-unit>
<trans-unit id="s67dedada007d4067">
<source>Failed to disconnected source: <x id="0" equiv-text="${exc}"/></source>
<target>Failed to disconnected source:
<x id="0" equiv-text="${exc}"/></target>
</trans-unit>
<trans-unit id="sd2208cd1a767644b">
<source>Disconnect</source>
<target>Disconnect</target>
</trans-unit>
<trans-unit id="s7a4f059aaa029719">
<source>Connect</source>
<target>Connect</target>
</trans-unit>
<trans-unit id="sababff57115130a0">
<source>Error: unsupported source settings: <x id="0" equiv-text="${source.component}"/></source>
<target>Error: unsupported source settings:
<x id="0" equiv-text="${source.component}"/></target>
</trans-unit>
<trans-unit id="sd1031bddc66dc495">
<source>Connect your user account to the services listed below, to allow you to login using the service instead of traditional credentials.</source>
<target>Connect your user account to the services listed below, to allow you to login using the service instead of traditional credentials.</target>
</trans-unit>
<trans-unit id="s7968dbed9b106c29">
<source>No services available.</source>
<target>No services available.</target>
</trans-unit>
<trans-unit id="s3a135682bd30bdbb">
<source>Create App password</source>
<target>Create App password</target>
</trans-unit>
<trans-unit id="s588796ee929a2e4c">
<source>User details</source>
<target>User details</target>
</trans-unit>
<trans-unit id="s332a5235948c1a1d">
<source>Consent</source>
<target>Consent</target>
</trans-unit>
<trans-unit id="sff945d3f59b93c5e">
<source>MFA Devices</source>
<target>MFA Devices</target>
</trans-unit>
<trans-unit id="sc54aafeea9c9bab0">
<source>Connected services</source>
<target>Connected services</target>
</trans-unit>
<trans-unit id="sc6b4ebd37b7a91c7">
<source>Tokens and App passwords</source>
<target>Tokens and App passwords</target>
</trans-unit>
<trans-unit id="sba65ae54d6585c1a">
<source>Unread notifications</source>
<target>Unread notifications</target>
</trans-unit>
<trans-unit id="s5599c62bb78c631f">
<source>Admin interface</source>
<target>Admin interface</target>
</trans-unit>
<trans-unit id="s1298e361e40ee1c5">
<source>Stop impersonation</source>
<target>Stop impersonation</target>
</trans-unit>
<trans-unit id="s6abff64e7ff7fde9">
<source>Avatar image</source>
<target>Avatar image</target>
</trans-unit>
<trans-unit id="sbf9c5c5a8e5efad4">
<source>Failed</source>
<target>Failed</target>
</trans-unit>
<trans-unit id="se4cd073c125382af">
<source>Unsynced / N/A</source>
<target>Unsynced / N/A</target>
</trans-unit>
<trans-unit id="s21b3058faf874368">
<source>Outdated outposts</source>
<target>Outdated outposts</target>
</trans-unit>
<trans-unit id="s51f92b6fa76656ca">
<source>Unhealthy outposts</source>
<target>Unhealthy outposts</target>
</trans-unit>
<trans-unit id="s0fbf6dc6a1966408">
<source>Next</source>
<target>Next</target>
</trans-unit>
<trans-unit id="s4409ada9c5c2a7f8">
<source>Inactive</source>
<target>Inactive</target>
</trans-unit>
<trans-unit id="s7ec7036b249f4f22">
<source>Regular user</source>
<target>Regular user</target>
</trans-unit>
<trans-unit id="s27976e94b05c6970">
<source>Activate</source>
<target>Activate</target>
</trans-unit>
<trans-unit id="s1024166475850a65">
<source>Use Server URI for SNI verification</source>
</trans-unit>
<trans-unit id="se65beb94fffc3c4b">
<source>Required for servers using TLS 1.3+</source>
</trans-unit>
<trans-unit id="s5506b35a1bceb141">
<source>Client certificate keypair to authenticate against the LDAP Server's Certificate.</source>
</trans-unit>
<trans-unit id="s4647b2c92638d6fd">
<source>The certificate for the above configured Base DN. As a fallback, the provider uses a self-signed certificate.</source>
</trans-unit>
<trans-unit id="scd247ffad6e04ac0">
<source>TLS Server name</source>
</trans-unit>
<trans-unit id="s2acef4f6ba39bf11">
<source>DNS name for which the above configured certificate should be used. The certificate cannot be detected based on the base DN, as the SSL/TLS negotiation happens before such data is exchanged.</source>
</trans-unit>
<trans-unit id="s000ee3e634868b3c">
<source>TLS Client authentication certificate</source>
</trans-unit>
<trans-unit id="s5da52af9b083c29a">
<source>Model</source>
</trans-unit>
<trans-unit id="s3ba9b8aeb686d9f7">
<source>Match events created by selected model. When left empty, all models are matched.</source>
</trans-unit>
<trans-unit id="s254d527e3a53dbb7">
<source>Code-based MFA Support</source>
</trans-unit>
<trans-unit id="s1889ba2eaeec2f1e">
<source>When enabled, code-based multi-factor authentication can be used by appending a semicolon and the TOTP code to the password. This should only be enabled if all users that will bind to this provider have a TOTP device configured, as otherwise a password may incorrectly be rejected if it contains a semicolon.</source>
enterprise: initial enterprise (#5721) * initial Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add user type Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add external users Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add ui, add more logic, add public JWT validation key Signed-off-by: Jens Langhammer <jens@goauthentik.io> * revert to not use install_id as session jwt signing key Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix more Signed-off-by: Jens Langhammer <jens@goauthentik.io> * switch to PKI Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add more licensing stuff Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add install ID to form Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix bugs Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start adding tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fixes Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use x5c correctly Signed-off-by: Jens Langhammer <jens@goauthentik.io> * license checks Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use production CA Signed-off-by: Jens Langhammer <jens@goauthentik.io> * more Signed-off-by: Jens Langhammer <jens@goauthentik.io> * more UI stuff Signed-off-by: Jens Langhammer <jens@goauthentik.io> * rename to summary Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update locale, improve ui Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add direct button Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update link Signed-off-by: Jens Langhammer <jens@goauthentik.io> * format and such Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove old attributes from ldap Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove is_enterprise_licensed Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix admin interface styling issue Signed-off-by: Jens Langhammer <jens@goauthentik.io> * Update authentik/core/models.py Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com> Signed-off-by: Jens L. <jens@beryju.org> * fix default case Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Signed-off-by: Jens L. <jens@beryju.org> Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2023-07-17 15:57:08 +00:00
</trans-unit>
<trans-unit id="s9f9492d30a96b9c6">
<source>User type</source>
</trans-unit>
<trans-unit id="s0e427111d750cc02">
<source>Successfully updated license.</source>
</trans-unit>
<trans-unit id="s06ae64e621f302eb">
<source>Successfully created license.</source>
</trans-unit>
<trans-unit id="s2905c425adae99bd">
<source>Install ID</source>
</trans-unit>
<trans-unit id="sb18ec434a8a3aafb">
<source>License key</source>
</trans-unit>
<trans-unit id="s2e109263b73c12d5">
<source>Licenses</source>
</trans-unit>
<trans-unit id="sd49099e9522635f4">
<source>License(s)</source>
</trans-unit>
<trans-unit id="s3be1d90ffa46b7f1">
<source>Enterprise is in preview.</source>
</trans-unit>
<trans-unit id="sd22bd01bdf28c548">
<source>Cumulative license expiry</source>
</trans-unit>
<trans-unit id="sdeb6cee42435dd07">
<source>Update License</source>
</trans-unit>
<trans-unit id="s7df5b92a3f93544f">
<source>Warning: The current user count has exceeded the configured licenses.</source>
</trans-unit>
<trans-unit id="s0141f42936495787">
<source>Click here for more info.</source>
</trans-unit>
<trans-unit id="s7be2df39f727faa2">
<source>Enterprise</source>
</trans-unit>
<trans-unit id="s9ce7cc01fb9b5b53">
<source>Manage enterprise licenses</source>
</trans-unit>
<trans-unit id="sf9ebf11ac2645820">
<source>No licenses found.</source>
</trans-unit>
<trans-unit id="sa1db89262360550b">
<source>Send us feedback!</source>
</trans-unit>
<trans-unit id="s4015746f55a8d89f">
<source>Get a license</source>
</trans-unit>
<trans-unit id="sb2cbd06f8e25b47e">
<source>Go to Customer Portal</source>
</trans-unit>
<trans-unit id="sf58825457d61c429">
<source>Forecast internal users</source>
</trans-unit>
<trans-unit id="sde9a3f41977ec1f8">
<source>Estimated user count one year from now based on <x id="0" equiv-text="${this.forecast?.internalUsers}"/> current internal users and <x id="1" equiv-text="${this.forecast?.forecastedInternalUsers}"/> forecasted internal users.</source>
</trans-unit>
<trans-unit id="s4557b6b9da258643">
<source>Forecast external users</source>
</trans-unit>
<trans-unit id="sf52479d6daa0a4a8">
<source>Estimated user count one year from now based on <x id="0" equiv-text="${this.forecast?.externalUsers}"/> current external users and <x id="1" equiv-text="${this.forecast?.forecastedExternalUsers}"/> forecasted external users.</source>
</trans-unit>
<trans-unit id="s6196153c4b0c1ea0">
<source>Install</source>
</trans-unit>
<trans-unit id="s0285b4bd69130fa3">
<source>Install License</source>
</trans-unit>
<trans-unit id="scef2eb6a2bfe3110">
<source>Internal users might be users such as company employees, which will get access to the full Enterprise feature set.</source>
</trans-unit>
<trans-unit id="sf66389b04fcc219c">
<source>External users might be external consultants or B2C customers. These users don't get access to enterprise features.</source>
</trans-unit>
<trans-unit id="s77e8668a27dbc402">
<source>Service accounts should be used for machine-to-machine authentication or other automations.</source>
</trans-unit>
<trans-unit id="s28cbd874ba450b4e">
<source>Less details</source>
</trans-unit>
<trans-unit id="s8fa26f65aed77c96">
<source>More details</source>
</trans-unit>
<trans-unit id="s08df8d0a773a3ea0">
<source>Remove item</source>
</trans-unit>
<trans-unit id="s364c4f177a2f8322">
<source>Open API drawer</source>
</trans-unit>
<trans-unit id="s9ba989e69344ff29">
<source>Open Notification drawer</source>
</trans-unit>
<trans-unit id="s14bf17e2a1a2c381">
<source>Restart task</source>
</trans-unit>
<trans-unit id="s19409e8712ddd369">
<source>Add provider</source>
</trans-unit>
<trans-unit id="s1f7698c061c208c9">
<source>Open</source>
</trans-unit>
<trans-unit id="scc3487e74c5a3e89">
<source>Copy token</source>
</trans-unit>
<trans-unit id="s424f57afae0caac4">
<source>Add users</source>
</trans-unit>
<trans-unit id="sd9f67fbf3f86efcf">
<source>Add group</source>
</trans-unit>
<trans-unit id="s254a9a23dc1635df">
<source>Import devices</source>
</trans-unit>
<trans-unit id="sc4fdeccf14be5378">
<source>Execute</source>
</trans-unit>
<trans-unit id="s3b3c333481944862">
<source>Show details</source>
</trans-unit>
<trans-unit id="sb8f855b49234b81b">
<source>Apply</source>
</trans-unit>
<trans-unit id="s9d8b8aa2b404c2c8">
<source>Settings</source>
</trans-unit>
<trans-unit id="s7cfe12cd14df9950">
<source>Sign out</source>
</trans-unit>
<trans-unit id="s7caa8f7edb920909">
<source>The number of tokens generated whenever this stage is used. Every token generated per stage execution will be attached to a single static device.</source>
</trans-unit>
<trans-unit id="s4aacc4e0277c1042">
<source>Token length</source>
</trans-unit>
<trans-unit id="s6931695c4f563bc4">
<source>The length of the individual generated tokens. Can be increased to improve security.</source>
</trans-unit>
<trans-unit id="s0dd031b58ed4017c">
<source>Internal: <x id="0" equiv-text="${item.internalUsers}"/></source>
</trans-unit>
<trans-unit id="s57b07e524f8f5c2a">
<source>External: <x id="0" equiv-text="${item.externalUsers}"/></source>
</trans-unit>
<trans-unit id="s7f68101a50f526ee">
<source>Statically deny the flow. To use this stage effectively, disable *Evaluate when flow is planned* on the respective binding.</source>
</trans-unit>
<trans-unit id="s911a27022aba349f">
<source>Create and bind Policy</source>
</trans-unit>
<trans-unit id="sb1a4e9b288e2f005">
<source>Federation and Social login</source>
</trans-unit>
<trans-unit id="s6f367f5604d5056d">
<source>Create and bind Stage</source>
</trans-unit>
<trans-unit id="s1a65ee08832fbfe2">
<source>Flows and Stages</source>
</trans-unit>
<trans-unit id="s4ba4473f3d4ec896">
<source>New version available</source>
</trans-unit>
<trans-unit id="s6b1ed7507f26cb4a">
<source>Failure result</source>
</trans-unit>
<trans-unit id="s2e422519ed38f7d8">
<source>Pass</source>
</trans-unit>
<trans-unit id="s81a45c4fd11e8e1a">
<source>Don't pass</source>
</trans-unit>
<trans-unit id="s95b73e0f4e47eb9a">
<source>Result used when policy execution fails.</source>
</trans-unit>
<trans-unit id="s6a3cf855140b9511">
<source>Required: User verification must occur.</source>
</trans-unit>
<trans-unit id="sc498a3b05cfe2b08">
<source>Preferred: User verification is preferred if available, but not required.</source>
</trans-unit>
<trans-unit id="s9d2239d2b0402795">
<source>Discouraged: User verification should not occur.</source>
</trans-unit>
<trans-unit id="s428b7859907f6db2">
<source>Required: The authenticator MUST create a dedicated credential. If it cannot, the RP is prepared for an error to occur</source>
</trans-unit>
<trans-unit id="s33e3766d4a02b042">
<source>Preferred: The authenticator can create and store a dedicated credential, but if it doesn't that's alright too</source>
</trans-unit>
<trans-unit id="sfb852dd507c25c24">
<source>Discouraged: The authenticator should not create a dedicated credential</source>
</trans-unit>
<trans-unit id="s028d385389b5aac0">
<source>Lock the user out of this system</source>
</trans-unit>
<trans-unit id="sd2122c514f0778b5">
<source>Allow the user to log in and use this system</source>
</trans-unit>
<trans-unit id="s43fe853bf219a9b8">
<source>Temporarily assume the identity of this user</source>
</trans-unit>
<trans-unit id="se28b5f3fcadaeeb1">
<source>Enter a new password for this user</source>
</trans-unit>
<trans-unit id="s6f5bb31e2733ecd5">
<source>Create a link for this user to reset their password</source>
</trans-unit>
<trans-unit id="s67ac11d47f1ce794">
<source>WebAuthn requires this page to be accessed via HTTPS.</source>
</trans-unit>
<trans-unit id="se9e9e1d6799b86a5">
<source>WebAuthn not supported by browser.</source>
</trans-unit>
<trans-unit id="sff0ac1ace2d90709">
<source>Use this provider with nginx's auth_request or traefik's forwardAuth. Each application/domain needs its own provider. Additionally, on each domain, /outpost.goauthentik.io must be routed to the outpost (when using a managed outpost, this is done for you).</source>
</trans-unit>
<trans-unit id="scb58b8a60cad8762">
<source>Default relay state</source>
</trans-unit>
<trans-unit id="s6827a456c9dfc6ee">
<source>When using IDP-initiated logins, the relay state will be set to this value.</source>
</trans-unit>
<trans-unit id="s01794c0ee3629c1b">
<source>Flow Info</source>
</trans-unit>
<trans-unit id="s24bce955914b1f0a">
<source>Stage used to configure a WebAuthn authenticator (i.e. Yubikey, FaceID/Windows Hello).</source>
</trans-unit>
web: Application wizard v2 with tests (#7004) * A lot of comments about forms. * Adding comments to the wizard. * Broke out the text input into a single renderer. Still works as required. * web: Legibility in the ApplicationForm. This is a pretty good result. By using the LightDOM setting, this provides the existing Authentik form manager with access to the ak-form-horizontal-element components without having to do any cross-border magic. It's not ideal, and it shows up just how badly we've got patternfly splattered everywhere, but the actual results are remarkable. The patterns for text, switch, radio, textarea, file, and even select are smaller and easier here. I'm still noodling on what an unspread search-select element would look like. It's just dependency injection, so it ought to be as straightforward as that. * web: Marking down the start of the 'components' library. * web: Baby steps I become frustrated with my inability to make any progress on this project, so I decided to reach for a tool that I consider highly reliable but also incredibly time-consuming and boring: test driven development. In this case, I wrote a story about how I wanted to see the first page rendered: just put the HTML tag, completely unadorned, that will handle the first page of the wizard. Then, add an event handler that will send the updated content to some parent object, since what we really want is to orchestrate the state of the user's input with a centralized location. Then, rather than fiddling with the attributes and properties of the various pages, I wanted them to be able to "look up" the values they want, much as we'd expect a standalone form to be able to pull its values from the server, so I added a context object that receives the update event and incorporates the new knowledge about the state of the process into itself. The result is surprisingly satisfying: the first page renders cleanly, displays the content that we want, and as we fiddle with, we can *watch in real time* as the results of the context are updated and retransmitted to all receiving objects. And the sending object gets the results so it re-renders, but it ends up looking the same as it was before the render. * Now, it's starting to look like a complete package. The LDAP method is working, but there is a bug: the radio is sending the wrong value !?!?!?. Track that down, dammit. The search wrappers now resend their events as standard `input` events, and that actually seems to work well; the browser is decorating it with the right target, with the right `name` attribute, and since we have good definitions of the `value` as a string (the real value of any search object is its UUID4), that works quite well. Added search wrappers for CoreGroup and CryptoCertificate (CertificateKeyPairs), and the latter has flags for "use the first one if it's the only one" and "allow the display of keyless certificates." Not sure why `state()` is blocking the transmission of typing information from the typed element to the context handler, but it's a bug in the typechecker, and it's not a problem so far. * Now, it's starting to look like a complete package. The LDAP method is working, but there is a bug: the radio is sending the wrong value !?!?!?. Track that down, dammit. The search wrappers now resend their events as standard `input` events, and that actually seems to work well; the browser is decorating it with the right target, with the right `name` attribute, and since we have good definitions of the `value` as a string (the real value of any search object is its UUID4), that works quite well. Added search wrappers for CoreGroup and CryptoCertificate (CertificateKeyPairs), and the latter has flags for "use the first one if it's the only one" and "allow the display of keyless certificates." Not sure why `state()` is blocking the transmission of typing information from the typed element to the context handler, but it's a bug in the typechecker, and it's not a problem so far. * web: tracked down that weirld bug with the radio. Because radio inputs are actually multiples, the events handling for radio is... wonky. If we want our `<ak-radio>` component to be a unitary event dispatcher, saying "This is the element selected," we needed to do more than what was currently being handled. I've intercepted the events that we care about and have placed them into a controller that dictates both the setting and the re-render of the component. This makes it "controlled" (to use the Angular/React/Vue) language and depends on Lit's reactiveElement lifecycle to work, rather than trust the browser, but the browser's experience with respect to the `<input type=radio` is pretty bad: both input elements fire events, one for "losing selection" and one for "gaining selection". That can be very confusing to handle, so we funnel them down in our aggregate radio element to a single event, "selection changed". As a quality-of-life measure, I've also set the label to be unselectable; this means that a click on the label will trigger the selection event, and a long click will not disable selection or confuse the selection event generator. * web: now passing the precommit phase * web: a HACK for Storybook to inject the "use light theme" flag into the body. This isn't really a very good hack; what it does is say that every story is responsible for hacking its theme into the parent. This is very annoying, but it does mean that we can at least show our components in the best light. * web: ak-application-wizard-authentication-by-oauth, and many fixes! 1. Fixed `eventEmitter` so that if the detail object is a scalar, it will not attempt to "objectify" it. This was causing a bug where retrofitting the eventEmitter to some older components resulted in a detail of "some" being translated into ['s', 'o', 'm', 'e']. Not what is wanted. 2. Removed the "transitional form" from the existing components; they had a two-step where the web component class was just a wrapper around an independent rendering function. While this worked, it was only to make the case that they *were* independent rendering objects and could be supported with the right web component framework. We're halfway there now; the last step will be to transform the horizontal-element and various input CSS into componentized CSS, the way Patternfly-Elements is currently doing. 3. Fixed the `help` field so that it could take a string or a TemplateResult, and if the latter, don't bother wrapping it in the helper text functionality; just let it be its own thing. This supports the multi-line help of redirectURI as well as the `ak-utils-time-delta` capability. 4. Transform Oauth2ProviderForm to use the new components, to the best of our ability. Also used the `provider = this.wizard.provider` and `provider = this.instance` syntax to make the render function *completely portable*; it's the exact same text that is dropped into... 5. The complete `ak-application-wizard-authentication-by-oauth` component. They're so similar part of me wonders if I could push them both out to a common reference, or a collection of common references. Both components use the PropertyMapping and Sources, and both use the same collection of searches (Crypto, Flow). 6. A Storybook for `ak-application-wizard-authentication-by-oauth`, showing the works working. 7. New mocks for `authorizationFlow`, `propertyMappings`, and `hasJWKs`. This sequence has revealed a bug in the radio control. (It's always the radio control.) If the default doesn't match the current setting, the radio control doesn't behave as expected; it won't change when you fully expect that it should. I'll investigate how to harmonize those tomorrow. * web: Converted our toggle groups to a more streamlined implementation. * web: one more toggle group. * initial api and schema Signed-off-by: Jens Langhammer <jens@goauthentik.io> * separate blueprint importer from yaml parsing Signed-off-by: Jens Langhammer <jens@goauthentik.io> * cleanup Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: Replace ad-hoc toggle control with ak-toggle-group This commit replaces various ad-hoc implementations of the Patternfly Toggle Group HTML with a web component that encapsulates all of the needed behavior and exposes a single API with a single event handler, return the value of the option clicked. The results are: Lots of visual clutter is eliminated. A single link of: ``` <div class="pf-c-toggle-group__item"> <button class="pf-c-toggle-group__button ${this.mode === ProxyMode.Proxy ? "pf-m-selected" : ""}" type="button" @click=${() => { this.mode = ProxyMode.Proxy; }}> <span class="pf-c-toggle-group__text">${msg("Proxy")}</span> </button> </div> <div class="pf-c-divider pf-m-vertical" role="separator"></div> ``` Now looks like: ``` <option value=${ProxyMode.Proxy}>${msg("Proxy")}</option> ``` This also means that the three pages that used the Patternfly Toggle Group could eliminate all of their Patternfly PFToggleGroup needs, as well as the `justify-content: center` extension, which also eliminated the `css` import. The savings aren't as spectacular as I'd hoped: removed 178 lines, but added 123; total savings 55 lines of code. I still count this a win: we need never write another toggle component again, and any bugs, extensions or features we may want to add can be centralized or forked without risking the whole edifice. * web: minor code formatting issue. * add new "must_created" state to blueprints to prevent overwriting objects Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: adding a storybook for the ak-toggle-group component * Bugs found by CI/CD. * web: Replace ad-hoc search for CryptoCertificateKeyPairs with ak-crypto-certeficate-search This commit replaces various ad-hoc implementations of `search-select` for CryptoCertificateKeyPairs with a web component that encapsulates all of the needed behavior and exposes a single API. The results are: Lots of visual clutter is eliminated. A single search of: ```HTML <ak-search-select .fetchObjects=${async (query?: string): Promise<CertificateKeyPair[]> => { const args: CryptoCertificatekeypairsListRequest = { ordering: "name", hasKey: true, includeDetails: false, }; if (query !== undefined) { args.search = query; } const certificates = await new CryptoApi( DEFAULT_CONFIG, ).cryptoCertificatekeypairsList(args); return certificates.results; }} .renderElement=${(item: CertificateKeyPair): string => { return item.name; }} .value=${(item: CertificateKeyPair | undefined): string | undefined => { return item?.pk; }} .selected=${(item: CertificateKeyPair): boolean => { return this.instance?.tlsVerification === item.pk; }} ?blankable=${true} > </ak-search-select> ``` Now looks like: ```HTML <ak-crypto-certificate-search certificate=${this.instance?.tlsVerification}> </ak-crypto-certificate-search> ``` There are three searches that do not require there to be a valid key with the certificate; these are supported with the boolean property `nokey`; likewise, there is one search (in SAMLProviderForm) that states that if there is no current certificate in the SAMLProvider and only one certificate can be found in the Authentik database, use that one; this is supported with the boolean property `singleton`. These changes replace 382 lines of object-oriented invocations with 36 lines of declarative configuration, and 98 lines for the class. Overall, the code for "find a crypto certificate" has been reduced by 46%. Suggestions for a better word than `singleton` are welcome! * web: display tests for CryptoCertificateKeypair search This adds a Storybook for the CryptoCertificateKeypair search, including a mock fetch of the data. In the course of running the tests, we discovered that including the SearchSelect _class_ won't include the customElement declaration unless you include the whole file! Other bugs found: including the CSS from Storybook is different from that of LitElement native, so much so that the adapter needed to be included. FlowSearch had a similar bug. The problem only manifests when building via Webpack (which Storybook uses) and not Rollup, but we should support both in distribution. * Fixed behavioral problem with the radio; the `if` there was preventing the radio from reflecting the default correctly. The observed behavior was that the radio wouldn't "activate" until the item selected during the render pass was clicked on first. * Proxy Provider done. * web: Tactical change. Put all the variants on the second page; it's a longer list, but it's also easier to manage than all those required sub-options. * Rounding out the catalog. * web: SAML Manual Configuration Added a 'design document' that just kinda describes what I'm trying to do, in case I don't get this done by Friday Aug 11, 2023. I had two tables doing the same thing, so I merged them and then wrote a few map/filters to specialize them for those two use cases. Along the way I had to fiddle with the ESLint settings so that underscore-prefixed unused variables would be ignored. I cleaned up the visual appeal of the forms in the LDAP application. I was copy/pasting the "handleProviderEvent" function, so I pulled it out into ApplicationWizardProviderPageBase. Not so much a matter of abstraction as just disliking that kind of duplication; it served no purpose. * Added SAML Story to Storybook. * Web: This is coming together amazingly well. Like, almost too well. * web: 80% of the way there This commit includes the first three pages of the wizard, the completion of the wizard framework with evented handling, and control over progression. Some shortcomings of this design have become evident: it isn't possible to communicate between the steps' wrappers, as they are POJOs without access to the context. An imperative decision-making process has to be inserted in the orchestration layer, which is kinda annoying. But it looks good and it behaves correctly, to the extent that I've given it behavior. It's an excellent foundation. * Linting. * web: application wizard Found where the hook for form validity should go. Excellent! Now I just need to incorporate that basic validation into the business logic and we're good to go. * Turns out that was one layer too many; the topmost component was fine for maintaining the context. * It looks like my brilliant strategy has hit a snag. The idea is simple. Let's start with this picture: ``` <application-wizard .steps=${[... a collection of step objects ...]}> <wizard-main .steps=${(steps from above)}> <application-current-panel> <current-form> ``` - ApplicationWizard has a Context for the ApplicationProviderPair (or whatever it's going to be). This context does not know about the steps; it just knows about: the "application" object, the "provider" object, and a discriminator to know *which* provider the user has selected. - ApplicationWizard has Steps that, among other things, provides Panels for: - Application - Pick Provider - Configure Provider - Submit ApplicationProviderPair to the back-end - The WizardFrame renders the CurrentPanel for the CurrentStep The CurrentPanel gets its data from the ApplicationWizard in the form of a Context. It then sends messages (events) to ApplicationWizard about the contents of each field as the user is filling out the form, so that the ApplicationWizard can record those in the ApplicationProviderPair for later submission. When a CurrentForm is valid, the ApplicationWizard updates the Steps object to show that the "Next button" on the Wizard is now available. In this way, the user can progress through the system. When they get to the last page, we can provide in the ApplicationWizard with the means to submit the form and/or send the user back to the page with the validation failure. Problem: The context is being updated in real-time, which is triggering re-renders of the form. This leads to focus problems as the fields that are not yet valid are triggering "focus grab" behavior. This is a classic problem with "controlled" inputs. What we really want is for the CurrentPanel to not re-render at all, but to behave like a normal, uncontrolled form, and let the browser do most of the work. We still want the [Next] button to enable when the form is valid enough to permit that. --- Other details: I've ripped out a lot of Jen's work, which is probably a mistake. It's still preserved elsewhere. I've also cleaned up the various wizardly things to try and look organized. It *looks* like it should work, it just... doesn't. Not yet. * Late addition: I had an inspiration about how to reduce the way reactivity broke focus by, basically, removing the reactivity and managing the first-time-through lifecycle to prevent the update from causing refocus. It works well! Now I just need to test it. * This application fixes the bug with respect to the wizard-level context being updated incorrectly. Understandings: - To use uncontrolled inputs, which I prefer, the context object should not be a state or property at the level of consumers; it should not automatically re-render with every keystroke, i.e. "The React Way." We're using Web Components, [client-side validation](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation) exists on the platform already, and live-validation is problematic for any number of reasons. - The trade-off is that it is now necessary to re-render the target page of the wizard de-novo, but that's not really as big a deal as it sounds. Lit is ready to do that... and then nothing else until we request a change-of-page. Excellent. - The top level context *must* be a state, but it's better if it's a state never actually used by the top-level context container. The debate about whether or not to make that container a dumb one (`<slot></slot>`) or to merge it with the top-level object continues; here, I've merged it with the top-level wizard object, but that object does not refer to the state variable being managed in its render pass, so changes to it do not cause a re-render of the whole wizard. The purpose of the top-level page is to manage the *steps*, not the *content of any step*. A step may change dynamically based on the content of a step, but that's the same thing as *which step*. Lesson: always know what your state is *about*. - Deep merging is a complex subject, but here it's appropriate to our needs. * web: Application Wizard This commit combines a working (but very unpolished) version of the Application Wizard with Jen's code for the CoreTransactionApplicationRequest, resulting in a successful round trip. It fixes a number of bugs with the way ContextProducer decorators were being processed, such that they just weren't working with our current configuration (although they did work fine in Storybook); consumers didn't need to be fixed. It also *removes* the steps-aware context from the Wizard. That *may* be a mistake. To re-iterate, the `WizardFrame` provides the chrome for a Wizard: the button bar div, the breadcrumbs div, the header div, and it takes the steps object as its source of truth for all of the content. The `WizardContent` part of the application has two parts: The `WizardMain`, which wraps the frame and supplies the context for all the `WizardPanels`, and the `WizardPanels` themselves, which are dependent on a context from `WizardMain` for the data that populates each panel. YAGNI right now that the panels need to know anything about the steps, and the `WizardMain` can just pass a fresh `.steps` object to the `WizardFrame` when they need updating. Using props drilling may make more sense here. It certainy does *not* make sense for the panels. They need to be renderable on-demand, and they need to make sense of what they're rendering on-demand, so the function is ``` (panel code) => (context) => (rendered panel) ``` (Yes, that's curried notation. Deal.) * This commit includes the first WDIO test for the ApplicationWizard. It doesn't do much right now, but it does log in and navigate to the wizard successfully. * web: completed test for single application, provided new programming language to make it easier to write tests. * Almost there. Missing: The validation is currently not working as expected, and I cannot get the backend to give me meaningful data helping us "go back" to the field that wasn't valid. I really don't want to put all the meaningful validation on the front-end; that's the road to - perdition, the back-end must be usable by people less assiduous than we are. Also: Need to make the button bar work better; maybe each panel can provide a custom button bar if one is needed? * web: Test harness We have an end-to-end test harness that includes a trivially correct DSL for "This is what a user would do, do this": ``` const deleteProvider = (theSlug) => ([ ["button", '>>>ak-sidebar-item a[href="#/core/providers"]'], ["deletebox", `>>>a[href="#/core/applications/${theSlug}"]`], ["button", '>>>ak-forms-delete-bulk button[slot="trigger"]'], ["button", '>>>ak-forms-delete-bulk div[role="dialog"] ak-spinner-button'], ]); ``` It's now possible to target individual sequences of events this way. With a little creativity, we could have standalone functions that take parameters for our calls and just do them, without too much struggle. * web: Revised navigation After working with the navigation for awhile, I realized that it's a poor map; what I really wanted was a controller/view pair, where events flow up to the controller and then messages on "what to draw" flow down to the view. It work quite well, and the wizard frame is smaller and smarter for it. I've also moved the WDIO-driven tests into the 'tests' folder, because it (a) makes more sense to put them there, and (b) it prevents any confusion about who's in charge of node_modules. * web: Simplify, simplify, simplify Sort-of. This commit changes the way the "wizard step coordinator" layer works, giving the wizard writer much more power over button bar. It still assumes there are only three actions the wizard frame wants to commit: next, back, and close. This empowers the steps themselves to re-arrange their buttons and describe the rules through which transitions occur. * web: resetting the form is not working yet... I vehemently dislike the object-oriented "reset" command; every wizard should start with an absolutely fresh copy of the data upon entry. Refactoring the wizard to re-build its content from the inside is the correct way to go, but I don't have a good mental image of how to make the ModalButton and the component it invokes interact cleanly, which frustrates the hell out of me. * web: reset As I said, I greatly dislike having to be dependent upon "resets"; I prefer my data to be de novo going into a "new" transaction. That said, we work with what we've got; I've created an event generated by the wizard that says the modal just closed; anything wrapping and implementing the wizard can then capture that event and reset the data. I've also added a pair of functions that create the two states (what step, what form data) anew, so that resetting is as trivial as initializing (and is exactly the same, code-wise). * web: Without error handling, this is complete, but I still need @BeryJu (Jens) for help with the SAML Upload (it doesn't appear to be correctly handled?) and the error handling. * web: revise tests for wizard This commit replaces the previous WDIO instance with a more formal and straightforward process using the [pageobjects](https://martinfowler.com/bliki/PageObject.html). In this form, every major component has its own test suite, and a test is a sequence of exercises of those components. A test then becomes something as straightforward as: ``` await LoginPage.open(); await LoginPage.login("ken@goauthentik.io", "eat10bugs"); expect(await UserLibraryPage.pageHeader).toHaveText("My Applications"); await UserLibraryPage.goToAdmin(); expect(await AdminOverviewPage.pageHeader).toHaveText("Welcome, "); await AdminOverviewPage.openApplicationsListPage(); expect(await ApplicationsListPage.pageHeader).toHaveText("Applications"); ApplicationsListPage.startCreateApplicationWizard(); await ApplicationWizard.app.name.setValue(`Test application ${newId}`); await ApplicationWizard.nextButton.click(); await (await ApplicationWizard.getProviderType("ldapprovider")).click(); await ApplicationWizard.nextButton.click(); await ApplicationWizard.ldap.setBindFlow("default-authentication-flow"); await ApplicationWizard.nextButton.click(); await expect(await ApplicationWizard.commitMessage).toHaveText( "Your application has been saved" ); ``` Whether or not there's another layer of DSL in there or not, this is a pretty nice idiom for maintaining tests. * web: updating with forms and fixes for eslint complaints. * web/add webdriverIO testing layer This commit adds WebdriverIO as an end-to-end solution to unit testing. WebdriverIO can be run both locally and remotely, supports strong integration with web components, and is generally robust for use in pipelines. I'll confess to working through a tutorial on how to do this for web components, and this is just chapter 2 (I think there are 5 or so chapters...). There's a makefile, with help! If you just run `make` it tells you: ``` Specify a command. The choices are: help Show this help node_modules Runs `npm install` to prepare this feature precommit Run the precommit: spell check all comments, eslint with sonarJS, prettier-write test-good-login Test that we can log into the server. Requires a running instance of the server. test-bad-login Test that bad usernames and passwords create appropriate error messages ``` ... because Makefiles are documentation, and documentation belongs in Makefiles. I've chosen to go with a PageObject-oriented low-level DSL; what that means is that for each major components (a page, a form, a wizard), there's a class that provides human-readable names for human-interactable and human-viewable objects on the page. The LoginPage object, for example, has selectors for the username, password, submit button, and the failure alert; accessing those allows us to test for items as expected., and to write a DSL for "a good login" that's as straightforward as: ``` await LoginPage.open(); await LoginPage.login("ken@goauthentik.io", "eat10bugs"); await expect(UserLibraryPage.pageHeader).toHaveText("My applications"); ``` There was a *lot* of messing around with the LoginPage to get the username and password into the system. For example, I had to do this with all the `waitForClickable` and `waitForEnable` because we both keep the buttons inaccessible until the form has something and we "black out" the page (put a darkening filter over it) while accessing the flow, meaning there was a race condition such that the test would attempt to interact with the username or password field before it was accessible. But this works now, which is very nice. ``` JavaScript get inputUsername() { return $('>>>input[name="uidField"]'); } get btnSubmit() { return $('>>>button[type="submit"]'); } async username(username: string) { await this.inputUsername.waitForClickable(); await this.inputUsername.setValue(username); await this.btnSubmit.waitForEnabled(); await this.btnSubmit.click(); } ``` The bells & whistles of *Prettier*, *Eslint*, and *Codespell* have also been enabled. I do like my guardrails. * web/adding tests: added comments and cleaned up some administrative features. * web/test: changed the name of one test to reflect it's 'good' status * core/allow alternative postgres credentials This commit allows the `dev-reset` command in the Makefile to pick up and use credentials from the `.env` file if they are present, or fallback to the defaults provided if they are not. This is the only place in the Makefile where the database credentials are used directly against postgresql binaries. The syntax was tested with bash, zsh, and csh, and did not fail under those. The `$${:-}` syntax is a combination of a Makefile idiom for "Pass a single `$` to the environment where this command will be executed," and the shell expresion `${VARIABLE:-default}` means "dereference the environment variable; if it is undefined, used the default value provided." * Re-arrange sequence to avoid recursive make. Nothing wrong with recursive make; it just wasn't essential here. `migrate` is just a build target, not a task. * Cleanup according to the Usage: checkmake [options] <makefile>... checkmake -h | --help checkmake --version checkmake --list-rules Makefile linting tool. * core: added 'help' to the Makefile * get postgres config from authentik config loader Signed-off-by: Jens Langhammer <jens@goauthentik.io> * don't set -x by default Signed-off-by: Jens Langhammer <jens@goauthentik.io> * sort help Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update help strings Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: test LDAP wizard sequence * web: improve testing by adding test admin user via blueprint * This commit continues the application wizard buildout. In this commit are the following changes: - Added SCIM to the list of available providers - Fixed ForwardProxy so that its mode is set correctly. (This is a special case in the committer; I'm unhappy with that.) - Fixed the commit messages so that: - icons are set correctly (Success, Danger, Working) - icons are colored correctly according to state - commit message includes a `data-commit-state` field so tests can find it! - Merged the application wizard tests into a single test pass - Isolated common parts of the application wizard tests to reduce unnecessary repetition. All application tests are the same until you reach the provider section anyway. - Fixed the unit tests so they're finding the right error messages and are enabled to display them correctly. - Moved the test Form handlers into their own folder so they're not cluttering up the Pages folder. * web: add radius to application wizard This commit continues the application wizard buildout. In this commit are the following changes: - Fixed a width-setting bug in the Makefile `make help` feature (i.e "automate that stuff!") - Added Radius to the list of providers we can offer via the wizard - Added `launchUrl` and `UI Settings` to features of the application page the wizard can find - Changed 'SAML Manual Configuration' to just say "SAML Configuration" - Modified `ak-form-group` to take and honor the `aria-label` property (which in turn makes it easier to target specific forms with unit testing) - Reduced the log level for wdio to 'warn'; 'info' was super-spammy and not helpful. It can be put back with `--logLevel info` from the command line. * fix blueprints Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update package name Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add dependabot Signed-off-by: Jens Langhammer <jens@goauthentik.io> * prettier run Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add basic CI Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove hooks Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: application wizard refactor & completion This commit refactors the various components of the Wizard and ApplicationWizard, creating a much more maintainable and satisfying Wizard experience for both developers (i.e, *me* and *Jens* so far), and for the customer. The Wizard base has been refactored into three components: **AkWizardController** The `AkWizardController` provides the event listenters for the wizard; it hooks them up, recevies the events, and forwards them to the wizard. It unwraps the event objects and forwards the relevant messages contained in the events. It knows of three event categories: - Navigation requests (move to a different step) - Update requests (the current step has updated the business content) - Close requests (close or cancel the wizard). **ak-wizard-frame** The `ak-wizard-frame` is the ModalButton interface. It provides the Header, Breadcrumbs (nee` "navigation block"), Buttons, and a DIV into which the main content is rendered. **AkWizard** `AkWizard` is an *incomplete* implementation of the wizard. It's meant to be inherited by a child class, which will implement the rest. It extends `AKElement`. It provides the basic content needed, such as steps, currentStep (as an index), an accessor for the step itself, an accessor for the frame, and the interface to the `AkWizardController`. **ApplicationWizard** The `ApplicationWizard` itself has been refactored to accommodate these changes. It inherits from `AkWizard` and provides the business logic for what to do when a form updates, some custom logic for preventing moving through the wizard when the forms are incomplete, and a persistence layer for filling out different providers in the same session. It's simplified a *lot*. The types specified for `AkWizard` are pretty nifty, I think. I could wish the types being passed via the custom events were more robust, but [strongly typed custom events](https://github.com/lit/lit-element/issues/808) turn out to be quite the pain in the, er, neck. As it is, the `precommit` pass did very good at preventing the worst disasters. The steps themselves were re-written as objects so that they could take advantage of their `valid` and `disabled` states and provide more meaningful buttons and labels. I think it's a solid compromise, and it moved a lot of display logic out of the core `handleUpdate()` business method. The tests, such as they are, are passing. * Added comment describing new test. * web: ensuring copy from `main` is canon * web: fixes after merge * web: laying the groundwork for future expansion This commit is a hodge-podge of updates and changes to the web. Functional changes: - Makefile: Fixed a bug in the `help` section that prevented the WIDTH from being accurately calculated if `help` was included rather than in-lined. - ESLint: Modified the "unused vars" rule so that variables starting with an underline are not considered by the rule. This allows for elided variables in event handlers. It's not a perfect solution-- a better one would be to use Typescript's function-specialization typing, but there are too many places where we elide or ignore some variables in a function's usage that switching over to specialization would be a huge lift. - locale: It turns out, lit-locale does its own context management. We don't need to have a context at all in this space, and that's one less listener we need to attach t othe DOM. - ModalButton: A small thing, but using `nothing` instead of "html``" allows lit better control over rendering and reduces the number of actual renders of the page. - FormGroup: Provided a means to modify the aria-label, rather than stick with the just the word "Details." Specializing this field will both help users of screen readers in the future, and will allow test suites to find specific form groups now. - RadioButton: provide a more consistent interface to the RadioButton. First, we dispatch the events to the outside world, and we set the value locally so that the current `Form.ts` continues to behave as expected. We also prevent the "button lost value" event from propagating; this presents a unified select-like interface to users of the RadioButtonGroup. The current value semantics are preserved; other clients of the RadioButton do not see a change in behavior. - EventEmitter: If the custom event detail is *not* an object, do not use the object-like semantics for forwarding it; just send it as-is. - Comments: In the course of laying the groundwork for the application wizard, I throw a LOT of comments into the code, describing APIs, interfaces, class and function signatures, to better document the behavior inside and as signposts for future work. * web: permit arrays to be sent in custom events without interpolation. * actually use assignValue or rather serializeFieldRecursive Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: eslint & prettier fixes, plus small aesthetic differences. * Restoring this file. Not sure where it disappears to. * fix label in dark mode Signed-off-by: Jens Langhammer <jens@goauthentik.io> * SCIM Manuel -> SCIM Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix lint errors Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: better converter configuration, CSS repair, and forward-domain-proxy 1. Forward Domain Proxy. I wasn't sure if this method was appropriate for the wizard, but Jens says it is. I've added it. 2. In the process of doing so, I decided that the Provider.converter field was overly complexified; I tried too hard to reduce the number of functions I needed to define, but in the process outsourced some of the logic of converting the Wizard's dataset into a property typed request to the `commit` phase, which was inappropriate. All of the logic about a provider, aside from its display, should be here with the code that distinguishes between providers. This commit makes it so. 3. Small CSS fix: the fields inherited from the Proxy provider forms had some unexpected CSS which was causing a bit of a weird indent. That has been rectified. * web: running pre-commit after merge. * web: ensure the applications wizard tests finish after current changes * prettier has opinions. * web: application wizard spit & polish The "ApplicationWizardHint" now correctly uses the localstorage and allows the user to navigate back and see the message after it's been hidden, so that it will always be available during the test phase. The ApplicationList's old "Create Application Form" button has been restored for the purposes of the test phase. The ApplicationWizard is now available on both the ApplicationList and ProviderList pages. Tana and I discussed the microcopy, putting a stronger second-person "You can do..." twist onto the language, to give the user the sense of empowerment. The ShowHintController now has both "hide" and "show" operations, to support the hint restoration. * web: updated storybook stories for the wizard, illustration how "a simple wizard" is configured in source code and tested with storybook. * web: I hate getting spanked by prettier. * web: sometimes I wish I had lower standards Anyway, this was a very stupid bug, because by definition function definition arguments don't have uses, they're being defined, not implemented. Fixed, conf fixed to compensate, and consequences conquered. * move context from labs to main Signed-off-by: Jens Langhammer <jens@goauthentik.io> * Revert "move context from labs to main" This reverts commit 3718ee69048966d26b1c357a7d2653fbb3ab613b. * web: reify the data loop I was very unhappy with the "update this dot-path" mechanism I was using earlier; it was hard for me to read and understand what was happening, and I wrote the darned thing. I decided instead to go with a hard substitution model; each phase of the wizard is responsible for updating the *entire* payload, mostly by creating a new payload and substituting the field value associated with the event. On the receiver, we have to do that *again* to handle the swapping of providers when the user chooses one and then another. It looks clunky, and it is, but it's *legible*; a junior dev could understand what it's doing, and that's the goal. * Revert "web: reify the data loop" This reverts commit 09fedcacf02a90a021ce9e18c0eb4bec1ef48302. * web: revert the 'lit' to 'lit-labs' for task and context. --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-10-18 19:43:37 +00:00
&lt;&lt;&lt;&lt;&lt;&lt;&lt; HEAD
<trans-unit id="s1cffe58249b04669">
<source>Internal application name used in URLs.</source>
</trans-unit>
<trans-unit id="sb3d4f79d9d8b71e5">
<source>Submit</source>
</trans-unit>
<trans-unit id="se2b29e6cfe59414c">
<source>UI Settings</source>
</trans-unit>
<trans-unit id="s836148f721d8913b">
<source>Transparent Reverse Proxy</source>
</trans-unit>
<trans-unit id="s945a6b94361ee45b">
<source>For transparent reverse proxies with required authentication</source>
</trans-unit>
<trans-unit id="s40830ec037f34626">
<source>Configure SAML provider manually</source>
</trans-unit>
<trans-unit id="sea9fc40dfd1d18b1">
<source>Configure RADIUS provider manually</source>
</trans-unit>
<trans-unit id="sa1b0052ae095b9b3">
<source>Configure SCIM provider manually</source>
</trans-unit>
<trans-unit id="s15831fa50a116545">
<source>Saving Application...</source>
</trans-unit>
<trans-unit id="s823abdb61543a826">
<source>Authentik was unable to save this application:</source>
</trans-unit>
<trans-unit id="s848288f8c2265aad">
<source>Your application has been saved</source>
</trans-unit>
<trans-unit id="s67d858051b34c38b">
<source>Method's display Name.</source>
</trans-unit>
<trans-unit id="h10ef80d434185070">
<source>Use this provider with nginx's <x id="0" equiv-text="&lt;code&gt;"/>auth_request<x id="1" equiv-text="&lt;/code&gt;"/> or traefik's
<x id="2" equiv-text="&lt;code&gt;"/>forwardAuth<x id="3" equiv-text="&lt;/code&gt;"/>. Each application/domain needs its own provider.
Additionally, on each domain, <x id="4" equiv-text="&lt;code&gt;"/>/outpost.goauthentik.io<x id="5" equiv-text="&lt;/code&gt;"/> must be
routed to the outpost (when using a managed outpost, this is done for you).</source>
</trans-unit>
<trans-unit id="sd18b18f91b804c3f">
<source>Custom attributes</source>
</trans-unit>
<trans-unit id="s71c5d51d5a357dbd">
<source>Don't show this message again.</source>
core: Initial RBAC (#6806) * rename consent permission Signed-off-by: Jens Langhammer <jens@goauthentik.io> * the user version Signed-off-by: Jens Langhammer <jens@goauthentik.io> t Signed-off-by: Jens Langhammer <jens@goauthentik.io> * initial role Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start form Signed-off-by: Jens Langhammer <jens@goauthentik.io> * some minor table refactoring Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix user, add assign Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add roles ui Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix backend Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add assign API for roles Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start adding toggle buttons Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start view page Signed-off-by: Jens Langhammer <jens@goauthentik.io> * exclude add_ permission for per-object perms Signed-off-by: Jens Langhammer <jens@goauthentik.io> * small cleanup Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add permission list for roles Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make sidebar update Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix page header not re-rendering? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fixup Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add search Signed-off-by: Jens Langhammer <jens@goauthentik.io> * show first category in table groupBy except when its empty Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make model and object PK optional but required together Signed-off-by: Jens Langhammer <jens@goauthentik.io> * allow for setting global perms Signed-off-by: Jens Langhammer <jens@goauthentik.io> * exclude non-authentik permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * exclude models which aren't allowed (base models etc) Signed-off-by: Jens Langhammer <jens@goauthentik.io> * ensure all models have verbose_name set, exclude some more internal objects Signed-off-by: Jens Langhammer <jens@goauthentik.io> * lint fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix role perm assign Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add unasign for global perms Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add meta changes Signed-off-by: Jens Langhammer <jens@goauthentik.io> * clear modal state after submit Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add roles to our group Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix duplicate url names Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make recursive group query more usable Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add name field to role itself and move group creation to signal Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start sync Signed-off-by: Jens Langhammer <jens@goauthentik.io> * move rbac stuff to separate django app Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix lint and such Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix go Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start API changes Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add more API tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make admin interface not require superuser for now, improve error handling Signed-off-by: Jens Langhammer <jens@goauthentik.io> * replace some IsAdminUser where applicable Signed-off-by: Jens Langhammer <jens@goauthentik.io> * migrate flow inspector perms to actual permission Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix license not being a serializermodel Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add permission modal to models without view page Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add additional permissions to assign/unassign permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add action to unassign user permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add permissions tab to remaining view pages Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix flow inspector permission check Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix codecov config? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add more API tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * ensure viewsets have an order set Signed-off-by: Jens Langhammer <jens@goauthentik.io> * hopefully the last api name change Signed-off-by: Jens Langhammer <jens@goauthentik.io> * make perm modal less confusing Signed-off-by: Jens Langhammer <jens@goauthentik.io> * start user view permission page Signed-off-by: Jens Langhammer <jens@goauthentik.io> * only make delete bulk form expandable if usedBy is set Signed-off-by: Jens Langhammer <jens@goauthentik.io> * expand permission tables Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add more things Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add user global permission table Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix lint Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix tests' url names Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add tests for assign perms Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add unassign tests Signed-off-by: Jens Langhammer <jens@goauthentik.io> * rebuild permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * prevent assigning/unassigning permissions to internal service accounts Signed-off-by: Jens Langhammer <jens@goauthentik.io> * only enable default api browser in debug Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix role object permissions showing duplicate Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix role link on role object permissions table Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix object permission modal having duplicate close buttons Signed-off-by: Jens Langhammer <jens@goauthentik.io> * return error if user has no global perm and no object perms also improve error display on table Signed-off-by: Jens Langhammer <jens@goauthentik.io> * small optimisation Signed-off-by: Jens Langhammer <jens@goauthentik.io> * optimise even more Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update locale Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add system permission for non-object permissions Signed-off-by: Jens Langhammer <jens@goauthentik.io> * allow access to admin interface based on perm Signed-off-by: Jens Langhammer <jens@goauthentik.io> * clean Signed-off-by: Jens Langhammer <jens@goauthentik.io> * don't exclude base models Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2023-10-16 15:31:50 +00:00
</trans-unit>
<trans-unit id="s3e99ea082ca5ade9">
<source>Failed to fetch</source>
</trans-unit>
<trans-unit id="s98327528f00365a7">
<source>Failed to fetch data.</source>
</trans-unit>
<trans-unit id="sf485014051ad0cf7">
<source>Successfully assigned permission.</source>
</trans-unit>
<trans-unit id="sca7fed2bef53cb99">
<source>Role</source>
</trans-unit>
<trans-unit id="sc92c1a54034e21cc">
<source>Assign</source>
</trans-unit>
<trans-unit id="scd84d10ee9137070">
<source>Assign permission to role</source>
</trans-unit>
<trans-unit id="s5ee6f1b84e9ebc69">
<source>Assign to new role</source>
</trans-unit>
<trans-unit id="s4afb26a8fae257e9">
<source>Directly assigned</source>
</trans-unit>
<trans-unit id="sd8051c26e155f043">
<source>Assign permission to user</source>
</trans-unit>
<trans-unit id="sf79f8681e5ffaee2">
<source>Assign to new user</source>
</trans-unit>
<trans-unit id="saabeb4cab074b0b9">
<source>User Object Permissions</source>
</trans-unit>
<trans-unit id="s8489d5559dda260c">
<source>Role Object Permissions</source>
</trans-unit>
<trans-unit id="s6b2beba7ab637e9e">
<source>Roles</source>
</trans-unit>
<trans-unit id="s96d2bb4be3f5e8aa">
<source>Select roles to grant this groups' users' permissions from the selected roles.</source>
</trans-unit>
<trans-unit id="sb37880a2a7288ef0">
<source>Update Permissions</source>
</trans-unit>
<trans-unit id="se9c07cf256774d81">
<source>Editing is disabled for managed tokens</source>
</trans-unit>
<trans-unit id="s78ab26da7f067de8">
<source>Select permissions to grant</source>
</trans-unit>
<trans-unit id="sdeb90bfd8a80b86b">
<source>Permissions to add</source>
</trans-unit>
<trans-unit id="s36247910d67421e1">
<source>Select permissions</source>
</trans-unit>
<trans-unit id="s67e136af8fc1107b">
<source>Assign permission</source>
</trans-unit>
<trans-unit id="sb923723d27df40ba">
<source>Permission(s)</source>
</trans-unit>
<trans-unit id="sc5fb00b25c7f5a02">
<source>Permission</source>
</trans-unit>
<trans-unit id="s1455753daa00f1bc">
<source>User doesn't have view permission so description cannot be retrieved.</source>
</trans-unit>
<trans-unit id="sa3a3e09b88ed9791">
<source>Assigned permissions</source>
</trans-unit>
<trans-unit id="s9cc631505c17b028">
<source>Assigned global permissions</source>
</trans-unit>
<trans-unit id="s8f85a0e678846080">
<source>Assigned object permissions</source>
</trans-unit>
<trans-unit id="s9103a949a3963aa9">
<source>Successfully updated role.</source>
</trans-unit>
<trans-unit id="sdf87c5661b31359e">
<source>Successfully created role.</source>
</trans-unit>
<trans-unit id="s3484b1e6d0b5335f">
<source>Manage roles which grant permissions to objects within authentik.</source>
</trans-unit>
<trans-unit id="s259de999919316db">
<source>Role(s)</source>
</trans-unit>
<trans-unit id="s2ffad156e8332f04">
<source>Update Role</source>
</trans-unit>
<trans-unit id="sc5f923729564fbf3">
<source>Create Role</source>
</trans-unit>
<trans-unit id="s14bfa8fd1bec8889">
<source>Role doesn't have view permission so description cannot be retrieved.</source>
</trans-unit>
<trans-unit id="s7e796fe83982863f">
<source>Role <x id="0" equiv-text="${this._role?.name || &quot;&quot;}"/></source>
</trans-unit>
<trans-unit id="s526e2c66bd51ff5f">
<source>Role Info</source>
web: Application wizard v2 with tests (#7004) * A lot of comments about forms. * Adding comments to the wizard. * Broke out the text input into a single renderer. Still works as required. * web: Legibility in the ApplicationForm. This is a pretty good result. By using the LightDOM setting, this provides the existing Authentik form manager with access to the ak-form-horizontal-element components without having to do any cross-border magic. It's not ideal, and it shows up just how badly we've got patternfly splattered everywhere, but the actual results are remarkable. The patterns for text, switch, radio, textarea, file, and even select are smaller and easier here. I'm still noodling on what an unspread search-select element would look like. It's just dependency injection, so it ought to be as straightforward as that. * web: Marking down the start of the 'components' library. * web: Baby steps I become frustrated with my inability to make any progress on this project, so I decided to reach for a tool that I consider highly reliable but also incredibly time-consuming and boring: test driven development. In this case, I wrote a story about how I wanted to see the first page rendered: just put the HTML tag, completely unadorned, that will handle the first page of the wizard. Then, add an event handler that will send the updated content to some parent object, since what we really want is to orchestrate the state of the user's input with a centralized location. Then, rather than fiddling with the attributes and properties of the various pages, I wanted them to be able to "look up" the values they want, much as we'd expect a standalone form to be able to pull its values from the server, so I added a context object that receives the update event and incorporates the new knowledge about the state of the process into itself. The result is surprisingly satisfying: the first page renders cleanly, displays the content that we want, and as we fiddle with, we can *watch in real time* as the results of the context are updated and retransmitted to all receiving objects. And the sending object gets the results so it re-renders, but it ends up looking the same as it was before the render. * Now, it's starting to look like a complete package. The LDAP method is working, but there is a bug: the radio is sending the wrong value !?!?!?. Track that down, dammit. The search wrappers now resend their events as standard `input` events, and that actually seems to work well; the browser is decorating it with the right target, with the right `name` attribute, and since we have good definitions of the `value` as a string (the real value of any search object is its UUID4), that works quite well. Added search wrappers for CoreGroup and CryptoCertificate (CertificateKeyPairs), and the latter has flags for "use the first one if it's the only one" and "allow the display of keyless certificates." Not sure why `state()` is blocking the transmission of typing information from the typed element to the context handler, but it's a bug in the typechecker, and it's not a problem so far. * Now, it's starting to look like a complete package. The LDAP method is working, but there is a bug: the radio is sending the wrong value !?!?!?. Track that down, dammit. The search wrappers now resend their events as standard `input` events, and that actually seems to work well; the browser is decorating it with the right target, with the right `name` attribute, and since we have good definitions of the `value` as a string (the real value of any search object is its UUID4), that works quite well. Added search wrappers for CoreGroup and CryptoCertificate (CertificateKeyPairs), and the latter has flags for "use the first one if it's the only one" and "allow the display of keyless certificates." Not sure why `state()` is blocking the transmission of typing information from the typed element to the context handler, but it's a bug in the typechecker, and it's not a problem so far. * web: tracked down that weirld bug with the radio. Because radio inputs are actually multiples, the events handling for radio is... wonky. If we want our `<ak-radio>` component to be a unitary event dispatcher, saying "This is the element selected," we needed to do more than what was currently being handled. I've intercepted the events that we care about and have placed them into a controller that dictates both the setting and the re-render of the component. This makes it "controlled" (to use the Angular/React/Vue) language and depends on Lit's reactiveElement lifecycle to work, rather than trust the browser, but the browser's experience with respect to the `<input type=radio` is pretty bad: both input elements fire events, one for "losing selection" and one for "gaining selection". That can be very confusing to handle, so we funnel them down in our aggregate radio element to a single event, "selection changed". As a quality-of-life measure, I've also set the label to be unselectable; this means that a click on the label will trigger the selection event, and a long click will not disable selection or confuse the selection event generator. * web: now passing the precommit phase * web: a HACK for Storybook to inject the "use light theme" flag into the body. This isn't really a very good hack; what it does is say that every story is responsible for hacking its theme into the parent. This is very annoying, but it does mean that we can at least show our components in the best light. * web: ak-application-wizard-authentication-by-oauth, and many fixes! 1. Fixed `eventEmitter` so that if the detail object is a scalar, it will not attempt to "objectify" it. This was causing a bug where retrofitting the eventEmitter to some older components resulted in a detail of "some" being translated into ['s', 'o', 'm', 'e']. Not what is wanted. 2. Removed the "transitional form" from the existing components; they had a two-step where the web component class was just a wrapper around an independent rendering function. While this worked, it was only to make the case that they *were* independent rendering objects and could be supported with the right web component framework. We're halfway there now; the last step will be to transform the horizontal-element and various input CSS into componentized CSS, the way Patternfly-Elements is currently doing. 3. Fixed the `help` field so that it could take a string or a TemplateResult, and if the latter, don't bother wrapping it in the helper text functionality; just let it be its own thing. This supports the multi-line help of redirectURI as well as the `ak-utils-time-delta` capability. 4. Transform Oauth2ProviderForm to use the new components, to the best of our ability. Also used the `provider = this.wizard.provider` and `provider = this.instance` syntax to make the render function *completely portable*; it's the exact same text that is dropped into... 5. The complete `ak-application-wizard-authentication-by-oauth` component. They're so similar part of me wonders if I could push them both out to a common reference, or a collection of common references. Both components use the PropertyMapping and Sources, and both use the same collection of searches (Crypto, Flow). 6. A Storybook for `ak-application-wizard-authentication-by-oauth`, showing the works working. 7. New mocks for `authorizationFlow`, `propertyMappings`, and `hasJWKs`. This sequence has revealed a bug in the radio control. (It's always the radio control.) If the default doesn't match the current setting, the radio control doesn't behave as expected; it won't change when you fully expect that it should. I'll investigate how to harmonize those tomorrow. * web: Converted our toggle groups to a more streamlined implementation. * web: one more toggle group. * initial api and schema Signed-off-by: Jens Langhammer <jens@goauthentik.io> * separate blueprint importer from yaml parsing Signed-off-by: Jens Langhammer <jens@goauthentik.io> * cleanup Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: Replace ad-hoc toggle control with ak-toggle-group This commit replaces various ad-hoc implementations of the Patternfly Toggle Group HTML with a web component that encapsulates all of the needed behavior and exposes a single API with a single event handler, return the value of the option clicked. The results are: Lots of visual clutter is eliminated. A single link of: ``` <div class="pf-c-toggle-group__item"> <button class="pf-c-toggle-group__button ${this.mode === ProxyMode.Proxy ? "pf-m-selected" : ""}" type="button" @click=${() => { this.mode = ProxyMode.Proxy; }}> <span class="pf-c-toggle-group__text">${msg("Proxy")}</span> </button> </div> <div class="pf-c-divider pf-m-vertical" role="separator"></div> ``` Now looks like: ``` <option value=${ProxyMode.Proxy}>${msg("Proxy")}</option> ``` This also means that the three pages that used the Patternfly Toggle Group could eliminate all of their Patternfly PFToggleGroup needs, as well as the `justify-content: center` extension, which also eliminated the `css` import. The savings aren't as spectacular as I'd hoped: removed 178 lines, but added 123; total savings 55 lines of code. I still count this a win: we need never write another toggle component again, and any bugs, extensions or features we may want to add can be centralized or forked without risking the whole edifice. * web: minor code formatting issue. * add new "must_created" state to blueprints to prevent overwriting objects Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: adding a storybook for the ak-toggle-group component * Bugs found by CI/CD. * web: Replace ad-hoc search for CryptoCertificateKeyPairs with ak-crypto-certeficate-search This commit replaces various ad-hoc implementations of `search-select` for CryptoCertificateKeyPairs with a web component that encapsulates all of the needed behavior and exposes a single API. The results are: Lots of visual clutter is eliminated. A single search of: ```HTML <ak-search-select .fetchObjects=${async (query?: string): Promise<CertificateKeyPair[]> => { const args: CryptoCertificatekeypairsListRequest = { ordering: "name", hasKey: true, includeDetails: false, }; if (query !== undefined) { args.search = query; } const certificates = await new CryptoApi( DEFAULT_CONFIG, ).cryptoCertificatekeypairsList(args); return certificates.results; }} .renderElement=${(item: CertificateKeyPair): string => { return item.name; }} .value=${(item: CertificateKeyPair | undefined): string | undefined => { return item?.pk; }} .selected=${(item: CertificateKeyPair): boolean => { return this.instance?.tlsVerification === item.pk; }} ?blankable=${true} > </ak-search-select> ``` Now looks like: ```HTML <ak-crypto-certificate-search certificate=${this.instance?.tlsVerification}> </ak-crypto-certificate-search> ``` There are three searches that do not require there to be a valid key with the certificate; these are supported with the boolean property `nokey`; likewise, there is one search (in SAMLProviderForm) that states that if there is no current certificate in the SAMLProvider and only one certificate can be found in the Authentik database, use that one; this is supported with the boolean property `singleton`. These changes replace 382 lines of object-oriented invocations with 36 lines of declarative configuration, and 98 lines for the class. Overall, the code for "find a crypto certificate" has been reduced by 46%. Suggestions for a better word than `singleton` are welcome! * web: display tests for CryptoCertificateKeypair search This adds a Storybook for the CryptoCertificateKeypair search, including a mock fetch of the data. In the course of running the tests, we discovered that including the SearchSelect _class_ won't include the customElement declaration unless you include the whole file! Other bugs found: including the CSS from Storybook is different from that of LitElement native, so much so that the adapter needed to be included. FlowSearch had a similar bug. The problem only manifests when building via Webpack (which Storybook uses) and not Rollup, but we should support both in distribution. * Fixed behavioral problem with the radio; the `if` there was preventing the radio from reflecting the default correctly. The observed behavior was that the radio wouldn't "activate" until the item selected during the render pass was clicked on first. * Proxy Provider done. * web: Tactical change. Put all the variants on the second page; it's a longer list, but it's also easier to manage than all those required sub-options. * Rounding out the catalog. * web: SAML Manual Configuration Added a 'design document' that just kinda describes what I'm trying to do, in case I don't get this done by Friday Aug 11, 2023. I had two tables doing the same thing, so I merged them and then wrote a few map/filters to specialize them for those two use cases. Along the way I had to fiddle with the ESLint settings so that underscore-prefixed unused variables would be ignored. I cleaned up the visual appeal of the forms in the LDAP application. I was copy/pasting the "handleProviderEvent" function, so I pulled it out into ApplicationWizardProviderPageBase. Not so much a matter of abstraction as just disliking that kind of duplication; it served no purpose. * Added SAML Story to Storybook. * Web: This is coming together amazingly well. Like, almost too well. * web: 80% of the way there This commit includes the first three pages of the wizard, the completion of the wizard framework with evented handling, and control over progression. Some shortcomings of this design have become evident: it isn't possible to communicate between the steps' wrappers, as they are POJOs without access to the context. An imperative decision-making process has to be inserted in the orchestration layer, which is kinda annoying. But it looks good and it behaves correctly, to the extent that I've given it behavior. It's an excellent foundation. * Linting. * web: application wizard Found where the hook for form validity should go. Excellent! Now I just need to incorporate that basic validation into the business logic and we're good to go. * Turns out that was one layer too many; the topmost component was fine for maintaining the context. * It looks like my brilliant strategy has hit a snag. The idea is simple. Let's start with this picture: ``` <application-wizard .steps=${[... a collection of step objects ...]}> <wizard-main .steps=${(steps from above)}> <application-current-panel> <current-form> ``` - ApplicationWizard has a Context for the ApplicationProviderPair (or whatever it's going to be). This context does not know about the steps; it just knows about: the "application" object, the "provider" object, and a discriminator to know *which* provider the user has selected. - ApplicationWizard has Steps that, among other things, provides Panels for: - Application - Pick Provider - Configure Provider - Submit ApplicationProviderPair to the back-end - The WizardFrame renders the CurrentPanel for the CurrentStep The CurrentPanel gets its data from the ApplicationWizard in the form of a Context. It then sends messages (events) to ApplicationWizard about the contents of each field as the user is filling out the form, so that the ApplicationWizard can record those in the ApplicationProviderPair for later submission. When a CurrentForm is valid, the ApplicationWizard updates the Steps object to show that the "Next button" on the Wizard is now available. In this way, the user can progress through the system. When they get to the last page, we can provide in the ApplicationWizard with the means to submit the form and/or send the user back to the page with the validation failure. Problem: The context is being updated in real-time, which is triggering re-renders of the form. This leads to focus problems as the fields that are not yet valid are triggering "focus grab" behavior. This is a classic problem with "controlled" inputs. What we really want is for the CurrentPanel to not re-render at all, but to behave like a normal, uncontrolled form, and let the browser do most of the work. We still want the [Next] button to enable when the form is valid enough to permit that. --- Other details: I've ripped out a lot of Jen's work, which is probably a mistake. It's still preserved elsewhere. I've also cleaned up the various wizardly things to try and look organized. It *looks* like it should work, it just... doesn't. Not yet. * Late addition: I had an inspiration about how to reduce the way reactivity broke focus by, basically, removing the reactivity and managing the first-time-through lifecycle to prevent the update from causing refocus. It works well! Now I just need to test it. * This application fixes the bug with respect to the wizard-level context being updated incorrectly. Understandings: - To use uncontrolled inputs, which I prefer, the context object should not be a state or property at the level of consumers; it should not automatically re-render with every keystroke, i.e. "The React Way." We're using Web Components, [client-side validation](https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation) exists on the platform already, and live-validation is problematic for any number of reasons. - The trade-off is that it is now necessary to re-render the target page of the wizard de-novo, but that's not really as big a deal as it sounds. Lit is ready to do that... and then nothing else until we request a change-of-page. Excellent. - The top level context *must* be a state, but it's better if it's a state never actually used by the top-level context container. The debate about whether or not to make that container a dumb one (`<slot></slot>`) or to merge it with the top-level object continues; here, I've merged it with the top-level wizard object, but that object does not refer to the state variable being managed in its render pass, so changes to it do not cause a re-render of the whole wizard. The purpose of the top-level page is to manage the *steps*, not the *content of any step*. A step may change dynamically based on the content of a step, but that's the same thing as *which step*. Lesson: always know what your state is *about*. - Deep merging is a complex subject, but here it's appropriate to our needs. * web: Application Wizard This commit combines a working (but very unpolished) version of the Application Wizard with Jen's code for the CoreTransactionApplicationRequest, resulting in a successful round trip. It fixes a number of bugs with the way ContextProducer decorators were being processed, such that they just weren't working with our current configuration (although they did work fine in Storybook); consumers didn't need to be fixed. It also *removes* the steps-aware context from the Wizard. That *may* be a mistake. To re-iterate, the `WizardFrame` provides the chrome for a Wizard: the button bar div, the breadcrumbs div, the header div, and it takes the steps object as its source of truth for all of the content. The `WizardContent` part of the application has two parts: The `WizardMain`, which wraps the frame and supplies the context for all the `WizardPanels`, and the `WizardPanels` themselves, which are dependent on a context from `WizardMain` for the data that populates each panel. YAGNI right now that the panels need to know anything about the steps, and the `WizardMain` can just pass a fresh `.steps` object to the `WizardFrame` when they need updating. Using props drilling may make more sense here. It certainy does *not* make sense for the panels. They need to be renderable on-demand, and they need to make sense of what they're rendering on-demand, so the function is ``` (panel code) => (context) => (rendered panel) ``` (Yes, that's curried notation. Deal.) * This commit includes the first WDIO test for the ApplicationWizard. It doesn't do much right now, but it does log in and navigate to the wizard successfully. * web: completed test for single application, provided new programming language to make it easier to write tests. * Almost there. Missing: The validation is currently not working as expected, and I cannot get the backend to give me meaningful data helping us "go back" to the field that wasn't valid. I really don't want to put all the meaningful validation on the front-end; that's the road to - perdition, the back-end must be usable by people less assiduous than we are. Also: Need to make the button bar work better; maybe each panel can provide a custom button bar if one is needed? * web: Test harness We have an end-to-end test harness that includes a trivially correct DSL for "This is what a user would do, do this": ``` const deleteProvider = (theSlug) => ([ ["button", '>>>ak-sidebar-item a[href="#/core/providers"]'], ["deletebox", `>>>a[href="#/core/applications/${theSlug}"]`], ["button", '>>>ak-forms-delete-bulk button[slot="trigger"]'], ["button", '>>>ak-forms-delete-bulk div[role="dialog"] ak-spinner-button'], ]); ``` It's now possible to target individual sequences of events this way. With a little creativity, we could have standalone functions that take parameters for our calls and just do them, without too much struggle. * web: Revised navigation After working with the navigation for awhile, I realized that it's a poor map; what I really wanted was a controller/view pair, where events flow up to the controller and then messages on "what to draw" flow down to the view. It work quite well, and the wizard frame is smaller and smarter for it. I've also moved the WDIO-driven tests into the 'tests' folder, because it (a) makes more sense to put them there, and (b) it prevents any confusion about who's in charge of node_modules. * web: Simplify, simplify, simplify Sort-of. This commit changes the way the "wizard step coordinator" layer works, giving the wizard writer much more power over button bar. It still assumes there are only three actions the wizard frame wants to commit: next, back, and close. This empowers the steps themselves to re-arrange their buttons and describe the rules through which transitions occur. * web: resetting the form is not working yet... I vehemently dislike the object-oriented "reset" command; every wizard should start with an absolutely fresh copy of the data upon entry. Refactoring the wizard to re-build its content from the inside is the correct way to go, but I don't have a good mental image of how to make the ModalButton and the component it invokes interact cleanly, which frustrates the hell out of me. * web: reset As I said, I greatly dislike having to be dependent upon "resets"; I prefer my data to be de novo going into a "new" transaction. That said, we work with what we've got; I've created an event generated by the wizard that says the modal just closed; anything wrapping and implementing the wizard can then capture that event and reset the data. I've also added a pair of functions that create the two states (what step, what form data) anew, so that resetting is as trivial as initializing (and is exactly the same, code-wise). * web: Without error handling, this is complete, but I still need @BeryJu (Jens) for help with the SAML Upload (it doesn't appear to be correctly handled?) and the error handling. * web: revise tests for wizard This commit replaces the previous WDIO instance with a more formal and straightforward process using the [pageobjects](https://martinfowler.com/bliki/PageObject.html). In this form, every major component has its own test suite, and a test is a sequence of exercises of those components. A test then becomes something as straightforward as: ``` await LoginPage.open(); await LoginPage.login("ken@goauthentik.io", "eat10bugs"); expect(await UserLibraryPage.pageHeader).toHaveText("My Applications"); await UserLibraryPage.goToAdmin(); expect(await AdminOverviewPage.pageHeader).toHaveText("Welcome, "); await AdminOverviewPage.openApplicationsListPage(); expect(await ApplicationsListPage.pageHeader).toHaveText("Applications"); ApplicationsListPage.startCreateApplicationWizard(); await ApplicationWizard.app.name.setValue(`Test application ${newId}`); await ApplicationWizard.nextButton.click(); await (await ApplicationWizard.getProviderType("ldapprovider")).click(); await ApplicationWizard.nextButton.click(); await ApplicationWizard.ldap.setBindFlow("default-authentication-flow"); await ApplicationWizard.nextButton.click(); await expect(await ApplicationWizard.commitMessage).toHaveText( "Your application has been saved" ); ``` Whether or not there's another layer of DSL in there or not, this is a pretty nice idiom for maintaining tests. * web: updating with forms and fixes for eslint complaints. * web/add webdriverIO testing layer This commit adds WebdriverIO as an end-to-end solution to unit testing. WebdriverIO can be run both locally and remotely, supports strong integration with web components, and is generally robust for use in pipelines. I'll confess to working through a tutorial on how to do this for web components, and this is just chapter 2 (I think there are 5 or so chapters...). There's a makefile, with help! If you just run `make` it tells you: ``` Specify a command. The choices are: help Show this help node_modules Runs `npm install` to prepare this feature precommit Run the precommit: spell check all comments, eslint with sonarJS, prettier-write test-good-login Test that we can log into the server. Requires a running instance of the server. test-bad-login Test that bad usernames and passwords create appropriate error messages ``` ... because Makefiles are documentation, and documentation belongs in Makefiles. I've chosen to go with a PageObject-oriented low-level DSL; what that means is that for each major components (a page, a form, a wizard), there's a class that provides human-readable names for human-interactable and human-viewable objects on the page. The LoginPage object, for example, has selectors for the username, password, submit button, and the failure alert; accessing those allows us to test for items as expected., and to write a DSL for "a good login" that's as straightforward as: ``` await LoginPage.open(); await LoginPage.login("ken@goauthentik.io", "eat10bugs"); await expect(UserLibraryPage.pageHeader).toHaveText("My applications"); ``` There was a *lot* of messing around with the LoginPage to get the username and password into the system. For example, I had to do this with all the `waitForClickable` and `waitForEnable` because we both keep the buttons inaccessible until the form has something and we "black out" the page (put a darkening filter over it) while accessing the flow, meaning there was a race condition such that the test would attempt to interact with the username or password field before it was accessible. But this works now, which is very nice. ``` JavaScript get inputUsername() { return $('>>>input[name="uidField"]'); } get btnSubmit() { return $('>>>button[type="submit"]'); } async username(username: string) { await this.inputUsername.waitForClickable(); await this.inputUsername.setValue(username); await this.btnSubmit.waitForEnabled(); await this.btnSubmit.click(); } ``` The bells & whistles of *Prettier*, *Eslint*, and *Codespell* have also been enabled. I do like my guardrails. * web/adding tests: added comments and cleaned up some administrative features. * web/test: changed the name of one test to reflect it's 'good' status * core/allow alternative postgres credentials This commit allows the `dev-reset` command in the Makefile to pick up and use credentials from the `.env` file if they are present, or fallback to the defaults provided if they are not. This is the only place in the Makefile where the database credentials are used directly against postgresql binaries. The syntax was tested with bash, zsh, and csh, and did not fail under those. The `$${:-}` syntax is a combination of a Makefile idiom for "Pass a single `$` to the environment where this command will be executed," and the shell expresion `${VARIABLE:-default}` means "dereference the environment variable; if it is undefined, used the default value provided." * Re-arrange sequence to avoid recursive make. Nothing wrong with recursive make; it just wasn't essential here. `migrate` is just a build target, not a task. * Cleanup according to the Usage: checkmake [options] <makefile>... checkmake -h | --help checkmake --version checkmake --list-rules Makefile linting tool. * core: added 'help' to the Makefile * get postgres config from authentik config loader Signed-off-by: Jens Langhammer <jens@goauthentik.io> * don't set -x by default Signed-off-by: Jens Langhammer <jens@goauthentik.io> * sort help Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update help strings Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: test LDAP wizard sequence * web: improve testing by adding test admin user via blueprint * This commit continues the application wizard buildout. In this commit are the following changes: - Added SCIM to the list of available providers - Fixed ForwardProxy so that its mode is set correctly. (This is a special case in the committer; I'm unhappy with that.) - Fixed the commit messages so that: - icons are set correctly (Success, Danger, Working) - icons are colored correctly according to state - commit message includes a `data-commit-state` field so tests can find it! - Merged the application wizard tests into a single test pass - Isolated common parts of the application wizard tests to reduce unnecessary repetition. All application tests are the same until you reach the provider section anyway. - Fixed the unit tests so they're finding the right error messages and are enabled to display them correctly. - Moved the test Form handlers into their own folder so they're not cluttering up the Pages folder. * web: add radius to application wizard This commit continues the application wizard buildout. In this commit are the following changes: - Fixed a width-setting bug in the Makefile `make help` feature (i.e "automate that stuff!") - Added Radius to the list of providers we can offer via the wizard - Added `launchUrl` and `UI Settings` to features of the application page the wizard can find - Changed 'SAML Manual Configuration' to just say "SAML Configuration" - Modified `ak-form-group` to take and honor the `aria-label` property (which in turn makes it easier to target specific forms with unit testing) - Reduced the log level for wdio to 'warn'; 'info' was super-spammy and not helpful. It can be put back with `--logLevel info` from the command line. * fix blueprints Signed-off-by: Jens Langhammer <jens@goauthentik.io> * update package name Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add dependabot Signed-off-by: Jens Langhammer <jens@goauthentik.io> * prettier run Signed-off-by: Jens Langhammer <jens@goauthentik.io> * add basic CI Signed-off-by: Jens Langhammer <jens@goauthentik.io> * remove hooks Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: application wizard refactor & completion This commit refactors the various components of the Wizard and ApplicationWizard, creating a much more maintainable and satisfying Wizard experience for both developers (i.e, *me* and *Jens* so far), and for the customer. The Wizard base has been refactored into three components: **AkWizardController** The `AkWizardController` provides the event listenters for the wizard; it hooks them up, recevies the events, and forwards them to the wizard. It unwraps the event objects and forwards the relevant messages contained in the events. It knows of three event categories: - Navigation requests (move to a different step) - Update requests (the current step has updated the business content) - Close requests (close or cancel the wizard). **ak-wizard-frame** The `ak-wizard-frame` is the ModalButton interface. It provides the Header, Breadcrumbs (nee` "navigation block"), Buttons, and a DIV into which the main content is rendered. **AkWizard** `AkWizard` is an *incomplete* implementation of the wizard. It's meant to be inherited by a child class, which will implement the rest. It extends `AKElement`. It provides the basic content needed, such as steps, currentStep (as an index), an accessor for the step itself, an accessor for the frame, and the interface to the `AkWizardController`. **ApplicationWizard** The `ApplicationWizard` itself has been refactored to accommodate these changes. It inherits from `AkWizard` and provides the business logic for what to do when a form updates, some custom logic for preventing moving through the wizard when the forms are incomplete, and a persistence layer for filling out different providers in the same session. It's simplified a *lot*. The types specified for `AkWizard` are pretty nifty, I think. I could wish the types being passed via the custom events were more robust, but [strongly typed custom events](https://github.com/lit/lit-element/issues/808) turn out to be quite the pain in the, er, neck. As it is, the `precommit` pass did very good at preventing the worst disasters. The steps themselves were re-written as objects so that they could take advantage of their `valid` and `disabled` states and provide more meaningful buttons and labels. I think it's a solid compromise, and it moved a lot of display logic out of the core `handleUpdate()` business method. The tests, such as they are, are passing. * Added comment describing new test. * web: ensuring copy from `main` is canon * web: fixes after merge * web: laying the groundwork for future expansion This commit is a hodge-podge of updates and changes to the web. Functional changes: - Makefile: Fixed a bug in the `help` section that prevented the WIDTH from being accurately calculated if `help` was included rather than in-lined. - ESLint: Modified the "unused vars" rule so that variables starting with an underline are not considered by the rule. This allows for elided variables in event handlers. It's not a perfect solution-- a better one would be to use Typescript's function-specialization typing, but there are too many places where we elide or ignore some variables in a function's usage that switching over to specialization would be a huge lift. - locale: It turns out, lit-locale does its own context management. We don't need to have a context at all in this space, and that's one less listener we need to attach t othe DOM. - ModalButton: A small thing, but using `nothing` instead of "html``" allows lit better control over rendering and reduces the number of actual renders of the page. - FormGroup: Provided a means to modify the aria-label, rather than stick with the just the word "Details." Specializing this field will both help users of screen readers in the future, and will allow test suites to find specific form groups now. - RadioButton: provide a more consistent interface to the RadioButton. First, we dispatch the events to the outside world, and we set the value locally so that the current `Form.ts` continues to behave as expected. We also prevent the "button lost value" event from propagating; this presents a unified select-like interface to users of the RadioButtonGroup. The current value semantics are preserved; other clients of the RadioButton do not see a change in behavior. - EventEmitter: If the custom event detail is *not* an object, do not use the object-like semantics for forwarding it; just send it as-is. - Comments: In the course of laying the groundwork for the application wizard, I throw a LOT of comments into the code, describing APIs, interfaces, class and function signatures, to better document the behavior inside and as signposts for future work. * web: permit arrays to be sent in custom events without interpolation. * actually use assignValue or rather serializeFieldRecursive Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: eslint & prettier fixes, plus small aesthetic differences. * Restoring this file. Not sure where it disappears to. * fix label in dark mode Signed-off-by: Jens Langhammer <jens@goauthentik.io> * SCIM Manuel -> SCIM Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix lint errors Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: better converter configuration, CSS repair, and forward-domain-proxy 1. Forward Domain Proxy. I wasn't sure if this method was appropriate for the wizard, but Jens says it is. I've added it. 2. In the process of doing so, I decided that the Provider.converter field was overly complexified; I tried too hard to reduce the number of functions I needed to define, but in the process outsourced some of the logic of converting the Wizard's dataset into a property typed request to the `commit` phase, which was inappropriate. All of the logic about a provider, aside from its display, should be here with the code that distinguishes between providers. This commit makes it so. 3. Small CSS fix: the fields inherited from the Proxy provider forms had some unexpected CSS which was causing a bit of a weird indent. That has been rectified. * web: running pre-commit after merge. * web: ensure the applications wizard tests finish after current changes * prettier has opinions. * web: application wizard spit & polish The "ApplicationWizardHint" now correctly uses the localstorage and allows the user to navigate back and see the message after it's been hidden, so that it will always be available during the test phase. The ApplicationList's old "Create Application Form" button has been restored for the purposes of the test phase. The ApplicationWizard is now available on both the ApplicationList and ProviderList pages. Tana and I discussed the microcopy, putting a stronger second-person "You can do..." twist onto the language, to give the user the sense of empowerment. The ShowHintController now has both "hide" and "show" operations, to support the hint restoration. * web: updated storybook stories for the wizard, illustration how "a simple wizard" is configured in source code and tested with storybook. * web: I hate getting spanked by prettier. * web: sometimes I wish I had lower standards Anyway, this was a very stupid bug, because by definition function definition arguments don't have uses, they're being defined, not implemented. Fixed, conf fixed to compensate, and consequences conquered. * move context from labs to main Signed-off-by: Jens Langhammer <jens@goauthentik.io> * Revert "move context from labs to main" This reverts commit 3718ee69048966d26b1c357a7d2653fbb3ab613b. * web: reify the data loop I was very unhappy with the "update this dot-path" mechanism I was using earlier; it was hard for me to read and understand what was happening, and I wrote the darned thing. I decided instead to go with a hard substitution model; each phase of the wizard is responsible for updating the *entire* payload, mostly by creating a new payload and substituting the field value associated with the event. On the receiver, we have to do that *again* to handle the swapping of providers when the user chooses one and then another. It looks clunky, and it is, but it's *legible*; a junior dev could understand what it's doing, and that's the goal. * Revert "web: reify the data loop" This reverts commit 09fedcacf02a90a021ce9e18c0eb4bec1ef48302. * web: revert the 'lit' to 'lit-labs' for task and context. --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-10-18 19:43:37 +00:00
</trans-unit>
<trans-unit id="s2da4aa7a9abeb653">
<source>Pseudolocale (for testing)</source>
</trans-unit>
<trans-unit id="s4bd386db7302bb22">
<source>Create With Wizard</source>
</trans-unit>
<trans-unit id="s070fdfb03034ca9b">
<source>One hint, 'New Application Wizard', is currently hidden</source>
</trans-unit>
<trans-unit id="s61bd841e66966325">
<source>External applications that use authentik as an identity provider via protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.</source>
</trans-unit>
<trans-unit id="s1cc306d8e28c4464">
<source>Deny message</source>
</trans-unit>
<trans-unit id="s6985c401e1100122">
<source>Message shown when this stage is run.</source>
</trans-unit>
<trans-unit id="s09f0c100d0ad2fec">
<source>Open Wizard</source>
</trans-unit>
<trans-unit id="sf2ef885f7d0a101d">
<source>Demo Wizard</source>
</trans-unit>
<trans-unit id="s77505ee5d2e45e53">
<source>Run the demo wizard</source>
2023-10-23 16:48:12 +00:00
</trans-unit>
<trans-unit id="s4498e890d47a8066">
<source>OAuth2/OIDC (Open Authorization/OpenID Connect)</source>
</trans-unit>
<trans-unit id="s4f2e195d09e2868c">
<source>LDAP (Lightweight Directory Access Protocol)</source>
</trans-unit>
<trans-unit id="s7f5bb0c9923315ed">
<source>Forward Auth (Single Application)</source>
</trans-unit>
<trans-unit id="sf8008d2d6b064b95">
<source>Forward Auth (Domain Level)</source>
</trans-unit>
<trans-unit id="sfa8a1ffa9fee07d3">
<source>SAML (Security Assertion Markup Language)</source>
</trans-unit>
<trans-unit id="s848a23972e388662">
<source>RADIUS (Remote Authentication Dial-In User Service)</source>
</trans-unit>
<trans-unit id="s3e902999ddf7b50e">
<source>SCIM (System for Cross-domain Identity Management)</source>
</trans-unit>
<trans-unit id="sdc5690be4a342985">
<source>The token has been copied to your clipboard</source>
</trans-unit>
<trans-unit id="s7f3edfee24690c9f">
<source>The token was displayed because authentik does not have permission to write to the clipboard</source>
</trans-unit>
<trans-unit id="saf6097bfa25205b8">
<source>A copy of this recovery link has been placed in your clipboard</source>
</trans-unit>
<trans-unit id="s5b8ee296ed258568">
<source>The current tenant must have a recovery flow configured to use a recovery link</source>
</trans-unit>
<trans-unit id="s895514dda9cb9c94">
<source>Create recovery link</source>
</trans-unit>
<trans-unit id="se5c795faf2c07514">
<source>Create Recovery Link</source>
</trans-unit>
<trans-unit id="s84fcddede27b8e2a">
<source>External</source>
</trans-unit>
<trans-unit id="s1a635369edaf4dc3">
<source>Service account</source>
</trans-unit>
<trans-unit id="sff930bf2834e2201">
<source>Service account (internal)</source>
</trans-unit>
<trans-unit id="s66313b45b69cfc88">
<source>Check the release notes</source>
</trans-unit>
<trans-unit id="sb4d7bae2440d9781">
<source>User Statistics</source>
</trans-unit>
<trans-unit id="s0924f51b028233a3">
<source>&lt;No name set&gt;</source>
</trans-unit>
<trans-unit id="sdc9a6ad1af30572c">
<source>For nginx's auth_request or traefik's forwardAuth</source>
</trans-unit>
<trans-unit id="sfc31264ef7ff86ef">
<source>For nginx's auth_request or traefik's forwardAuth per root domain</source>
</trans-unit>
<trans-unit id="sc615309d10a9228c">
<source>RBAC is in preview.</source>
</trans-unit>
<trans-unit id="s32babfed740fd3c1">
<source>User type used for newly created users.</source>
</trans-unit>
<trans-unit id="s4a34a6be4c68ec87">
<source>Users created</source>
</trans-unit>
<trans-unit id="s275c956687e2e656">
<source>Failed logins</source>
</trans-unit>
<trans-unit id="sb35c08e3a541188f">
<source>Also known as Client ID.</source>
</trans-unit>
<trans-unit id="sd46fd9b647cfea10">
<source>Also known as Client Secret.</source>
</trans-unit>
<trans-unit id="s4476e9c50cfd13f4">
<source>Global status</source>
</trans-unit>
<trans-unit id="sd21a971eea208533">
<source>Vendor</source>
</trans-unit>
<trans-unit id="sadadfe9dfa06d7dd">
<source>No sync status.</source>
</trans-unit>
<trans-unit id="s2b1c81130a65a55b">
<source>Sync currently running.</source>
</trans-unit>
<trans-unit id="sf36170f71cea38c2">
<source>Connectivity</source>
</trans-unit>
<trans-unit id="sd94e99af8b41ff54">
<source>0: Too guessable: risky password. (guesses &amp;lt; 10^3)</source>
</trans-unit>
<trans-unit id="sc926385d1a624c3a">
<source>1: Very guessable: protection from throttled online attacks. (guesses &amp;lt; 10^6)</source>
</trans-unit>
<trans-unit id="s8aae61c41319602c">
<source>2: Somewhat guessable: protection from unthrottled online attacks. (guesses &amp;lt; 10^8)</source>
</trans-unit>
<trans-unit id="sc1f4b57e722a89d6">
<source>3: Safely unguessable: moderate protection from offline slow-hash scenario. (guesses &amp;lt; 10^10)</source>
</trans-unit>
<trans-unit id="sd47f3d3c9741343d">
<source>4: Very unguessable: strong protection from offline slow-hash scenario. (guesses &amp;gt;= 10^10)</source>
</trans-unit>
<trans-unit id="s3d2a8b86a4f5a810">
<source>Successfully created user and added to group <x id="0" equiv-text="${this.group.name}"/></source>
</trans-unit>
<trans-unit id="s824e0943a7104668">
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
</trans-unit>
<trans-unit id="s62e7f6ed7d9cb3ca">
<source>Pretend user exists</source>
</trans-unit>
<trans-unit id="s52bdc80690a9a8dc">
<source>When enabled, the stage will always accept the given user identifier and continue.</source>
web/admin: revise wizard form handling (#7331) * web: break circular dependency between AKElement & Interface. This commit changes the way the root node of the web application shell is discovered by child components, such that the base class shared by both no longer results in a circular dependency between the two models. I've run this in isolation and have seen no failures of discovery; the identity token exists as soon as the Interface is constructed and is found by every item on the page. * web: fix broken typescript references This built... and then it didn't? Anyway, the current fix is to provide type information the AkInterface for the data that consumers require. * web: extract the form processing from the form submission process Our forms have a lot of customized value handling, and the function `serializeForm` takes our input structures and creates a JSON object ready for submission across the wire for the various models provided by the API. That function was embedded in the `ak-form` object, but it has no actual dependencies on the state of that object; aside from identifying the input elements, which is done at the very start of processing, this large block of code stands alone. Separating out the "processing the form" from "identifying the form" allows us to customize our form handling and preserve form information on the client for transactional purposes such as our wizard. w * web: multi-select, but there's a styling issue. * web: provide a closed control for multi-select This commit creates a new control, using the ak-form-element-horizontal as a *CLOSED* object, for our multi-select. This control right now is limited to what we expect to be using in the wizard, but that doesn't mean it can't be smarter in the future. * web: hung up by a silly spelling error * web: update the form-handling method With the `serializeForm` method extracted, it's much easier to examine and parse every *form* with every keystroke, preserving them against the changes that happen as the customer navigates the Wizard. With that in place, it became straightforward to retrofit the "handle changes to the application, to the provider, and to the providerType" into the three pages of the wizard, and to provide *all* of the form elements in a base class such that no specialized handling needs to happen to any of the child pages. Fixed an ugly typo in the oauth2 provider, as well. * web: wizard should work with multi-select and should reflect default values (Note: This commit is predicated on both the "Extract serializeForm function from Form.ts" and "Provide a controlled multi-select input control" PRs.) The initial attempt at the wizard was woefully naive in its implementation, missing some critical details along the way. This revision starts off with one stronger assumption: trust that Jens knows what he's doing, and knew what he was building when he wrote the initial `Form` handler. The problem with the `Form` handler, and the reason I avoided it, was simply that it does too many things, especially in its ModelForm variant: it receives a model from the back-end, renders a (hand-written) form for that model, allows the user to interact with that model, and facilitates saving it to the back-end again, complete with on-page notifications of success or failure. The Wizard could not use all of that. It needs to gather the information for *two* models (an Application and a Provider, plus the ProviderType) and has a new and specialized end-point for a transaction that allows the committing or roll back of both models to happen simultaneously, predicated on success or failure respectively. With "Extract `serializeForm` completed, it was possible to repurpose the forms that already existed, stripping them down to just their input components, and eventing the entire thing in a single event loop of "events flow up, data flows down." In this case, the *entire form* is serialized on a per-event basis and pushed up the to the orchestration layer, which saves them off. Writing a parent `BasePanel` class that has accessors for `formValues` and `valid` means that the state of every page is accessible with a simple query. This simplified the `BaseProviderPanel` class to just specialize the `dispatchUpdate` method to send the wizard update with the new provider information filled out. Because the *form* is being treated as the source of truth about the state of a `Partial<Application>` or `Partial<*Provider>` object, the defaults are now being captured as expected. Likewise, this simplified the `providerCache` layer which preserves customer input in the event that the customer starts filling out the wrong provider to a simple conditional clause in the orchestrator. The Wizard has much fewer smarts because it doesn't (and probably never did) need them. Along with the above changes, the following has also been done: For SAML and SCIM, the providerMappings now works. They weren't being managed as `state` objects, so they weren't receiving updates when the update event retrieved the information from the back-end. In order to make clear what's happening, I have extracted the loops from the original definition and built them as named objects: `propertyMappings`, `pmUserValues`, `pmGroupValues` and so on, which I then pass into the new multi-select component. I fixed a really embarrassing typo in Oauth2's "advanced settings" block. I have extracted the CoreGroup search-select into a custom component. I deleted the `merge` function. That was a faulty experiment with non-deterministic outcomes, and I was never happy with it. I'm glad its gone. I've added a title header to each of the providers, so the user can be sure that they're looking at the right provider type when they start filling out the form. I've created a new token, `data-ak-control`, with which we can mark all objects that we can treat as Authentik value-producing components, the form value of which is available through a `json()` method. I've added this bit of intelligence to the `serializeForm` function, short-circuiting the complex processing and putting the "this is the shape of the value we expect from this input" *onto the input itself*. Which is where it belongs. * web: add error handling to wizard. * web: improve error handling in light components Rather than reproduce the error handling across all of the LightComponents, I've made a parent class that takes the common fields to distribute between the ak-form-element-horizontal and the input object itself. This made it much easier to properly display errors in freeform input fields in the wizard, as well as working with the routine error handling in Form.ts * Added the radio control to the list of LightComponents. * Fix bug where event was recorded twice. * Fixed merge bug (?) that somehow deleted the Authorization Select block in OAuth2. * web: prettier had opinions * web: added error handling and display * web: bump @lit-labs/context from 0.4.1 to 0.5.1 in /web Bumps [@lit-labs/context](https://github.com/lit/lit/tree/HEAD/packages/labs/context) from 0.4.1 to 0.5.1. - [Release notes](https://github.com/lit/lit/releases) - [Changelog](https://github.com/lit/lit/blob/main/packages/labs/context/CHANGELOG.md) - [Commits](https://github.com/lit/lit/commits/@lit-labs/context@0.5.1/packages/labs/context) --- updated-dependencies: - dependency-name: "@lit-labs/context" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * web: updated wizard to run with latest package.json configuration Apparently, there were stale dependencies in package-lock.json that were conflicting with the requests in our package.json. By running `npm update`, I was able to resolve the conflict. I have also removed the default names from the context names collection; they weren't doing any good, and they permit frictionless renaming of dependencies, which is never a good idea. * web: schlepping on the errors messages During testing, I realized I was unhappy with the error messages. They're not very helpful. By adding links to navigate back to the place where the error occurred, and providing better context for what the error could have been, I hope to help the use correct their errors. * make package the same as main Signed-off-by: Jens Langhammer <jens@goauthentik.io> --------- Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-12-06 11:28:19 +00:00
</trans-unit>
<trans-unit id="scda8dc24b561e205">
<source>There was an error in the application.</source>
</trans-unit>
<trans-unit id="sdaca9c2c0361ed3a">
<source>Review the application.</source>
</trans-unit>
<trans-unit id="sb50000a8fada5672">
<source>There was an error in the provider.</source>
</trans-unit>
<trans-unit id="s21f95eaf151d4ce3">
<source>Review the provider.</source>
</trans-unit>
<trans-unit id="s9fd39a5cb20b4e61">
<source>There was an error</source>
</trans-unit>
<trans-unit id="s7a6b3453209e1066">
<source>There was an error creating the application, but no error message was sent. Please review the server logs.</source>
</trans-unit>
<trans-unit id="s1a711c19cda48375">
<source>Configure LDAP Provider</source>
</trans-unit>
<trans-unit id="s9368e965b5c292ab">
<source>Configure OAuth2/OpenId Provider</source>
</trans-unit>
<trans-unit id="sf5cbccdc6254c8dc">
<source>Configure Proxy Provider</source>
</trans-unit>
<trans-unit id="sf6d46bb442b77e91">
<source>AdditionalScopes</source>
</trans-unit>
<trans-unit id="s2c8c6f89089b31d4">
<source>Configure Radius Provider</source>
</trans-unit>
<trans-unit id="sfe906cde5dddc041">
<source>Configure SAML Provider</source>
</trans-unit>
<trans-unit id="sb3defbacd01ad972">
<source>Property mappings used for user mapping.</source>
</trans-unit>
<trans-unit id="s7ccce0ec8d228db6">
<source>Configure SCIM Provider</source>
</trans-unit>
<trans-unit id="sd7728d2b6e1d25e9">
<source>Property mappings used for group creation.</source>
</trans-unit>
<trans-unit id="s7513372fe60f6387">
<source>Event volume</source>
</trans-unit>
web: Replace lingui.js with lit-localize (#5761) * \#\# Details web: replace lingui with lit/localize \#\# Changes This rather massive shift replaces the lingui and `t()` syntax with lit-localize, XLIFF, and the `msg()` syntax used by lit-localize. 90% of this work was mechanized; simple perl scripts found and replaced all uses of `t()` with the appropriate corresponding syntax for `msg()` and `msg(str())`. The XLIFF files were auto-generated from the PO files. They have not been audited, and they should be checked over by professional translators. The actual _strings_ have not been changed, but as this was a mechanized change there is always the possibility of mis-translation-- not by the translator, but by the script. * web: revise lit/localize: fix two installation issues. * web: revise localization TL;DR: - Replaced all of Lingui's `t()` syntax with `msg()` syntax. - Mechanically (i.e with a script) converted all of the PO files to XLIFF files - Refactored the localization code to be a bit smarter: - the function `getBestMatchLocale` takes the locale lists and a requested locale, and returns the first match of: - The locale's code exactly matches the requested locale - The locale code exactly matches the prefix of the requested locale (i.e the "en" part of "en-US") - the locale code's prefix exactly matches the prefix of the requested locale This function is passed to lit-locate's `loadLocale()`. - `activateLocale()` just calls `loadLocale()` now. - `autodetectLanguage` searches the following, and picks the first that returns a valid locale object, before passing it to `loadLocale()`: - The User's settings - A `?locale=` component found in `window.location.search` - The `window.navigator.language` field - English The `msg()` only runs when it's run. This seems obvious, but it means that you cannot cache strings at load time; they must be kept inside functions that are re-run so that the `msg()` engine can look up the strings in the preferred language of the user at that moment. You can use thunks-of-strings if you really need them that way. * Including the 'xliff-converter' in case anyone wants to review it. * The xliff-converter is tagged as 'xliff-converter', but has been deleted. \#\# Details - Resolves #5171 \#\# Changes \#\#\# New Features - Adds a "Add an Application" to the LibraryView if there are no applications and the user is an administrator. \#\#\# Breaking Changes - Adds breaking change which causes \<issue\>. \#\# Checklist - [ ] Local tests pass (`ak test authentik/`) - [ ] The code has been formatted (`make lint-fix`) If an API change has been made - [ ] The API schema has been updated (`make gen-build`) If changes to the frontend have been made - [ ] The code has been formatted (`make web`) - [ ] The translation files have been updated (`make i18n-extract`) If applicable - [ ] The documentation has been updated - [ ] The documentation has been formatted (`make website`) * web: fix redundant locales for zh suite. * web: prettier pass for locale update * web: localization moderization Changed the names of the lit-localize commands to make it clear they're part of the localization effort, and not just "build" and "extract". * update transifex config Signed-off-by: Jens Langhammer <jens@goauthentik.io> * fix package lock? Signed-off-by: Jens Langhammer <jens@goauthentik.io> * use build not compile Signed-off-by: Jens Langhammer <jens@goauthentik.io> * web: conversion to lit-localize The CI produced a list of problems that I hadn't caught earlier, due to a typo ("localize build" is correct, "localize compile" is not) I had left in package.json. They were minor and linty, but it was still wise to fix them. * web: replace lingui with lit/locale This commit fixes some minor linting issues that were hidden by a typo in package.json. The issues were not apparently problematic from a Javascript point of view, but they pointed to sloppy thinking in the progression of types through the system, so I cleaned them up and formalized the types from LocaleModule to AkLocale. * web: replace lingui with lit/localize One problem that has repeatedly come up is that localize's templates do not produce JavaScript that conforms with our shop style. I've replaced `build-locale` with a two-step that builds the locale *and* ensures that it conforms to the shop style via `prettier` every time. * web: replace lingui with lit-locale This commit applies the most recent bundle of translations to the new lit-locale aspect component. It also revises the algorithm for *finding* the correct locale, replacing the complex fall-back with some rather straightforward regular expressions. In the case of Chinese, the fallback comes at the end of the selection list, which may not be, er, politically valuable (since Taiwan and Hong Kong come before, being exceptions that need to be tested). If we need a different order for presentation, that'll be a future feature. * web: replace lingui with lit/locale Well, that was embarassing. --------- Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
2023-06-02 15:08:36 +00:00
</body>
</file>
</xliff>