web/user: new end-user interface (#1404)
* web/user: migrate to top navbar Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * web/user: prepare config from server Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * re-sort Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * remove old interface Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * update issue template Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * use notification badge Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * web/user: re-add go-to-admin button Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * *: fix remaining redirects directly to admin Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * make settings better Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * api: ensure sources and stages are sorted Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * web/user: add sessions and consent Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * providers/oauth2: add post wrapper to stage Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org> * website/docs: add new interface to release notes Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
9441be1ee2
commit
13e2eea72f
|
@ -27,7 +27,7 @@ If applicable, add screenshots to help explain your problem.
|
|||
Output of docker-compose logs or kubectl logs respectively
|
||||
|
||||
**Version and Deployment (please complete the following information):**
|
||||
- authentik version: [e.g. 0.10.0-stable]
|
||||
- authentik version: [e.g. 2021.8.5]
|
||||
- Deployment: [e.g. docker-compose, helm]
|
||||
|
||||
**Additional context**
|
||||
|
|
|
@ -20,7 +20,7 @@ If applicable, add screenshots to help explain your problem.
|
|||
Output of docker-compose logs or kubectl logs respectively
|
||||
|
||||
**Version and Deployment (please complete the following information):**
|
||||
- authentik version: [e.g. 0.10.0-stable]
|
||||
- authentik version: [e.g. 2021.8.5]
|
||||
- Deployment: [e.g. docker-compose, helm]
|
||||
|
||||
**Additional context**
|
||||
|
|
|
@ -11,6 +11,7 @@ from rest_framework.serializers import ModelSerializer
|
|||
from rest_framework.viewsets import GenericViewSet
|
||||
from ua_parser import user_agent_parser
|
||||
|
||||
from authentik.api.authorization import OwnerPermissions
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.models import AuthenticatedSession
|
||||
from authentik.events.geo import GEOIP_READER, GeoIPDict
|
||||
|
@ -102,11 +103,8 @@ class AuthenticatedSessionViewSet(
|
|||
search_fields = ["user__username", "last_ip", "last_user_agent"]
|
||||
filterset_fields = ["user__username", "last_ip", "last_user_agent"]
|
||||
ordering = ["user__username"]
|
||||
filter_backends = [
|
||||
DjangoFilterBackend,
|
||||
OrderingFilter,
|
||||
SearchFilter,
|
||||
]
|
||||
permission_classes = [OwnerPermissions]
|
||||
filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter]
|
||||
|
||||
def get_queryset(self):
|
||||
user = self.request.user if self.request else get_anonymous_user()
|
||||
|
|
|
@ -95,7 +95,9 @@ class SourceViewSet(
|
|||
@action(detail=False, pagination_class=None, filter_backends=[])
|
||||
def user_settings(self, request: Request) -> Response:
|
||||
"""Get all sources the user can configure"""
|
||||
_all_sources: Iterable[Source] = Source.objects.filter(enabled=True).select_subclasses()
|
||||
_all_sources: Iterable[Source] = (
|
||||
Source.objects.filter(enabled=True).select_subclasses().order_by("name")
|
||||
)
|
||||
matching_sources: list[UserSettingSerializer] = []
|
||||
for source in _all_sources:
|
||||
user_settings = source.ui_user_settings
|
||||
|
|
|
@ -184,7 +184,7 @@ class SourceFlowManager:
|
|||
# Ensure redirect is carried through when user was trying to
|
||||
# authorize application
|
||||
final_redirect = self.request.session.get(SESSION_KEY_GET, {}).get(
|
||||
NEXT_ARG_NAME, "authentik_core:if-admin"
|
||||
NEXT_ARG_NAME, "authentik_core:if-user"
|
||||
)
|
||||
kwargs.update(
|
||||
{
|
||||
|
@ -243,9 +243,9 @@ class SourceFlowManager:
|
|||
return self.handle_auth_user(connection)
|
||||
return redirect(
|
||||
reverse(
|
||||
"authentik_core:if-admin",
|
||||
"authentik_core:if-user",
|
||||
)
|
||||
+ f"#/user;page-{self.source.slug}"
|
||||
+ f"#/settings;page-{self.source.slug}"
|
||||
)
|
||||
|
||||
def handle_enroll(
|
||||
|
|
|
@ -21,7 +21,7 @@ You've logged out of {{ application }}.
|
|||
{% endblocktrans %}
|
||||
</p>
|
||||
|
||||
<a id="ak-back-home" href="{% url 'authentik_core:if-admin' %}" class="pf-c-button pf-m-primary">{% trans 'Go back to overview' %}</a>
|
||||
<a id="ak-back-home" href="{% url 'authentik_core:root-redirect' %}" class="pf-c-button pf-m-primary">{% trans 'Go back to overview' %}</a>
|
||||
|
||||
<a id="logout" href="{% url 'authentik_flows:default-invalidation' %}" class="pf-c-button pf-m-secondary">{% trans 'Log out of authentik' %}</a>
|
||||
|
||||
|
|
|
@ -58,4 +58,4 @@ class TestImpersonation(TestCase):
|
|||
self.client.force_login(self.other_user)
|
||||
|
||||
response = self.client.get(reverse("authentik_core:impersonate-end"))
|
||||
self.assertRedirects(response, reverse("authentik_core:if-admin"))
|
||||
self.assertRedirects(response, reverse("authentik_core:if-user"))
|
||||
|
|
|
@ -28,7 +28,7 @@ class ImpersonateInitView(View):
|
|||
|
||||
Event.new(EventAction.IMPERSONATION_STARTED).from_http(request, user_to_be)
|
||||
|
||||
return redirect("authentik_core:if-admin")
|
||||
return redirect("authentik_core:if-user")
|
||||
|
||||
|
||||
class ImpersonateEndView(View):
|
||||
|
@ -41,7 +41,7 @@ class ImpersonateEndView(View):
|
|||
or SESSION_IMPERSONATE_ORIGINAL_USER not in request.session
|
||||
):
|
||||
LOGGER.debug("Can't end impersonation", user=request.user)
|
||||
return redirect("authentik_core:if-admin")
|
||||
return redirect("authentik_core:if-user")
|
||||
|
||||
original_user = request.session[SESSION_IMPERSONATE_ORIGINAL_USER]
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ class StageViewSet(
|
|||
@action(detail=False, pagination_class=None, filter_backends=[])
|
||||
def user_settings(self, request: Request) -> Response:
|
||||
"""Get all stages the user can configure"""
|
||||
_all_stages: Iterable[Stage] = Stage.objects.all().select_subclasses()
|
||||
_all_stages: Iterable[Stage] = Stage.objects.all().select_subclasses().order_by("name")
|
||||
matching_stages: list[dict] = []
|
||||
for stage in _all_stages:
|
||||
user_settings = stage.ui_user_settings
|
||||
|
|
|
@ -238,6 +238,10 @@ class OAuthFulfillmentStage(StageView):
|
|||
parsed = urlparse(uri)
|
||||
return HttpResponseRedirectScheme(uri, allowed_schemes=[parsed.scheme])
|
||||
|
||||
def post(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||
"""Wrapper when this stage gets hit with a post request"""
|
||||
return self.get(request, *args, **kwargs)
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||
"""final Stage of an OAuth2 Flow"""
|
||||
|
|
|
@ -22,4 +22,4 @@ class UseTokenView(View):
|
|||
login(request, token.user, backend=BACKEND_INBUILT)
|
||||
token.delete()
|
||||
messages.warning(request, _("Used recovery-link to authenticate."))
|
||||
return redirect("authentik_core:if-admin")
|
||||
return redirect("authentik_core:if-user")
|
||||
|
|
|
@ -190,7 +190,7 @@ class ResponseProcessor:
|
|||
# Ensure redirect is carried through when user was trying to
|
||||
# authorize application
|
||||
final_redirect = self._http_request.session.get(SESSION_KEY_GET, {}).get(
|
||||
NEXT_ARG_NAME, "authentik_core:if-admin"
|
||||
NEXT_ARG_NAME, "authentik_core:if-user"
|
||||
)
|
||||
if matching_users.exists():
|
||||
# User exists already, switch to authentication flow
|
||||
|
|
|
@ -71,7 +71,7 @@ class InitiateView(View):
|
|||
# Ensure redirect is carried through when user was trying to
|
||||
# authorize application
|
||||
final_redirect = self.request.session.get(SESSION_KEY_GET, {}).get(
|
||||
NEXT_ARG_NAME, "authentik_core:if-admin"
|
||||
NEXT_ARG_NAME, "authentik_core:if-user"
|
||||
)
|
||||
kwargs.update(
|
||||
{
|
||||
|
|
|
@ -28,6 +28,15 @@ export class Route {
|
|||
return this;
|
||||
}
|
||||
|
||||
redirectRaw(to: string): Route {
|
||||
this.callback = () => {
|
||||
console.debug(`authentik/router: redirecting ${to}`);
|
||||
window.location.hash = `${to}`;
|
||||
return html``;
|
||||
};
|
||||
return this;
|
||||
}
|
||||
|
||||
then(render: (args: RouteArgs) => TemplateResult): Route {
|
||||
this.callback = render;
|
||||
return this;
|
||||
|
|
|
@ -32,7 +32,7 @@ export class SidebarUser extends LitElement {
|
|||
|
||||
render(): TemplateResult {
|
||||
return html`
|
||||
<a href="#/user" class="pf-c-nav__link user-avatar" id="user-settings">
|
||||
<a href="/if/user/#settings" class="pf-c-nav__link user-avatar" id="user-settings">
|
||||
${until(
|
||||
me().then((u) => {
|
||||
return html`<img
|
||||
|
|
|
@ -172,7 +172,7 @@ export class AdminInterface extends LitElement {
|
|||
}),
|
||||
)}
|
||||
<ak-sidebar-item path="/if/user/" ?isAbsoluteLink=${true} ?highlight=${true}>
|
||||
<span slot="label">${t`Go to user interface`}</span>
|
||||
<span slot="label">${t`User interface`}</span>
|
||||
</ak-sidebar-item>
|
||||
<ak-sidebar-item path="/administration/overview">
|
||||
<span slot="label">${t`Overview`}</span>
|
||||
|
|
|
@ -14,31 +14,30 @@ import "../elements/sidebar/SidebarItem";
|
|||
import { t } from "@lingui/macro";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFBrand from "@patternfly/patternfly/components/Brand/brand.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFDrawer from "@patternfly/patternfly/components/Drawer/drawer.css";
|
||||
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
|
||||
import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css";
|
||||
import PFNotificationBadge from "@patternfly/patternfly/components/NotificationBadge/notification-badge.css";
|
||||
import AKGlobal from "../authentik.css";
|
||||
|
||||
import "../elements/router/RouterOutlet";
|
||||
import "../elements/messages/MessageContainer";
|
||||
import "../elements/notifications/NotificationDrawer";
|
||||
import "../elements/sidebar/Sidebar";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import {
|
||||
EVENT_API_DRAWER_TOGGLE,
|
||||
EVENT_NOTIFICATION_DRAWER_TOGGLE,
|
||||
EVENT_SIDEBAR_TOGGLE,
|
||||
VERSION,
|
||||
} from "../constants";
|
||||
import { AdminApi, Version } from "@goauthentik/api";
|
||||
import { DEFAULT_CONFIG } from "../api/Config";
|
||||
import { EVENT_API_DRAWER_TOGGLE, EVENT_NOTIFICATION_DRAWER_TOGGLE } from "../constants";
|
||||
import { CurrentTenant, EventsApi } from "@goauthentik/api";
|
||||
import { DEFAULT_CONFIG, tenant } from "../api/Config";
|
||||
import { WebsocketClient } from "../common/ws";
|
||||
import { ROUTES } from "../routesUser";
|
||||
import { first } from "../utils";
|
||||
import { DefaultTenant } from "../elements/sidebar/SidebarBrand";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { uiConfig } from "../user/config";
|
||||
|
||||
@customElement("ak-interface-user")
|
||||
export class UserInterface extends LitElement {
|
||||
@property({ type: Boolean })
|
||||
sidebarOpen = true;
|
||||
|
||||
@property({ type: Boolean })
|
||||
notificationOpen = false;
|
||||
|
||||
|
@ -47,14 +46,22 @@ export class UserInterface extends LitElement {
|
|||
|
||||
ws: WebsocketClient;
|
||||
|
||||
private version: Promise<Version>;
|
||||
@property({ attribute: false })
|
||||
tenant: CurrentTenant = DefaultTenant;
|
||||
|
||||
@property({ type: Number })
|
||||
notificationsCount = -1;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
PFBase,
|
||||
PFBrand,
|
||||
PFPage,
|
||||
PFAvatar,
|
||||
PFButton,
|
||||
PFDrawer,
|
||||
PFDropdown,
|
||||
PFNotificationBadge,
|
||||
AKGlobal,
|
||||
css`
|
||||
.pf-c-page__main,
|
||||
|
@ -65,6 +72,12 @@ export class UserInterface extends LitElement {
|
|||
.display-none {
|
||||
display: none;
|
||||
}
|
||||
.pf-c-brand {
|
||||
min-height: 48px;
|
||||
}
|
||||
.has-notifications {
|
||||
color: #2b9af3;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
@ -72,29 +85,152 @@ export class UserInterface extends LitElement {
|
|||
constructor() {
|
||||
super();
|
||||
this.ws = new WebsocketClient();
|
||||
this.sidebarOpen = window.innerWidth >= 1280;
|
||||
window.addEventListener("resize", () => {
|
||||
this.sidebarOpen = window.innerWidth >= 1280;
|
||||
});
|
||||
window.addEventListener(EVENT_SIDEBAR_TOGGLE, () => {
|
||||
this.sidebarOpen = !this.sidebarOpen;
|
||||
});
|
||||
window.addEventListener(EVENT_NOTIFICATION_DRAWER_TOGGLE, () => {
|
||||
this.notificationOpen = !this.notificationOpen;
|
||||
});
|
||||
window.addEventListener(EVENT_API_DRAWER_TOGGLE, () => {
|
||||
this.apiDrawerOpen = !this.apiDrawerOpen;
|
||||
});
|
||||
this.version = new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
|
||||
tenant().then((tenant) => (this.tenant = tenant));
|
||||
new EventsApi(DEFAULT_CONFIG)
|
||||
.eventsNotificationsList({
|
||||
seen: false,
|
||||
ordering: "-created",
|
||||
pageSize: 1,
|
||||
})
|
||||
.then((r) => {
|
||||
this.notificationsCount = r.pagination.count;
|
||||
});
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html` <div class="pf-c-page">
|
||||
<ak-sidebar
|
||||
class="pf-c-page__sidebar ${this.sidebarOpen ? "pf-m-expanded" : "pf-m-collapsed"}"
|
||||
<header class="pf-c-page__header">
|
||||
<div class="pf-c-page__header-brand">
|
||||
<a href="#/" class="pf-c-page__header-brand-link">
|
||||
<img
|
||||
class="pf-c-brand"
|
||||
src="${first(this.tenant.brandingLogo, DefaultTenant.brandingLogo)}"
|
||||
alt="${(this.tenant.brandingTitle, DefaultTenant.brandingTitle)}"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="pf-c-page__header-tools">
|
||||
<div class="pf-c-page__header-tools-group">
|
||||
${until(
|
||||
uiConfig().then((config) => {
|
||||
if (!config.enabledFeatures.apiDrawer) {
|
||||
return html``;
|
||||
}
|
||||
return html`<div
|
||||
class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-lg"
|
||||
>
|
||||
${this.renderSidebarItems()}
|
||||
</ak-sidebar>
|
||||
<button
|
||||
class="pf-c-button pf-m-plain"
|
||||
type="button"
|
||||
@click=${() => {
|
||||
this.apiDrawerOpen = !this.apiDrawerOpen;
|
||||
}}
|
||||
>
|
||||
<i class="fas fa-code" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>`;
|
||||
}),
|
||||
)}
|
||||
${until(
|
||||
uiConfig().then((config) => {
|
||||
if (!config.enabledFeatures.notificationDrawer) {
|
||||
return html``;
|
||||
}
|
||||
return html`
|
||||
<button
|
||||
class="pf-c-button pf-m-plain"
|
||||
type="button"
|
||||
aria-label="${t`Unread notifications`}"
|
||||
@click=${() => {
|
||||
this.notificationOpen = !this.notificationOpen;
|
||||
}}
|
||||
>
|
||||
<span
|
||||
class="pf-c-notification-badge ${this
|
||||
.notificationsCount > 0
|
||||
? html`pf-m-unread`
|
||||
: html``}"
|
||||
>
|
||||
<i class="pf-icon-bell" aria-hidden="true"></i>
|
||||
<span class="pf-c-notification-badge__count"
|
||||
>${this.notificationsCount}</span
|
||||
>
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
}),
|
||||
)}
|
||||
${until(
|
||||
uiConfig().then((config) => {
|
||||
if (!config.enabledFeatures.settings) {
|
||||
return html``;
|
||||
}
|
||||
return html` <div
|
||||
class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-lg"
|
||||
>
|
||||
<a
|
||||
class="pf-c-button pf-m-plain"
|
||||
type="button"
|
||||
href="#/settings"
|
||||
>
|
||||
<i class="fas fa-cog" aria-hidden="true"></i>
|
||||
</a>
|
||||
</div>`;
|
||||
}),
|
||||
)}
|
||||
<a href="/flows/-/default/invalidation/" class="pf-c-button pf-m-plain">
|
||||
<i class="fas fa-sign-out-alt" aria-hidden="true"></i>
|
||||
</a>
|
||||
${until(
|
||||
me().then((u) => {
|
||||
if (!u.user.isSuperuser) return html``;
|
||||
return html`
|
||||
<a class="pf-c-button pf-m-primary pf-m-small" href="/if/admin">
|
||||
${t`Admin interface`}
|
||||
</a>
|
||||
`;
|
||||
}),
|
||||
)}
|
||||
</div>
|
||||
<div class="pf-c-page__header-tools-group">
|
||||
<div class="pf-c-page__header-tools-item pf-m-hidden pf-m-visible-on-md">
|
||||
<span class="pf-c-dropdown__toggle-text"
|
||||
>${until(
|
||||
uiConfig().then((config) => {
|
||||
return me().then((me) => {
|
||||
switch (config.navbar.userDisplay) {
|
||||
case "username":
|
||||
return me.user.username;
|
||||
case "name":
|
||||
return me.user.name;
|
||||
case "email":
|
||||
return me.user.email;
|
||||
default:
|
||||
return me.user.username;
|
||||
}
|
||||
});
|
||||
}),
|
||||
)}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
${until(
|
||||
me().then((me) => {
|
||||
return html`<img
|
||||
class="pf-c-avatar"
|
||||
src=${me.user.avatar}
|
||||
alt="${t`Avatar image`}"
|
||||
/>`;
|
||||
}),
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
<div class="pf-c-page__drawer">
|
||||
<div
|
||||
class="pf-c-drawer ${this.notificationOpen || this.apiDrawerOpen
|
||||
|
@ -107,7 +243,7 @@ export class UserInterface extends LitElement {
|
|||
<main class="pf-c-page__main">
|
||||
<ak-router-outlet
|
||||
role="main"
|
||||
class="pf-c-page__main"
|
||||
class="pf-l-bullseye__item pf-c-page__main"
|
||||
tabindex="-1"
|
||||
id="main-content"
|
||||
defaultUrl="/library"
|
||||
|
@ -134,43 +270,4 @@ export class UserInterface extends LitElement {
|
|||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderSidebarItems(): TemplateResult {
|
||||
return html`
|
||||
${until(
|
||||
this.version.then((version) => {
|
||||
if (version.versionCurrent !== VERSION) {
|
||||
return html`<ak-sidebar-item ?highlight=${true}>
|
||||
<span slot="label"
|
||||
>${t`A newer version of the frontend is available.`}</span
|
||||
>
|
||||
</ak-sidebar-item>`;
|
||||
}
|
||||
return html``;
|
||||
}),
|
||||
)}
|
||||
${until(
|
||||
me().then((u) => {
|
||||
if (u.original) {
|
||||
return html`<ak-sidebar-item
|
||||
?highlight=${true}
|
||||
?isAbsoluteLink=${true}
|
||||
path=${`/-/impersonation/end/?back=${window.location.pathname}%23${window.location.hash}`}
|
||||
>
|
||||
<span slot="label"
|
||||
>${t`You're currently impersonating ${u.user.username}. Click to stop.`}</span
|
||||
>
|
||||
</ak-sidebar-item>`;
|
||||
}
|
||||
return html``;
|
||||
}),
|
||||
)}
|
||||
<ak-sidebar-item path="/if/admin" ?isAbsoluteLink=${true} ?highlight=${true}>
|
||||
<span slot="label">${t`Go to admin interface`}</span>
|
||||
</ak-sidebar-item>
|
||||
<ak-sidebar-item path="/library">
|
||||
<span slot="label">${t`Library`}</span>
|
||||
</ak-sidebar-item>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@ msgid "8 digits, not compatible with apps like Google Authenticator"
|
|||
msgstr "8 digits, not compatible with apps like Google Authenticator"
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "A newer version of the frontend is available."
|
||||
msgstr "A newer version of the frontend is available."
|
||||
|
||||
|
@ -172,6 +171,10 @@ msgstr "Additional user DN, prepended to the Base DN."
|
|||
#~ msgid "Admin"
|
||||
#~ msgstr "Admin"
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Admin interface"
|
||||
msgstr "Admin interface"
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/pages/providers/saml/SAMLProviderForm.ts
|
||||
|
@ -284,10 +287,8 @@ msgid "Application(s)"
|
|||
msgstr "Application(s)"
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#: src/pages/LibraryPage.ts
|
||||
#: src/pages/applications/ApplicationListPage.ts
|
||||
#: src/pages/outposts/OutpostForm.ts
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "Applications"
|
||||
msgstr "Applications"
|
||||
|
||||
|
@ -386,8 +387,7 @@ msgid "Authentication flow"
|
|||
msgstr "Authentication flow"
|
||||
|
||||
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Authenticator"
|
||||
msgstr "Authenticator"
|
||||
|
||||
|
@ -423,6 +423,10 @@ msgstr "Authorize URL"
|
|||
msgid "Authorized application:"
|
||||
msgstr "Authorized application:"
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Avatar image"
|
||||
msgstr "Avatar image"
|
||||
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
msgid "Backends"
|
||||
msgstr "Backends"
|
||||
|
@ -608,8 +612,7 @@ msgstr "Certificate/Key used for authentication. Can be left empty for no authen
|
|||
msgid "Certificates"
|
||||
msgstr "Certificates"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsPassword.ts
|
||||
#: src/user/user-settings/settings/UserSettingsPassword.ts
|
||||
#: src/user/user-settings/stages/UserSettingsPassword.ts
|
||||
msgid "Change password"
|
||||
msgstr "Change password"
|
||||
|
||||
|
@ -617,8 +620,7 @@ msgstr "Change password"
|
|||
msgid "Change status"
|
||||
msgstr "Change status"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsPassword.ts
|
||||
#: src/user/user-settings/settings/UserSettingsPassword.ts
|
||||
#: src/user/user-settings/stages/UserSettingsPassword.ts
|
||||
msgid "Change your password"
|
||||
msgstr "Change your password"
|
||||
|
||||
|
@ -796,8 +798,7 @@ msgstr "Configuration flow"
|
|||
msgid "Configuration stage"
|
||||
msgstr "Configuration stage"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Configure WebAuthn"
|
||||
msgstr "Configure WebAuthn"
|
||||
|
||||
|
@ -829,10 +830,10 @@ msgstr "Configure how the flow executor should handle an invalid response to a c
|
|||
msgid "Configure how the issuer field of the ID Token should be filled."
|
||||
msgstr "Configure how the issuer field of the ID Token should be filled."
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Configure settings relevant to your user profile."
|
||||
msgstr "Configure settings relevant to your user profile."
|
||||
#:
|
||||
#:
|
||||
#~ msgid "Configure settings relevant to your user profile."
|
||||
#~ msgstr "Configure settings relevant to your user profile."
|
||||
|
||||
#: src/pages/providers/saml/SAMLProviderForm.ts
|
||||
msgid "Configure the maximum allowed time drift for an asseration."
|
||||
|
@ -846,15 +847,16 @@ msgstr "Configure visual settings and defaults for different domains."
|
|||
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
|
||||
msgstr "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
msgid "Connect"
|
||||
msgstr "Connect"
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/pages/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Connected services"
|
||||
msgstr "Connected services"
|
||||
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsPlex.ts
|
||||
msgid "Connected."
|
||||
msgstr "Connected."
|
||||
|
||||
|
@ -940,7 +942,6 @@ msgstr "Cookie domain"
|
|||
msgid "Copy"
|
||||
msgstr "Copy"
|
||||
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Copy Key"
|
||||
msgstr "Copy Key"
|
||||
|
@ -998,8 +999,6 @@ msgstr "Copy recovery link"
|
|||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
|
@ -1008,8 +1007,6 @@ msgstr "Copy recovery link"
|
|||
msgid "Create"
|
||||
msgstr "Create"
|
||||
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Create App password"
|
||||
|
@ -1087,8 +1084,6 @@ msgid "Create Tenant"
|
|||
msgstr "Create Tenant"
|
||||
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Create Token"
|
||||
|
@ -1126,8 +1121,7 @@ msgstr "Create {0}"
|
|||
msgid "Created by"
|
||||
msgstr "Created by"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Created {0}"
|
||||
msgstr "Created {0}"
|
||||
|
||||
|
@ -1210,10 +1204,8 @@ msgstr "Define how notifications are sent to users, like Email or Webhook."
|
|||
#: src/pages/stages/prompt/PromptListPage.ts
|
||||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Delete"
|
||||
msgstr "Delete"
|
||||
|
@ -1239,7 +1231,6 @@ msgstr "Delete"
|
|||
#~ msgid "Delete Session"
|
||||
#~ msgstr "Delete Session"
|
||||
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
msgid "Delete account"
|
||||
msgstr "Delete account"
|
||||
|
@ -1277,7 +1268,6 @@ msgstr "Deny the user access"
|
|||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
#: src/pages/system-tasks/SystemTaskListPage.ts
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/user/user-settings/tokens/UserTokenForm.ts
|
||||
msgid "Description"
|
||||
msgstr "Description"
|
||||
|
@ -1319,8 +1309,7 @@ msgstr "Device classes"
|
|||
msgid "Device classes which can be used to authenticate."
|
||||
msgstr "Device classes which can be used to authenticate."
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Device name"
|
||||
msgstr "Device name"
|
||||
|
||||
|
@ -1338,18 +1327,15 @@ msgstr "Digits"
|
|||
#~ msgid "Disable"
|
||||
#~ msgstr "Disable"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
msgid "Disable Duo authenticator"
|
||||
msgstr "Disable Duo authenticator"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
msgid "Disable Static Tokens"
|
||||
msgstr "Disable Static Tokens"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Disable Time-based OTP"
|
||||
msgstr "Disable Time-based OTP"
|
||||
|
||||
|
@ -1357,10 +1343,8 @@ msgstr "Disable Time-based OTP"
|
|||
msgid "Disabled"
|
||||
msgstr "Disabled"
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/pages/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsPlex.ts
|
||||
msgid "Disconnect"
|
||||
msgstr "Disconnect"
|
||||
|
||||
|
@ -1395,8 +1379,7 @@ msgstr "Due to protocol limitations, this certificate is only used when the outp
|
|||
msgid "Dummy stage used for testing. Shows a simple continue button and always passes."
|
||||
msgstr "Dummy stage used for testing. Shows a simple continue button and always passes."
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
msgid "Duo"
|
||||
msgstr "Duo"
|
||||
|
||||
|
@ -1455,7 +1438,6 @@ msgstr "Edit Stage"
|
|||
msgid "Edit User"
|
||||
msgstr "Edit User"
|
||||
|
||||
#: src/pages/LibraryPage.ts
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "Either no applications are defined, or you don't have access to any."
|
||||
msgstr "Either no applications are defined, or you don't have access to any."
|
||||
|
@ -1463,7 +1445,6 @@ msgstr "Either no applications are defined, or you don't have access to any."
|
|||
#: src/flows/stages/identification/IdentificationStage.ts
|
||||
#: src/pages/events/TransportForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
#: src/pages/users/UserViewPage.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
|
@ -1503,8 +1484,7 @@ msgstr "Embedded outpost is not configured correctly."
|
|||
#~ msgid "Enable"
|
||||
#~ msgstr "Enable"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
msgid "Enable Duo authenticator"
|
||||
msgstr "Enable Duo authenticator"
|
||||
|
||||
|
@ -1512,13 +1492,11 @@ msgstr "Enable Duo authenticator"
|
|||
msgid "Enable StartTLS"
|
||||
msgstr "Enable StartTLS"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
msgid "Enable Static Tokens"
|
||||
msgstr "Enable Static Tokens"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Enable TOTP"
|
||||
msgstr "Enable TOTP"
|
||||
|
||||
|
@ -1570,13 +1548,11 @@ msgstr "Error when creating credential: {err}"
|
|||
msgid "Error when validating assertion on server: {err}"
|
||||
msgstr "Error when validating assertion on server: {err}"
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/SourceSettings.ts
|
||||
msgid "Error: unsupported source settings: {0}"
|
||||
msgstr "Error: unsupported source settings: {0}"
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/StageSettings.ts
|
||||
msgid "Error: unsupported stage settings: {0}"
|
||||
msgstr "Error: unsupported stage settings: {0}"
|
||||
|
||||
|
@ -1660,8 +1636,6 @@ msgstr "Expires on"
|
|||
msgid "Expires?"
|
||||
msgstr "Expires?"
|
||||
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Expiring"
|
||||
|
@ -1926,9 +1900,9 @@ msgstr "Generate"
|
|||
msgid "Generate Certificate-Key Pair"
|
||||
msgstr "Generate Certificate-Key Pair"
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Go to admin interface"
|
||||
msgstr "Go to admin interface"
|
||||
#:
|
||||
#~ msgid "Go to admin interface"
|
||||
#~ msgstr "Go to admin interface"
|
||||
|
||||
#: src/elements/table/TablePagination.ts
|
||||
msgid "Go to next page"
|
||||
|
@ -1938,9 +1912,9 @@ msgstr "Go to next page"
|
|||
msgid "Go to previous page"
|
||||
msgstr "Go to previous page"
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
msgid "Go to user interface"
|
||||
msgstr "Go to user interface"
|
||||
#:
|
||||
#~ msgid "Go to user interface"
|
||||
#~ msgstr "Go to user interface"
|
||||
|
||||
#: src/pages/events/RuleForm.ts
|
||||
#: src/pages/policies/PolicyBindingForm.ts
|
||||
|
@ -2077,8 +2051,6 @@ msgstr "Icon shown in the browser tab."
|
|||
#: src/pages/system-tasks/SystemTaskListPage.ts
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Identifier"
|
||||
|
@ -2185,7 +2157,6 @@ msgstr "Integrations"
|
|||
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Intent"
|
||||
msgstr "Intent"
|
||||
|
@ -2327,9 +2298,9 @@ msgstr "Launch URL"
|
|||
msgid "Let the user identify themselves with their username or Email address."
|
||||
msgstr "Let the user identify themselves with their username or Email address."
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Library"
|
||||
msgstr "Library"
|
||||
#:
|
||||
#~ msgid "Library"
|
||||
#~ msgstr "Library"
|
||||
|
||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||
#: src/pages/sources/plex/PlexSourceForm.ts
|
||||
|
@ -2374,7 +2345,8 @@ msgstr "Load servers"
|
|||
#: src/flows/stages/prompt/PromptStage.ts
|
||||
#: src/pages/applications/ApplicationViewPage.ts
|
||||
#: src/pages/applications/ApplicationViewPage.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/user/user-settings/SourceSettings.ts
|
||||
#: src/user/user-settings/StageSettings.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
#: src/utils.ts
|
||||
msgid "Loading"
|
||||
|
@ -2599,11 +2571,14 @@ msgstr "Model updated"
|
|||
#~ msgid "Monitor"
|
||||
#~ msgstr "Monitor"
|
||||
|
||||
#: src/pages/LibraryPage.ts
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "My Applications"
|
||||
msgstr "My Applications"
|
||||
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "My applications"
|
||||
msgstr "My applications"
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/applications/ApplicationForm.ts
|
||||
#: src/pages/applications/ApplicationListPage.ts
|
||||
|
@ -2677,7 +2652,6 @@ msgstr "My Applications"
|
|||
#: src/pages/stages/user_login/UserLoginStageForm.ts
|
||||
#: src/pages/stages/user_logout/UserLogoutStageForm.ts
|
||||
#: src/pages/stages/user_write/UserWriteStageForm.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/GroupSelectModal.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
|
@ -2729,14 +2703,12 @@ msgstr "Newly created users are added to this group, if a group is selected."
|
|||
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/GroupSelectModal.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "No"
|
||||
msgstr "No"
|
||||
|
||||
#: src/pages/LibraryPage.ts
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "No Applications available."
|
||||
msgstr "No Applications available."
|
||||
|
@ -2803,10 +2775,8 @@ msgstr "Not available"
|
|||
msgid "Not configured action"
|
||||
msgstr "Not configured action"
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/pages/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsPlex.ts
|
||||
msgid "Not connected."
|
||||
msgstr "Not connected."
|
||||
|
||||
|
@ -3071,6 +3041,10 @@ msgstr "Password set"
|
|||
msgid "Password stage"
|
||||
msgstr "Password stage"
|
||||
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Password, 2FA, etc"
|
||||
msgstr "Password, 2FA, etc"
|
||||
|
||||
#: src/pages/stages/prompt/PromptForm.ts
|
||||
msgid "Password: Masked input, password is validated against sources. Policies still have to be applied to this Stage. If two of these are used in the same stage, they are ensured to be identical."
|
||||
msgstr "Password: Masked input, password is validated against sources. Policies still have to be applied to this Stage. If two of these are used in the same stage, they are ensured to be identical."
|
||||
|
@ -3471,7 +3445,6 @@ msgstr "Required"
|
|||
msgid "Required."
|
||||
msgstr "Required."
|
||||
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/ServiceAccountForm.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
|
@ -3849,10 +3822,8 @@ msgstr "Something went wrong! Please try again later."
|
|||
msgid "Source linked"
|
||||
msgstr "Source linked"
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/pages/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsPlex.ts
|
||||
msgid "Source {0}"
|
||||
msgstr "Source {0}"
|
||||
|
||||
|
@ -3962,8 +3933,7 @@ msgstr "State"
|
|||
msgid "Static Tokens"
|
||||
msgstr "Static Tokens"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
msgid "Static tokens"
|
||||
msgstr "Static tokens"
|
||||
|
||||
|
@ -3979,21 +3949,15 @@ msgstr "Statically deny the flow. To use this stage effectively, disable *Evalua
|
|||
msgid "Status"
|
||||
msgstr "Status"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Status: Disabled"
|
||||
msgstr "Status: Disabled"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Status: Enabled"
|
||||
msgstr "Status: Enabled"
|
||||
|
||||
|
@ -4134,7 +4098,6 @@ msgid "Successfully created tenant."
|
|||
msgstr "Successfully created tenant."
|
||||
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/user/user-settings/tokens/UserTokenForm.ts
|
||||
msgid "Successfully created token."
|
||||
msgstr "Successfully created token."
|
||||
|
@ -4193,13 +4156,11 @@ msgstr "Successfully updated binding."
|
|||
msgid "Successfully updated certificate-key pair."
|
||||
msgstr "Successfully updated certificate-key pair."
|
||||
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
msgid "Successfully updated details."
|
||||
msgstr "Successfully updated details."
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Successfully updated device."
|
||||
msgstr "Successfully updated device."
|
||||
|
||||
|
@ -4294,7 +4255,6 @@ msgid "Successfully updated tenant."
|
|||
msgstr "Successfully updated tenant."
|
||||
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/user/user-settings/tokens/UserTokenForm.ts
|
||||
msgid "Successfully updated token."
|
||||
msgstr "Successfully updated token."
|
||||
|
@ -4538,8 +4498,7 @@ msgstr "Time in minutes the token sent is valid."
|
|||
msgid "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. (Format: hours=1;minutes=2;seconds=3)."
|
||||
msgstr "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. (Format: hours=1;minutes=2;seconds=3)."
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Time-based One-Time Passwords"
|
||||
msgstr "Time-based One-Time Passwords"
|
||||
|
||||
|
@ -4586,7 +4545,6 @@ msgid "Token validity"
|
|||
msgstr "Token validity"
|
||||
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Token(s)"
|
||||
msgstr "Token(s)"
|
||||
|
@ -4600,7 +4558,6 @@ msgstr "Tokens"
|
|||
msgid "Tokens & App passwords"
|
||||
msgstr "Tokens & App passwords"
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Tokens and App passwords"
|
||||
msgstr "Tokens and App passwords"
|
||||
|
@ -4722,6 +4679,10 @@ msgstr "Unknown"
|
|||
#~ msgid "Unmanaged"
|
||||
#~ msgstr "Unmanaged"
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Unread notifications"
|
||||
msgstr "Unread notifications"
|
||||
|
||||
#: src/pages/admin-overview/charts/LDAPSyncStatusChart.ts
|
||||
msgid "Unsynced sources"
|
||||
msgstr "Unsynced sources"
|
||||
|
@ -4761,18 +4722,13 @@ msgstr "Up-to-date!"
|
|||
#: src/pages/stages/prompt/PromptListPage.ts
|
||||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/UserActiveForm.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/pages/users/UserViewPage.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Update"
|
||||
msgstr "Update"
|
||||
|
@ -4856,7 +4812,6 @@ msgid "Update Tenant"
|
|||
msgstr "Update Tenant"
|
||||
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Update Token"
|
||||
msgstr "Update Token"
|
||||
|
@ -4871,7 +4826,6 @@ msgstr "Update User"
|
|||
msgid "Update available"
|
||||
msgstr "Update available"
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Update details"
|
||||
msgstr "Update details"
|
||||
|
@ -4949,7 +4903,6 @@ msgstr "Use this tenant for each domain that doesn't have a dedicated tenant."
|
|||
#: src/pages/property-mappings/PropertyMappingTestForm.ts
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "User"
|
||||
|
@ -4968,10 +4921,10 @@ msgstr "User Property Mappings"
|
|||
msgid "User Reputation"
|
||||
msgstr "User Reputation"
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "User Settings"
|
||||
msgstr "User Settings"
|
||||
#:
|
||||
#:
|
||||
#~ msgid "User Settings"
|
||||
#~ msgstr "User Settings"
|
||||
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
msgid "User database + LDAP password"
|
||||
|
@ -4985,7 +4938,6 @@ msgstr "User database + app passwords"
|
|||
msgid "User database + standard password"
|
||||
msgstr "User database + standard password"
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "User details"
|
||||
msgstr "User details"
|
||||
|
@ -4998,6 +4950,10 @@ msgstr "User events"
|
|||
msgid "User fields"
|
||||
msgstr "User fields"
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
msgid "User interface"
|
||||
msgstr "User interface"
|
||||
|
||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||
#: src/pages/sources/plex/PlexSourceForm.ts
|
||||
msgid "User matching mode"
|
||||
|
@ -5028,7 +4984,6 @@ msgstr "User {0}"
|
|||
msgid "User's avatar"
|
||||
msgstr "User's avatar"
|
||||
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
msgid "User's display name."
|
||||
|
@ -5053,7 +5008,6 @@ msgstr "Userinfo URL"
|
|||
#: src/flows/stages/identification/IdentificationStage.ts
|
||||
#: src/pages/policies/reputation/UserReputationListPage.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/ServiceAccountForm.ts
|
||||
#: src/pages/users/ServiceAccountForm.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
|
@ -5177,8 +5131,7 @@ msgstr "Warning: authentik Domain is not configured, authentication will not wor
|
|||
msgid "WebAuthn Authenticators"
|
||||
msgstr "WebAuthn Authenticators"
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "WebAuthn Devices"
|
||||
msgstr "WebAuthn Devices"
|
||||
|
||||
|
@ -5271,7 +5224,6 @@ msgstr "X509 Subject"
|
|||
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/GroupSelectModal.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
|
@ -5283,7 +5235,6 @@ msgid "You can only select providers that match the type of the outpost."
|
|||
msgstr "You can only select providers that match the type of the outpost."
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "You're currently impersonating {0}. Click to stop."
|
||||
msgstr "You're currently impersonating {0}. Click to stop."
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ msgid "8 digits, not compatible with apps like Google Authenticator"
|
|||
msgstr ""
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "A newer version of the frontend is available."
|
||||
msgstr ""
|
||||
|
||||
|
@ -172,6 +171,10 @@ msgstr ""
|
|||
#~ msgid "Admin"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Admin interface"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#: src/pages/providers/proxy/ProxyProviderForm.ts
|
||||
#: src/pages/providers/saml/SAMLProviderForm.ts
|
||||
|
@ -284,10 +287,8 @@ msgid "Application(s)"
|
|||
msgstr ""
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#: src/pages/LibraryPage.ts
|
||||
#: src/pages/applications/ApplicationListPage.ts
|
||||
#: src/pages/outposts/OutpostForm.ts
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "Applications"
|
||||
msgstr ""
|
||||
|
||||
|
@ -382,8 +383,7 @@ msgid "Authentication flow"
|
|||
msgstr ""
|
||||
|
||||
#: src/flows/stages/authenticator_validate/AuthenticatorValidateStage.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Authenticator"
|
||||
msgstr ""
|
||||
|
||||
|
@ -419,6 +419,10 @@ msgstr ""
|
|||
msgid "Authorized application:"
|
||||
msgstr ""
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Avatar image"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
msgid "Backends"
|
||||
msgstr ""
|
||||
|
@ -604,8 +608,7 @@ msgstr ""
|
|||
msgid "Certificates"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsPassword.ts
|
||||
#: src/user/user-settings/settings/UserSettingsPassword.ts
|
||||
#: src/user/user-settings/stages/UserSettingsPassword.ts
|
||||
msgid "Change password"
|
||||
msgstr ""
|
||||
|
||||
|
@ -613,8 +616,7 @@ msgstr ""
|
|||
msgid "Change status"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsPassword.ts
|
||||
#: src/user/user-settings/settings/UserSettingsPassword.ts
|
||||
#: src/user/user-settings/stages/UserSettingsPassword.ts
|
||||
msgid "Change your password"
|
||||
msgstr ""
|
||||
|
||||
|
@ -790,8 +792,7 @@ msgstr ""
|
|||
msgid "Configuration stage"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Configure WebAuthn"
|
||||
msgstr ""
|
||||
|
||||
|
@ -823,10 +824,10 @@ msgstr ""
|
|||
msgid "Configure how the issuer field of the ID Token should be filled."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Configure settings relevant to your user profile."
|
||||
msgstr ""
|
||||
#:
|
||||
#:
|
||||
#~ msgid "Configure settings relevant to your user profile."
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/pages/providers/saml/SAMLProviderForm.ts
|
||||
msgid "Configure the maximum allowed time drift for an asseration."
|
||||
|
@ -840,15 +841,16 @@ msgstr ""
|
|||
msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
msgid "Connect"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/pages/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Connected services"
|
||||
msgstr ""
|
||||
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsPlex.ts
|
||||
msgid "Connected."
|
||||
msgstr ""
|
||||
|
||||
|
@ -934,7 +936,6 @@ msgstr ""
|
|||
msgid "Copy"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Copy Key"
|
||||
msgstr ""
|
||||
|
@ -992,8 +993,6 @@ msgstr ""
|
|||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
|
@ -1002,8 +1001,6 @@ msgstr ""
|
|||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Create App password"
|
||||
|
@ -1081,8 +1078,6 @@ msgid "Create Tenant"
|
|||
msgstr ""
|
||||
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Create Token"
|
||||
|
@ -1120,8 +1115,7 @@ msgstr ""
|
|||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Created {0}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1204,10 +1198,8 @@ msgstr ""
|
|||
#: src/pages/stages/prompt/PromptListPage.ts
|
||||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
@ -1233,7 +1225,6 @@ msgstr ""
|
|||
#~ msgid "Delete Session"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
msgid "Delete account"
|
||||
msgstr ""
|
||||
|
@ -1269,7 +1260,6 @@ msgstr ""
|
|||
#: src/pages/property-mappings/PropertyMappingScopeForm.ts
|
||||
#: src/pages/system-tasks/SystemTaskListPage.ts
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/user/user-settings/tokens/UserTokenForm.ts
|
||||
msgid "Description"
|
||||
msgstr ""
|
||||
|
@ -1311,8 +1301,7 @@ msgstr ""
|
|||
msgid "Device classes which can be used to authenticate."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Device name"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1330,18 +1319,15 @@ msgstr ""
|
|||
#~ msgid "Disable"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
msgid "Disable Duo authenticator"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
msgid "Disable Static Tokens"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Disable Time-based OTP"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1349,10 +1335,8 @@ msgstr ""
|
|||
msgid "Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/pages/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsPlex.ts
|
||||
msgid "Disconnect"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1387,8 +1371,7 @@ msgstr ""
|
|||
msgid "Dummy stage used for testing. Shows a simple continue button and always passes."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
msgid "Duo"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1447,7 +1430,6 @@ msgstr ""
|
|||
msgid "Edit User"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/LibraryPage.ts
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "Either no applications are defined, or you don't have access to any."
|
||||
msgstr ""
|
||||
|
@ -1455,7 +1437,6 @@ msgstr ""
|
|||
#: src/flows/stages/identification/IdentificationStage.ts
|
||||
#: src/pages/events/TransportForm.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
#: src/pages/users/UserViewPage.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
|
@ -1495,8 +1476,7 @@ msgstr ""
|
|||
#~ msgid "Enable"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
msgid "Enable Duo authenticator"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1504,13 +1484,11 @@ msgstr ""
|
|||
msgid "Enable StartTLS"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
msgid "Enable Static Tokens"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Enable TOTP"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1562,13 +1540,11 @@ msgstr ""
|
|||
msgid "Error when validating assertion on server: {err}"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/SourceSettings.ts
|
||||
msgid "Error: unsupported source settings: {0}"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/StageSettings.ts
|
||||
msgid "Error: unsupported stage settings: {0}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1652,8 +1628,6 @@ msgstr ""
|
|||
msgid "Expires?"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Expiring"
|
||||
|
@ -1918,9 +1892,9 @@ msgstr ""
|
|||
msgid "Generate Certificate-Key Pair"
|
||||
msgstr ""
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Go to admin interface"
|
||||
msgstr ""
|
||||
#:
|
||||
#~ msgid "Go to admin interface"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/elements/table/TablePagination.ts
|
||||
msgid "Go to next page"
|
||||
|
@ -1930,9 +1904,9 @@ msgstr ""
|
|||
msgid "Go to previous page"
|
||||
msgstr ""
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
msgid "Go to user interface"
|
||||
msgstr ""
|
||||
#:
|
||||
#~ msgid "Go to user interface"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/pages/events/RuleForm.ts
|
||||
#: src/pages/policies/PolicyBindingForm.ts
|
||||
|
@ -2069,8 +2043,6 @@ msgstr ""
|
|||
#: src/pages/system-tasks/SystemTaskListPage.ts
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Identifier"
|
||||
|
@ -2177,7 +2149,6 @@ msgstr ""
|
|||
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Intent"
|
||||
msgstr ""
|
||||
|
@ -2319,9 +2290,9 @@ msgstr ""
|
|||
msgid "Let the user identify themselves with their username or Email address."
|
||||
msgstr ""
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Library"
|
||||
msgstr ""
|
||||
#:
|
||||
#~ msgid "Library"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||
#: src/pages/sources/plex/PlexSourceForm.ts
|
||||
|
@ -2366,7 +2337,8 @@ msgstr ""
|
|||
#: src/flows/stages/prompt/PromptStage.ts
|
||||
#: src/pages/applications/ApplicationViewPage.ts
|
||||
#: src/pages/applications/ApplicationViewPage.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/user/user-settings/SourceSettings.ts
|
||||
#: src/user/user-settings/StageSettings.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
#: src/utils.ts
|
||||
msgid "Loading"
|
||||
|
@ -2591,11 +2563,14 @@ msgstr ""
|
|||
#~ msgid "Monitor"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/pages/LibraryPage.ts
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "My Applications"
|
||||
msgstr ""
|
||||
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "My applications"
|
||||
msgstr ""
|
||||
|
||||
#: src/elements/forms/DeleteBulkForm.ts
|
||||
#: src/pages/applications/ApplicationForm.ts
|
||||
#: src/pages/applications/ApplicationListPage.ts
|
||||
|
@ -2669,7 +2644,6 @@ msgstr ""
|
|||
#: src/pages/stages/user_login/UserLoginStageForm.ts
|
||||
#: src/pages/stages/user_logout/UserLogoutStageForm.ts
|
||||
#: src/pages/stages/user_write/UserWriteStageForm.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/GroupSelectModal.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
|
@ -2721,14 +2695,12 @@ msgstr ""
|
|||
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/GroupSelectModal.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "No"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/LibraryPage.ts
|
||||
#: src/user/LibraryPage.ts
|
||||
msgid "No Applications available."
|
||||
msgstr ""
|
||||
|
@ -2795,10 +2767,8 @@ msgstr ""
|
|||
msgid "Not configured action"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/pages/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsPlex.ts
|
||||
msgid "Not connected."
|
||||
msgstr ""
|
||||
|
||||
|
@ -3063,6 +3033,10 @@ msgstr ""
|
|||
msgid "Password stage"
|
||||
msgstr ""
|
||||
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Password, 2FA, etc"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/stages/prompt/PromptForm.ts
|
||||
msgid "Password: Masked input, password is validated against sources. Policies still have to be applied to this Stage. If two of these are used in the same stage, they are ensured to be identical."
|
||||
msgstr ""
|
||||
|
@ -3463,7 +3437,6 @@ msgstr ""
|
|||
msgid "Required."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/ServiceAccountForm.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
|
@ -3841,10 +3814,8 @@ msgstr ""
|
|||
msgid "Source linked"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/pages/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/settings/SourceSettingsPlex.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsOAuth.ts
|
||||
#: src/user/user-settings/sources/SourceSettingsPlex.ts
|
||||
msgid "Source {0}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3954,8 +3925,7 @@ msgstr ""
|
|||
msgid "Static Tokens"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
msgid "Static tokens"
|
||||
msgstr ""
|
||||
|
||||
|
@ -3971,21 +3941,15 @@ msgstr ""
|
|||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Status: Disabled"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Status: Enabled"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4126,7 +4090,6 @@ msgid "Successfully created tenant."
|
|||
msgstr ""
|
||||
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/user/user-settings/tokens/UserTokenForm.ts
|
||||
msgid "Successfully created token."
|
||||
msgstr ""
|
||||
|
@ -4185,13 +4148,11 @@ msgstr ""
|
|||
msgid "Successfully updated certificate-key pair."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
msgid "Successfully updated details."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "Successfully updated device."
|
||||
msgstr ""
|
||||
|
||||
|
@ -4286,7 +4247,6 @@ msgid "Successfully updated tenant."
|
|||
msgstr ""
|
||||
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenForm.ts
|
||||
#: src/user/user-settings/tokens/UserTokenForm.ts
|
||||
msgid "Successfully updated token."
|
||||
msgstr ""
|
||||
|
@ -4523,8 +4483,7 @@ msgstr ""
|
|||
msgid "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. (Format: hours=1;minutes=2;seconds=3)."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts
|
||||
msgid "Time-based One-Time Passwords"
|
||||
msgstr ""
|
||||
|
||||
|
@ -4571,7 +4530,6 @@ msgid "Token validity"
|
|||
msgstr ""
|
||||
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Token(s)"
|
||||
msgstr ""
|
||||
|
@ -4585,7 +4543,6 @@ msgstr ""
|
|||
msgid "Tokens & App passwords"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Tokens and App passwords"
|
||||
msgstr ""
|
||||
|
@ -4707,6 +4664,10 @@ msgstr ""
|
|||
#~ msgid "Unmanaged"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "Unread notifications"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/admin-overview/charts/LDAPSyncStatusChart.ts
|
||||
msgid "Unsynced sources"
|
||||
msgstr ""
|
||||
|
@ -4746,18 +4707,13 @@ msgstr ""
|
|||
#: src/pages/stages/prompt/PromptListPage.ts
|
||||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/UserActiveForm.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/pages/users/UserViewPage.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Update"
|
||||
msgstr ""
|
||||
|
@ -4841,7 +4797,6 @@ msgid "Update Tenant"
|
|||
msgstr ""
|
||||
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "Update Token"
|
||||
msgstr ""
|
||||
|
@ -4856,7 +4811,6 @@ msgstr ""
|
|||
msgid "Update available"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "Update details"
|
||||
msgstr ""
|
||||
|
@ -4934,7 +4888,6 @@ msgstr ""
|
|||
#: src/pages/property-mappings/PropertyMappingTestForm.ts
|
||||
#: src/pages/tokens/TokenForm.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
msgid "User"
|
||||
|
@ -4953,10 +4906,10 @@ msgstr ""
|
|||
msgid "User Reputation"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "User Settings"
|
||||
msgstr ""
|
||||
#:
|
||||
#:
|
||||
#~ msgid "User Settings"
|
||||
#~ msgstr ""
|
||||
|
||||
#: src/pages/stages/password/PasswordStageForm.ts
|
||||
msgid "User database + LDAP password"
|
||||
|
@ -4970,7 +4923,6 @@ msgstr ""
|
|||
msgid "User database + standard password"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSettingsPage.ts
|
||||
#: src/user/user-settings/UserSettingsPage.ts
|
||||
msgid "User details"
|
||||
msgstr ""
|
||||
|
@ -4983,6 +4935,10 @@ msgstr ""
|
|||
msgid "User fields"
|
||||
msgstr ""
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
msgid "User interface"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/sources/oauth/OAuthSourceForm.ts
|
||||
#: src/pages/sources/plex/PlexSourceForm.ts
|
||||
msgid "User matching mode"
|
||||
|
@ -5013,7 +4969,6 @@ msgstr ""
|
|||
msgid "User's avatar"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
#: src/user/user-settings/UserSelfForm.ts
|
||||
msgid "User's display name."
|
||||
|
@ -5038,7 +4993,6 @@ msgstr ""
|
|||
#: src/flows/stages/identification/IdentificationStage.ts
|
||||
#: src/pages/policies/reputation/UserReputationListPage.ts
|
||||
#: src/pages/stages/identification/IdentificationStageForm.ts
|
||||
#: src/pages/user-settings/UserSelfForm.ts
|
||||
#: src/pages/users/ServiceAccountForm.ts
|
||||
#: src/pages/users/ServiceAccountForm.ts
|
||||
#: src/pages/users/UserForm.ts
|
||||
|
@ -5162,8 +5116,7 @@ msgstr ""
|
|||
msgid "WebAuthn Authenticators"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts
|
||||
#: src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts
|
||||
msgid "WebAuthn Devices"
|
||||
msgstr ""
|
||||
|
||||
|
@ -5254,7 +5207,6 @@ msgstr ""
|
|||
#: src/pages/providers/proxy/ProxyProviderViewPage.ts
|
||||
#: src/pages/tenants/TenantListPage.ts
|
||||
#: src/pages/tokens/TokenListPage.ts
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts
|
||||
#: src/pages/users/GroupSelectModal.ts
|
||||
#: src/pages/users/UserListPage.ts
|
||||
#: src/user/user-settings/tokens/UserTokenList.ts
|
||||
|
@ -5266,7 +5218,6 @@ msgid "You can only select providers that match the type of the outpost."
|
|||
msgstr ""
|
||||
|
||||
#: src/interfaces/AdminInterface.ts
|
||||
#: src/interfaces/UserInterface.ts
|
||||
msgid "You're currently impersonating {0}. Click to stop."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -1,170 +0,0 @@
|
|||
import { t } from "@lingui/macro";
|
||||
import {
|
||||
css,
|
||||
CSSResult,
|
||||
customElement,
|
||||
html,
|
||||
LitElement,
|
||||
property,
|
||||
TemplateResult,
|
||||
} from "lit-element";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { Application, CoreApi } from "@goauthentik/api";
|
||||
import { AKResponse } from "../api/Client";
|
||||
import { DEFAULT_CONFIG } from "../api/Config";
|
||||
import { me } from "../api/Users";
|
||||
import { loading, truncate } from "../utils";
|
||||
import "../elements/PageHeader";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
||||
import PFEmptyState from "@patternfly/patternfly/components/EmptyState/empty-state.css";
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
import AKGlobal from "../authentik.css";
|
||||
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
|
||||
import PFGallery from "@patternfly/patternfly/layouts/Gallery/gallery.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
|
||||
@customElement("ak-library-app")
|
||||
export class LibraryApplication extends LitElement {
|
||||
@property({ attribute: false })
|
||||
application?: Application;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
PFBase,
|
||||
PFCard,
|
||||
PFButton,
|
||||
PFAvatar,
|
||||
AKGlobal,
|
||||
css`
|
||||
.pf-c-card {
|
||||
height: 100%;
|
||||
}
|
||||
i.pf-icon {
|
||||
height: 36px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
.pf-c-avatar {
|
||||
--pf-c-avatar--BorderRadius: 0;
|
||||
}
|
||||
.pf-c-card__header {
|
||||
min-height: 60px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.pf-c-card__header a {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
if (!this.application) {
|
||||
return html`<ak-spinner></ak-spinner>`;
|
||||
}
|
||||
return html` <div class="pf-c-card pf-m-hoverable pf-m-compact">
|
||||
<div class="pf-c-card__header">
|
||||
${this.application.metaIcon
|
||||
? html`<a href="${ifDefined(this.application.launchUrl ?? "")}"
|
||||
><img
|
||||
class="app-icon pf-c-avatar"
|
||||
src="${ifDefined(this.application.metaIcon)}"
|
||||
alt="Application Icon"
|
||||
/></a>`
|
||||
: html`<i class="fas fas fa-share-square"></i>`}
|
||||
${until(
|
||||
me().then((u) => {
|
||||
if (!u.user.isSuperuser) return html``;
|
||||
return html`
|
||||
<a
|
||||
class="pf-c-button pf-m-control pf-m-small"
|
||||
href="#/core/applications/${this.application?.slug}"
|
||||
>
|
||||
<i class="fas fa-pencil-alt"></i>
|
||||
</a>
|
||||
`;
|
||||
}),
|
||||
)}
|
||||
</div>
|
||||
<div class="pf-c-card__title">
|
||||
<p id="card-1-check-label">
|
||||
<a href="${ifDefined(this.application.launchUrl ?? "")}"
|
||||
>${this.application.name}</a
|
||||
>
|
||||
</p>
|
||||
<div class="pf-c-content">
|
||||
<small>${this.application.metaPublisher}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pf-c-card__body">${truncate(this.application.metaDescription, 35)}</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement("ak-library")
|
||||
export class LibraryPage extends LitElement {
|
||||
@property({ attribute: false })
|
||||
apps?: AKResponse<Application>;
|
||||
|
||||
pageTitle(): string {
|
||||
return t`My Applications`;
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [PFBase, PFEmptyState, PFTitle, PFPage, PFContent, PFGallery, AKGlobal].concat(css`
|
||||
:host,
|
||||
main {
|
||||
height: 100%;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
firstUpdated(): void {
|
||||
new CoreApi(DEFAULT_CONFIG).coreApplicationsList({}).then((apps) => {
|
||||
this.apps = apps;
|
||||
});
|
||||
}
|
||||
|
||||
renderEmptyState(): TemplateResult {
|
||||
return html` <div class="pf-c-empty-state pf-m-full-height">
|
||||
<div class="pf-c-empty-state__content">
|
||||
<i class="fas fa-cubes pf-c-empty-state__icon" aria-hidden="true"></i>
|
||||
<h1 class="pf-c-title pf-m-lg">${t`No Applications available.`}</h1>
|
||||
<div class="pf-c-empty-state__body">
|
||||
${t`Either no applications are defined, or you don't have access to any.`}
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderApps(): TemplateResult {
|
||||
return html`<div class="pf-l-gallery pf-m-gutter">
|
||||
${this.apps?.results.map(
|
||||
(app) => html`<ak-library-app .application=${app}></ak-library-app>`,
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<main role="main" class="pf-c-page__main" tabindex="-1" id="main-content">
|
||||
<ak-page-header icon="pf-icon pf-icon-applications" header=${t`Applications`}>
|
||||
</ak-page-header>
|
||||
<section class="pf-c-page__main-section">
|
||||
${loading(
|
||||
this.apps,
|
||||
html`${(this.apps?.results.length || 0) > 0
|
||||
? this.renderApps()
|
||||
: this.renderEmptyState()}`,
|
||||
)}
|
||||
</section>
|
||||
</main>`;
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
import { t } from "@lingui/macro";
|
||||
import { customElement, html, TemplateResult } from "lit-element";
|
||||
import { CoreApi, UserSelf } from "@goauthentik/api";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import { DEFAULT_CONFIG, tenant } from "../../api/Config";
|
||||
import "../../elements/forms/FormElement";
|
||||
import "../../elements/EmptyState";
|
||||
import "../../elements/forms/Form";
|
||||
import "../../elements/forms/HorizontalFormElement";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { ModelForm } from "../../elements/forms/ModelForm";
|
||||
|
||||
@customElement("ak-user-self-form")
|
||||
export class UserSelfForm extends ModelForm<UserSelf, number> {
|
||||
viewportCheck = false;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
loadInstance(pk: number): Promise<UserSelf> {
|
||||
return new CoreApi(DEFAULT_CONFIG).coreUsersMeRetrieve().then((su) => {
|
||||
return su.user;
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
return t`Successfully updated details.`;
|
||||
}
|
||||
|
||||
send = (data: UserSelf): Promise<UserSelf> => {
|
||||
return new CoreApi(DEFAULT_CONFIG)
|
||||
.coreUsersUpdateSelfUpdate({
|
||||
userSelfRequest: data,
|
||||
})
|
||||
.then((su) => {
|
||||
return su.user;
|
||||
});
|
||||
};
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
if (!this.instance) {
|
||||
return html`<ak-empty-state ?loading="${true}" header=${t`Loading`}> </ak-empty-state>`;
|
||||
}
|
||||
return html`<form class="pf-c-form pf-m-horizontal">
|
||||
<ak-form-element-horizontal label=${t`Username`} ?required=${true} name="username">
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.username)}"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${t`Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.`}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${t`Name`} ?required=${true} name="name">
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.name)}"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
<p class="pf-c-form__helper-text">${t`User's display name.`}</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${t`Email`} name="email">
|
||||
<input
|
||||
type="email"
|
||||
value="${ifDefined(this.instance?.email)}"
|
||||
class="pf-c-form-control"
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
|
||||
<div class="pf-c-form__group pf-m-action">
|
||||
<div class="pf-c-form__horizontal-group">
|
||||
<div class="pf-c-form__actions">
|
||||
<button
|
||||
@click=${(ev: Event) => {
|
||||
return this.submit(ev);
|
||||
}}
|
||||
class="pf-c-button pf-m-primary"
|
||||
>
|
||||
${t`Update`}
|
||||
</button>
|
||||
${until(
|
||||
tenant().then((tenant) => {
|
||||
if (tenant.flowUnenrollment) {
|
||||
return html`<a
|
||||
class="pf-c-button pf-m-danger"
|
||||
href="/if/flow/${tenant.flowUnenrollment}"
|
||||
>
|
||||
${t`Delete account`}
|
||||
</a>`;
|
||||
}
|
||||
return html``;
|
||||
}),
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>`;
|
||||
}
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
import { t } from "@lingui/macro";
|
||||
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
|
||||
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
import PFGallery from "@patternfly/patternfly/layouts/Gallery/gallery.css";
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
|
||||
import PFSizing from "@patternfly/patternfly/utilities/Sizing/sizing.css";
|
||||
import PFFlex from "@patternfly/patternfly/utilities/Flex/flex.css";
|
||||
import PFDisplay from "@patternfly/patternfly/utilities/Display/display.css";
|
||||
import AKGlobal from "../../authentik.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||
import { SourcesApi, StagesApi, UserSetting } from "@goauthentik/api";
|
||||
import { DEFAULT_CONFIG } from "../../api/Config";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import "../../elements/Tabs";
|
||||
import "../../elements/PageHeader";
|
||||
import "./tokens/UserTokenList";
|
||||
import "./UserSelfForm";
|
||||
import "./settings/UserSettingsAuthenticatorDuo";
|
||||
import "./settings/UserSettingsAuthenticatorStatic";
|
||||
import "./settings/UserSettingsAuthenticatorTOTP";
|
||||
import "./settings/UserSettingsAuthenticatorWebAuthn";
|
||||
import "./settings/UserSettingsPassword";
|
||||
import "./settings/SourceSettingsOAuth";
|
||||
import "./settings/SourceSettingsPlex";
|
||||
import { EVENT_REFRESH } from "../../constants";
|
||||
|
||||
@customElement("ak-user-settings")
|
||||
export class UserSettingsPage extends LitElement {
|
||||
static get styles(): CSSResult[] {
|
||||
return [
|
||||
PFBase,
|
||||
PFPage,
|
||||
PFFlex,
|
||||
PFDisplay,
|
||||
PFGallery,
|
||||
PFContent,
|
||||
PFCard,
|
||||
PFDescriptionList,
|
||||
PFSizing,
|
||||
PFForm,
|
||||
PFFormControl,
|
||||
AKGlobal,
|
||||
];
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
userSettings?: Promise<UserSetting[]>;
|
||||
|
||||
@property({ attribute: false })
|
||||
sourceSettings?: Promise<UserSetting[]>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener(EVENT_REFRESH, () => {
|
||||
this.firstUpdated();
|
||||
});
|
||||
}
|
||||
|
||||
firstUpdated(): void {
|
||||
this.userSettings = new StagesApi(DEFAULT_CONFIG).stagesAllUserSettingsList();
|
||||
this.sourceSettings = new SourcesApi(DEFAULT_CONFIG).sourcesAllUserSettingsList();
|
||||
}
|
||||
|
||||
renderStageSettings(stage: UserSetting): TemplateResult {
|
||||
switch (stage.component) {
|
||||
case "ak-user-settings-authenticator-webauthn":
|
||||
return html`<ak-user-settings-authenticator-webauthn
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-webauthn>`;
|
||||
case "ak-user-settings-password":
|
||||
return html`<ak-user-settings-password
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-password>`;
|
||||
case "ak-user-settings-authenticator-totp":
|
||||
return html`<ak-user-settings-authenticator-totp
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-totp>`;
|
||||
case "ak-user-settings-authenticator-static":
|
||||
return html`<ak-user-settings-authenticator-static
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-static>`;
|
||||
case "ak-user-settings-authenticator-duo":
|
||||
return html`<ak-user-settings-authenticator-duo
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-duo>`;
|
||||
default:
|
||||
return html`<p>${t`Error: unsupported stage settings: ${stage.component}`}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
renderSourceSettings(source: UserSetting): TemplateResult {
|
||||
switch (source.component) {
|
||||
case "ak-user-settings-source-oauth":
|
||||
return html`<ak-user-settings-source-oauth
|
||||
objectId=${source.objectUid}
|
||||
title=${source.title}
|
||||
.configureUrl=${source.configureUrl}
|
||||
>
|
||||
</ak-user-settings-source-oauth>`;
|
||||
case "ak-user-settings-source-plex":
|
||||
return html`<ak-user-settings-source-plex
|
||||
objectId=${source.objectUid}
|
||||
title=${source.title}
|
||||
>
|
||||
</ak-user-settings-source-plex>`;
|
||||
default:
|
||||
return html`<p>${t`Error: unsupported source settings: ${source.component}`}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-page">
|
||||
<main role="main" class="pf-c-page__main" tabindex="-1">
|
||||
<ak-page-header
|
||||
icon="pf-icon pf-icon-user"
|
||||
header=${t`User Settings`}
|
||||
description=${t`Configure settings relevant to your user profile.`}
|
||||
>
|
||||
</ak-page-header>
|
||||
<ak-tabs ?vertical="${true}" style="height: 100%;">
|
||||
<section
|
||||
slot="page-details"
|
||||
data-tab-title="${t`User details`}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${t`Update details`}</div>
|
||||
<div class="pf-c-card__body">
|
||||
<ak-user-self-form .instancePk=${1}></ak-user-self-form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section
|
||||
slot="page-tokens"
|
||||
data-tab-title="${t`Tokens and App passwords`}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
<ak-user-token-list></ak-user-token-list>
|
||||
</section>
|
||||
${until(
|
||||
this.userSettings?.then((stages) => {
|
||||
return stages.map((stage) => {
|
||||
return html`<section
|
||||
slot="page-${stage.objectUid}"
|
||||
data-tab-title="${ifDefined(stage.title)}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
${this.renderStageSettings(stage)}
|
||||
</section>`;
|
||||
});
|
||||
}),
|
||||
)}
|
||||
${until(
|
||||
this.sourceSettings?.then((source) => {
|
||||
return source.map((stage) => {
|
||||
return html`<section
|
||||
slot="page-${stage.objectUid}"
|
||||
data-tab-title="${ifDefined(stage.title)}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
${this.renderSourceSettings(stage)}
|
||||
</section>`;
|
||||
});
|
||||
}),
|
||||
)}
|
||||
</ak-tabs>
|
||||
</main>
|
||||
</div>`;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
import { CSSResult, LitElement, property } from "lit-element";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import AKGlobal from "../../../authentik.css";
|
||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||
|
||||
export abstract class BaseUserSettings extends LitElement {
|
||||
@property()
|
||||
objectId!: string;
|
||||
|
||||
@property()
|
||||
configureUrl?: string;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [PFBase, PFCard, PFButton, PFForm, PFFormControl, AKGlobal];
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
import { AuthenticatorsApi } from "@goauthentik/api";
|
||||
import { t } from "@lingui/macro";
|
||||
import { CSSResult, customElement, html, TemplateResult } from "lit-element";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { STATIC_TOKEN_STYLE } from "../../../flows/stages/authenticator_static/AuthenticatorStaticStage";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { EVENT_REFRESH } from "../../../constants";
|
||||
|
||||
@customElement("ak-user-settings-authenticator-static")
|
||||
export class UserSettingsAuthenticatorStatic extends BaseUserSettings {
|
||||
static get styles(): CSSResult[] {
|
||||
return super.styles.concat(STATIC_TOKEN_STYLE);
|
||||
}
|
||||
|
||||
renderEnabled(): TemplateResult {
|
||||
return html`<div class="pf-c-card__body">
|
||||
<p>
|
||||
${t`Status: Enabled`}
|
||||
<i class="pf-icon pf-icon-ok"></i>
|
||||
</p>
|
||||
<ul class="ak-otp-tokens">
|
||||
${until(
|
||||
new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsStaticList({})
|
||||
.then((devices) => {
|
||||
if (devices.results.length < 1) {
|
||||
return;
|
||||
}
|
||||
return devices.results[0].tokenSet?.map((token) => {
|
||||
return html`<li>${token.token}</li>`;
|
||||
});
|
||||
}),
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<button
|
||||
class="pf-c-button pf-m-danger"
|
||||
@click=${() => {
|
||||
return new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsStaticList({})
|
||||
.then((devices) => {
|
||||
if (devices.results.length < 1) {
|
||||
return;
|
||||
}
|
||||
// TODO: Handle multiple devices, currently we assume only one TOTP Device
|
||||
return new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsStaticDestroy({
|
||||
id: devices.results[0].pk || 0,
|
||||
})
|
||||
.then(() => {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(EVENT_REFRESH, {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
}}
|
||||
>
|
||||
${t`Disable Static Tokens`}
|
||||
</button>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderDisabled(): TemplateResult {
|
||||
return html` <div class="pf-c-card__body">
|
||||
<p>
|
||||
${t`Status: Disabled`}
|
||||
<i class="pf-icon pf-icon-error-circle-o"></i>
|
||||
</p>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
${this.configureUrl
|
||||
? html`<a
|
||||
href="${this.configureUrl}?next=/%23%2Fuser"
|
||||
class="pf-c-button pf-m-primary"
|
||||
>${t`Enable Static Tokens`}
|
||||
</a>`
|
||||
: html``}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${t`Static tokens`}</div>
|
||||
${until(
|
||||
new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsStaticList({})
|
||||
.then((devices) => {
|
||||
return devices.results.length > 0
|
||||
? this.renderEnabled()
|
||||
: this.renderDisabled();
|
||||
}),
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
import { AuthenticatorsApi } from "@goauthentik/api";
|
||||
import { t } from "@lingui/macro";
|
||||
import { customElement, html, TemplateResult } from "lit-element";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { EVENT_REFRESH } from "../../../constants";
|
||||
|
||||
@customElement("ak-user-settings-authenticator-totp")
|
||||
export class UserSettingsAuthenticatorTOTP extends BaseUserSettings {
|
||||
renderEnabled(): TemplateResult {
|
||||
return html`<div class="pf-c-card__body">
|
||||
<p>
|
||||
${t`Status: Enabled`}
|
||||
<i class="pf-icon pf-icon-ok"></i>
|
||||
</p>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<button
|
||||
class="pf-c-button pf-m-danger"
|
||||
@click=${() => {
|
||||
return new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsTotpList({})
|
||||
.then((devices) => {
|
||||
if (devices.results.length < 1) {
|
||||
return;
|
||||
}
|
||||
// TODO: Handle multiple devices, currently we assume only one TOTP Device
|
||||
return new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsTotpDestroy({
|
||||
id: devices.results[0].pk || 0,
|
||||
})
|
||||
.then(() => {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(EVENT_REFRESH, {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
}}
|
||||
>
|
||||
${t`Disable Time-based OTP`}
|
||||
</button>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderDisabled(): TemplateResult {
|
||||
return html` <div class="pf-c-card__body">
|
||||
<p>
|
||||
${t`Status: Disabled`}
|
||||
<i class="pf-icon pf-icon-error-circle-o"></i>
|
||||
</p>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
${this.configureUrl
|
||||
? html`<a
|
||||
href="${this.configureUrl}?next=/%23%2Fuser"
|
||||
class="pf-c-button pf-m-primary"
|
||||
>${t`Enable TOTP`}
|
||||
</a>`
|
||||
: html``}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${t`Time-based One-Time Passwords`}</div>
|
||||
${until(
|
||||
new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsTotpList({}).then((devices) => {
|
||||
return devices.results.length > 0
|
||||
? this.renderEnabled()
|
||||
: this.renderDisabled();
|
||||
}),
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
}
|
|
@ -1,62 +0,0 @@
|
|||
import { CoreApi, IntentEnum, Token } from "@goauthentik/api";
|
||||
import { t } from "@lingui/macro";
|
||||
import { customElement, property } from "lit-element";
|
||||
import { html, TemplateResult } from "lit-html";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import "../../../elements/forms/HorizontalFormElement";
|
||||
import { ModelForm } from "../../../elements/forms/ModelForm";
|
||||
|
||||
@customElement("ak-user-token-form")
|
||||
export class UserTokenForm extends ModelForm<Token, string> {
|
||||
@property()
|
||||
intent: IntentEnum = IntentEnum.Api;
|
||||
|
||||
loadInstance(pk: string): Promise<Token> {
|
||||
return new CoreApi(DEFAULT_CONFIG).coreTokensRetrieve({
|
||||
identifier: pk,
|
||||
});
|
||||
}
|
||||
|
||||
getSuccessMessage(): string {
|
||||
if (this.instance) {
|
||||
return t`Successfully updated token.`;
|
||||
} else {
|
||||
return t`Successfully created token.`;
|
||||
}
|
||||
}
|
||||
|
||||
send = (data: Token): Promise<Token> => {
|
||||
if (this.instance) {
|
||||
return new CoreApi(DEFAULT_CONFIG).coreTokensUpdate({
|
||||
identifier: this.instance.identifier,
|
||||
tokenRequest: data,
|
||||
});
|
||||
} else {
|
||||
data.intent = this.intent;
|
||||
return new CoreApi(DEFAULT_CONFIG).coreTokensCreate({
|
||||
tokenRequest: data,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
return html`<form class="pf-c-form pf-m-horizontal">
|
||||
<ak-form-element-horizontal label=${t`Identifier`} ?required=${true} name="identifier">
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.identifier)}"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${t`Description`} name="description">
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(this.instance?.description)}"
|
||||
class="pf-c-form-control"
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
</form>`;
|
||||
}
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
import { t } from "@lingui/macro";
|
||||
import { CSSResult, customElement, html, property, TemplateResult } from "lit-element";
|
||||
import { AKResponse } from "../../../api/Client";
|
||||
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
|
||||
|
||||
import "../../../elements/forms/DeleteBulkForm";
|
||||
import "../../../elements/forms/ModalForm";
|
||||
import "../../../elements/buttons/ModalButton";
|
||||
import "../../../elements/buttons/Dropdown";
|
||||
import "../../../elements/buttons/TokenCopyButton";
|
||||
import { Table, TableColumn } from "../../../elements/table/Table";
|
||||
import { PAGE_SIZE } from "../../../constants";
|
||||
import { CoreApi, IntentEnum, Token } from "@goauthentik/api";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import "./UserTokenForm";
|
||||
import { IntentToLabel } from "../../tokens/TokenListPage";
|
||||
|
||||
@customElement("ak-user-token-list")
|
||||
export class UserTokenList extends Table<Token> {
|
||||
searchEnabled(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
expandable = true;
|
||||
checkbox = true;
|
||||
|
||||
@property()
|
||||
order = "expires";
|
||||
|
||||
apiEndpoint(page: number): Promise<AKResponse<Token>> {
|
||||
return new CoreApi(DEFAULT_CONFIG).coreTokensList({
|
||||
ordering: this.order,
|
||||
page: page,
|
||||
pageSize: PAGE_SIZE,
|
||||
search: this.search || "",
|
||||
});
|
||||
}
|
||||
|
||||
columns(): TableColumn[] {
|
||||
return [new TableColumn(t`Identifier`, "identifier"), new TableColumn("")];
|
||||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return super.styles.concat(PFDescriptionList);
|
||||
}
|
||||
|
||||
renderToolbar(): TemplateResult {
|
||||
return html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit"> ${t`Create`} </span>
|
||||
<span slot="header"> ${t`Create Token`} </span>
|
||||
<ak-user-token-form intent=${IntentEnum.Api} slot="form"> </ak-user-token-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
||||
${t`Create Token`}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<ak-forms-modal>
|
||||
<span slot="submit"> ${t`Create`} </span>
|
||||
<span slot="header"> ${t`Create App password`} </span>
|
||||
<ak-user-token-form intent=${IntentEnum.AppPassword} slot="form">
|
||||
</ak-user-token-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-secondary">
|
||||
${t`Create App password`}
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
${super.renderToolbar()}
|
||||
`;
|
||||
}
|
||||
|
||||
renderExpanded(item: Token): TemplateResult {
|
||||
return html` <td role="cell" colspan="3">
|
||||
<div class="pf-c-table__expandable-row-content">
|
||||
<dl class="pf-c-description-list pf-m-horizontal">
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text">${t`User`}</span>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${item.user?.username}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text">${t`Expiring`}</span>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${item.expiring ? t`Yes` : t`No`}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text">${t`Expiring`}</span>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${item.expiring ? item.expires?.toLocaleString() : "-"}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
<div class="pf-c-description-list__group">
|
||||
<dt class="pf-c-description-list__term">
|
||||
<span class="pf-c-description-list__text">${t`Intent`}</span>
|
||||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${IntentToLabel(item.intent || IntentEnum.Api)}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</td>
|
||||
<td></td>`;
|
||||
}
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
const disabled = this.selectedElements.length < 1;
|
||||
return html`<ak-forms-delete-bulk
|
||||
objectLabel=${t`Token(s)`}
|
||||
.objects=${this.selectedElements}
|
||||
.delete=${(item: Token) => {
|
||||
return new CoreApi(DEFAULT_CONFIG).coreTokensDestroy({
|
||||
identifier: item.identifier,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<button ?disabled=${disabled} slot="trigger" class="pf-c-button pf-m-danger">
|
||||
${t`Delete`}
|
||||
</button>
|
||||
</ak-forms-delete-bulk>`;
|
||||
}
|
||||
|
||||
row(item: Token): TemplateResult[] {
|
||||
return [
|
||||
html`${item.identifier}`,
|
||||
html`
|
||||
<ak-forms-modal>
|
||||
<span slot="submit"> ${t`Update`} </span>
|
||||
<span slot="header"> ${t`Update Token`} </span>
|
||||
<ak-user-token-form slot="form" .instancePk=${item.identifier}>
|
||||
</ak-user-token-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-plain">
|
||||
<i class="fas fa-edit"></i>
|
||||
</button>
|
||||
</ak-forms-modal>
|
||||
<ak-token-copy-button identifier="${item.identifier}">
|
||||
${t`Copy Key`}
|
||||
</ak-token-copy-button>
|
||||
`,
|
||||
];
|
||||
}
|
||||
}
|
|
@ -12,7 +12,6 @@ import "./pages/events/TransportListPage";
|
|||
import "./pages/flows/FlowListPage";
|
||||
import "./pages/flows/FlowViewPage";
|
||||
import "./pages/groups/GroupListPage";
|
||||
import "./user/LibraryPage";
|
||||
import "./pages/outposts/OutpostListPage";
|
||||
import "./pages/outposts/ServiceConnectionListPage";
|
||||
import "./pages/policies/PolicyListPage";
|
||||
|
@ -29,7 +28,6 @@ import "./pages/stages/StageListPage";
|
|||
import "./pages/system-tasks/SystemTaskListPage";
|
||||
import "./pages/tenants/TenantListPage";
|
||||
import "./pages/tokens/TokenListPage";
|
||||
import "./pages/user-settings/UserSettingsPage";
|
||||
import "./pages/users/UserListPage";
|
||||
import "./pages/users/UserViewPage";
|
||||
|
||||
|
@ -37,7 +35,7 @@ export const ROUTES: Route[] = [
|
|||
// Prevent infinite Shell loops
|
||||
new Route(new RegExp("^/$")).redirect("/administration/overview"),
|
||||
new Route(new RegExp("^#.*")).redirect("/administration/overview"),
|
||||
new Route(new RegExp("^/library$"), html`<ak-library></ak-library>`),
|
||||
new Route(new RegExp("^/library$")).redirectRaw("/if/user/"),
|
||||
new Route(
|
||||
new RegExp("^/administration/overview$"),
|
||||
html`<ak-admin-overview></ak-admin-overview>`,
|
||||
|
@ -112,5 +110,4 @@ export const ROUTES: Route[] = [
|
|||
new RegExp("^/crypto/certificates$"),
|
||||
html`<ak-crypto-certificate-list></ak-crypto-certificate-list>`,
|
||||
),
|
||||
new Route(new RegExp("^/user$"), html`<ak-user-settings></ak-user-settings>`),
|
||||
];
|
||||
|
|
|
@ -9,5 +9,5 @@ export const ROUTES: Route[] = [
|
|||
new Route(new RegExp("^/$")).redirect("/library"),
|
||||
new Route(new RegExp("^#.*")).redirect("/library"),
|
||||
new Route(new RegExp("^/library$"), html`<ak-library></ak-library>`),
|
||||
new Route(new RegExp("^/user$"), html`<ak-user-settings></ak-user-settings>`),
|
||||
new Route(new RegExp("^/settings$"), html`<ak-user-settings></ak-user-settings>`),
|
||||
];
|
||||
|
|
|
@ -15,17 +15,16 @@ import { AKResponse } from "../api/Client";
|
|||
import { DEFAULT_CONFIG } from "../api/Config";
|
||||
import { me } from "../api/Users";
|
||||
import { loading, truncate } from "../utils";
|
||||
import "../elements/PageHeader";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
import PFTitle from "@patternfly/patternfly/components/Title/title.css";
|
||||
import PFEmptyState from "@patternfly/patternfly/components/EmptyState/empty-state.css";
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
import AKGlobal from "../authentik.css";
|
||||
import PFAvatar from "@patternfly/patternfly/components/Avatar/avatar.css";
|
||||
import PFGallery from "@patternfly/patternfly/layouts/Gallery/gallery.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
import PFEmptyState from "@patternfly/patternfly/components/EmptyState/empty-state.css";
|
||||
import PFGallery from "@patternfly/patternfly/layouts/Gallery/gallery.css";
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import { uiConfig } from "./config";
|
||||
|
||||
@customElement("ak-library-app")
|
||||
export class LibraryApplication extends LitElement {
|
||||
|
@ -81,7 +80,11 @@ export class LibraryApplication extends LitElement {
|
|||
/></a>`
|
||||
: html`<i class="fas fas fa-share-square"></i>`}
|
||||
${until(
|
||||
me().then((u) => {
|
||||
uiConfig().then((config) => {
|
||||
if (!config.enabledFeatures.applicationEdit) {
|
||||
return html``;
|
||||
}
|
||||
return me().then((u) => {
|
||||
if (!u.user.isSuperuser) return html``;
|
||||
return html`
|
||||
<a
|
||||
|
@ -91,6 +94,7 @@ export class LibraryApplication extends LitElement {
|
|||
<i class="fas fa-pencil-alt"></i>
|
||||
</a>
|
||||
`;
|
||||
});
|
||||
}),
|
||||
)}
|
||||
</div>
|
||||
|
@ -119,10 +123,11 @@ export class LibraryPage extends LitElement {
|
|||
}
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [PFBase, PFEmptyState, PFTitle, PFPage, PFContent, PFGallery, AKGlobal].concat(css`
|
||||
return [PFBase, PFEmptyState, PFPage, PFContent, PFGallery, AKGlobal].concat(css`
|
||||
:host,
|
||||
main {
|
||||
height: 100%;
|
||||
padding: 3% 5%;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
@ -147,16 +152,17 @@ export class LibraryPage extends LitElement {
|
|||
|
||||
renderApps(): TemplateResult {
|
||||
return html`<div class="pf-l-gallery pf-m-gutter">
|
||||
${this.apps?.results.map(
|
||||
(app) => html`<ak-library-app .application=${app}></ak-library-app>`,
|
||||
)}
|
||||
${this.apps?.results
|
||||
.filter((app) => app.launchUrl)
|
||||
.map((app) => html`<ak-library-app .application=${app}></ak-library-app>`)}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<main role="main" class="pf-c-page__main" tabindex="-1" id="main-content">
|
||||
<ak-page-header icon="pf-icon pf-icon-applications" header=${t`Applications`}>
|
||||
</ak-page-header>
|
||||
<div class="pf-c-content">
|
||||
<h1>${t`My applications`}</h1>
|
||||
</div>
|
||||
<section class="pf-c-page__main-section">
|
||||
${loading(
|
||||
this.apps,
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
export interface UIConfig {
|
||||
enabledFeatures: {
|
||||
// API Request drawer in navbar
|
||||
apiDrawer: boolean;
|
||||
// Notification drawer in navbar
|
||||
notificationDrawer: boolean;
|
||||
// Settings in user dropdown
|
||||
settings: boolean;
|
||||
// Application edit in library (only shown when user is superuser)
|
||||
applicationEdit: boolean;
|
||||
};
|
||||
navbar: {
|
||||
userDisplay: "username" | "name" | "email";
|
||||
};
|
||||
}
|
||||
|
||||
export const DefaultUIConfig: UIConfig = {
|
||||
enabledFeatures: {
|
||||
apiDrawer: true,
|
||||
notificationDrawer: true,
|
||||
settings: true,
|
||||
applicationEdit: true,
|
||||
},
|
||||
navbar: {
|
||||
userDisplay: "name",
|
||||
},
|
||||
};
|
||||
|
||||
export function uiConfig(): Promise<UIConfig> {
|
||||
return Promise.resolve(DefaultUIConfig);
|
||||
}
|
|
@ -2,7 +2,7 @@ import { CSSResult, LitElement, property } from "lit-element";
|
|||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import PFCard from "@patternfly/patternfly/components/Card/card.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import AKGlobal from "../../../authentik.css";
|
||||
import AKGlobal from "../../authentik.css";
|
||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||
|
|
@ -77,7 +77,7 @@ export class UserSelfForm extends ModelForm<UserSelf, number> {
|
|||
}}
|
||||
class="pf-c-button pf-m-primary"
|
||||
>
|
||||
${t`Update`}
|
||||
${t`Save`}
|
||||
</button>
|
||||
${until(
|
||||
tenant().then((tenant) => {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { t } from "@lingui/macro";
|
||||
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
|
||||
import { CSSResult, customElement, html, LitElement, TemplateResult } from "lit-element";
|
||||
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
|
@ -13,22 +13,15 @@ import AKGlobal from "../../authentik.css";
|
|||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||
import PFFormControl from "@patternfly/patternfly/components/FormControl/form-control.css";
|
||||
import { SourcesApi, StagesApi, UserSetting } from "@goauthentik/api";
|
||||
import { DEFAULT_CONFIG } from "../../api/Config";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import "../../elements/Tabs";
|
||||
import "../../elements/PageHeader";
|
||||
import "../../elements/user/SessionList";
|
||||
import "../../elements/user/UserConsentList";
|
||||
import "./tokens/UserTokenList";
|
||||
import "./UserSelfForm";
|
||||
import "./settings/UserSettingsAuthenticatorDuo";
|
||||
import "./settings/UserSettingsAuthenticatorStatic";
|
||||
import "./settings/UserSettingsAuthenticatorTOTP";
|
||||
import "./settings/UserSettingsAuthenticatorWebAuthn";
|
||||
import "./settings/UserSettingsPassword";
|
||||
import "./settings/SourceSettingsOAuth";
|
||||
import "./settings/SourceSettingsPlex";
|
||||
import { EVENT_REFRESH } from "../../constants";
|
||||
import "./sources/SourceSettings";
|
||||
import "./stages/StageSettings";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { me } from "../../api/Users";
|
||||
|
||||
@customElement("ak-user-settings")
|
||||
export class UserSettingsPage extends LitElement {
|
||||
|
@ -49,91 +42,10 @@ export class UserSettingsPage extends LitElement {
|
|||
];
|
||||
}
|
||||
|
||||
@property({ attribute: false })
|
||||
userSettings?: Promise<UserSetting[]>;
|
||||
|
||||
@property({ attribute: false })
|
||||
sourceSettings?: Promise<UserSetting[]>;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener(EVENT_REFRESH, () => {
|
||||
this.firstUpdated();
|
||||
});
|
||||
}
|
||||
|
||||
firstUpdated(): void {
|
||||
this.userSettings = new StagesApi(DEFAULT_CONFIG).stagesAllUserSettingsList();
|
||||
this.sourceSettings = new SourcesApi(DEFAULT_CONFIG).sourcesAllUserSettingsList();
|
||||
}
|
||||
|
||||
renderStageSettings(stage: UserSetting): TemplateResult {
|
||||
switch (stage.component) {
|
||||
case "ak-user-settings-authenticator-webauthn":
|
||||
return html`<ak-user-settings-authenticator-webauthn
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-webauthn>`;
|
||||
case "ak-user-settings-password":
|
||||
return html`<ak-user-settings-password
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-password>`;
|
||||
case "ak-user-settings-authenticator-totp":
|
||||
return html`<ak-user-settings-authenticator-totp
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-totp>`;
|
||||
case "ak-user-settings-authenticator-static":
|
||||
return html`<ak-user-settings-authenticator-static
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-static>`;
|
||||
case "ak-user-settings-authenticator-duo":
|
||||
return html`<ak-user-settings-authenticator-duo
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-duo>`;
|
||||
default:
|
||||
return html`<p>${t`Error: unsupported stage settings: ${stage.component}`}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
renderSourceSettings(source: UserSetting): TemplateResult {
|
||||
switch (source.component) {
|
||||
case "ak-user-settings-source-oauth":
|
||||
return html`<ak-user-settings-source-oauth
|
||||
objectId=${source.objectUid}
|
||||
title=${source.title}
|
||||
.configureUrl=${source.configureUrl}
|
||||
>
|
||||
</ak-user-settings-source-oauth>`;
|
||||
case "ak-user-settings-source-plex":
|
||||
return html`<ak-user-settings-source-plex
|
||||
objectId=${source.objectUid}
|
||||
title=${source.title}
|
||||
>
|
||||
</ak-user-settings-source-plex>`;
|
||||
default:
|
||||
return html`<p>${t`Error: unsupported source settings: ${source.component}`}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-page">
|
||||
<main role="main" class="pf-c-page__main" tabindex="-1">
|
||||
<ak-page-header
|
||||
icon="pf-icon pf-icon-user"
|
||||
header=${t`User Settings`}
|
||||
description=${t`Configure settings relevant to your user profile.`}
|
||||
>
|
||||
</ak-page-header>
|
||||
<ak-tabs ?vertical="${true}" style="height: 100%;">
|
||||
<ak-tabs ?vertical="${true}">
|
||||
<section
|
||||
slot="page-details"
|
||||
data-tab-title="${t`User details`}"
|
||||
|
@ -146,6 +58,46 @@ export class UserSettingsPage extends LitElement {
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section
|
||||
slot="page-sessions"
|
||||
data-tab-title="${t`Sessions`}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
${until(
|
||||
me().then((u) => {
|
||||
return html`<ak-user-session-list
|
||||
targetUser=${u.user.username}
|
||||
></ak-user-session-list>`;
|
||||
}),
|
||||
)}
|
||||
</section>
|
||||
<section
|
||||
slot="page-consents"
|
||||
data-tab-title="${t`Consent`}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
${until(
|
||||
me().then((u) => {
|
||||
return html`<ak-user-consent-list
|
||||
userId=${u.user.pk}
|
||||
></ak-user-consent-list>`;
|
||||
}),
|
||||
)}
|
||||
</section>
|
||||
<section
|
||||
slot="page-stages"
|
||||
data-tab-title="${t`Password, 2FA, etc`}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
<ak-user-settings-stage></ak-user-settings-stage>
|
||||
</section>
|
||||
<section
|
||||
slot="page-sources"
|
||||
data-tab-title="${t`Connected services`}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
<ak-user-settings-source></ak-user-settings-source>
|
||||
</section>
|
||||
<section
|
||||
slot="page-tokens"
|
||||
data-tab-title="${t`Tokens and App passwords`}"
|
||||
|
@ -153,32 +105,6 @@ export class UserSettingsPage extends LitElement {
|
|||
>
|
||||
<ak-user-token-list></ak-user-token-list>
|
||||
</section>
|
||||
${until(
|
||||
this.userSettings?.then((stages) => {
|
||||
return stages.map((stage) => {
|
||||
return html`<section
|
||||
slot="page-${stage.objectUid}"
|
||||
data-tab-title="${ifDefined(stage.title)}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
${this.renderStageSettings(stage)}
|
||||
</section>`;
|
||||
});
|
||||
}),
|
||||
)}
|
||||
${until(
|
||||
this.sourceSettings?.then((source) => {
|
||||
return source.map((stage) => {
|
||||
return html`<section
|
||||
slot="page-${stage.objectUid}"
|
||||
data-tab-title="${ifDefined(stage.title)}"
|
||||
class="pf-c-page__main-section pf-m-no-padding-mobile"
|
||||
>
|
||||
${this.renderSourceSettings(stage)}
|
||||
</section>`;
|
||||
});
|
||||
}),
|
||||
)}
|
||||
</ak-tabs>
|
||||
</main>
|
||||
</div>`;
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
import { customElement, html, property, TemplateResult } from "lit-element";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { SourcesApi } from "@goauthentik/api";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { t } from "@lingui/macro";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
|
||||
@customElement("ak-user-settings-source-oauth")
|
||||
export class SourceSettingsOAuth extends BaseUserSettings {
|
||||
@property()
|
||||
title!: string;
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${t`Source ${this.title}`}</div>
|
||||
<div class="pf-c-card__body">${this.renderInner()}</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderInner(): TemplateResult {
|
||||
return html`${until(
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesUserConnectionsOauthList({
|
||||
sourceSlug: this.objectId,
|
||||
})
|
||||
.then((connection) => {
|
||||
if (connection.results.length > 0) {
|
||||
return html`<p>${t`Connected.`}</p>
|
||||
<button
|
||||
class="pf-c-button pf-m-danger"
|
||||
@click=${() => {
|
||||
return new SourcesApi(
|
||||
DEFAULT_CONFIG,
|
||||
).sourcesUserConnectionsOauthDestroy({
|
||||
id: connection.results[0].pk || 0,
|
||||
});
|
||||
}}
|
||||
>
|
||||
${t`Disconnect`}
|
||||
</button>`;
|
||||
}
|
||||
return html`<p>${t`Not connected.`}</p>
|
||||
<a class="pf-c-button pf-m-primary" href=${ifDefined(this.configureUrl)}>
|
||||
${t`Connect`}
|
||||
</a>`;
|
||||
}),
|
||||
)}`;
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
import { customElement, html, property, TemplateResult } from "lit-element";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { SourcesApi } from "@goauthentik/api";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { t } from "@lingui/macro";
|
||||
|
||||
@customElement("ak-user-settings-source-plex")
|
||||
export class SourceSettingsPlex extends BaseUserSettings {
|
||||
@property()
|
||||
title!: string;
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${t`Source ${this.title}`}</div>
|
||||
<div class="pf-c-card__body">${this.renderInner()}</div>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderInner(): TemplateResult {
|
||||
return html`${until(
|
||||
new SourcesApi(DEFAULT_CONFIG)
|
||||
.sourcesUserConnectionsPlexList({
|
||||
sourceSlug: this.objectId,
|
||||
})
|
||||
.then((connection) => {
|
||||
if (connection.results.length > 0) {
|
||||
return html`<p>${t`Connected.`}</p>
|
||||
<button
|
||||
class="pf-c-button pf-m-danger"
|
||||
@click=${() => {
|
||||
return new SourcesApi(
|
||||
DEFAULT_CONFIG,
|
||||
).sourcesUserConnectionsPlexDestroy({
|
||||
id: connection.results[0].pk || 0,
|
||||
});
|
||||
}}
|
||||
>
|
||||
${t`Disconnect`}
|
||||
</button>`;
|
||||
}
|
||||
return html`<p>${t`Not connected.`}</p>`;
|
||||
}),
|
||||
)}`;
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
import { AuthenticatorsApi } from "@goauthentik/api";
|
||||
import { t } from "@lingui/macro";
|
||||
import { customElement, html, TemplateResult } from "lit-element";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { EVENT_REFRESH } from "../../../constants";
|
||||
|
||||
@customElement("ak-user-settings-authenticator-duo")
|
||||
export class UserSettingsAuthenticatorDuo extends BaseUserSettings {
|
||||
renderEnabled(): TemplateResult {
|
||||
return html`<div class="pf-c-card__body">
|
||||
<p>
|
||||
${t`Status: Enabled`}
|
||||
<i class="pf-icon pf-icon-ok"></i>
|
||||
</p>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
<button
|
||||
class="pf-c-button pf-m-danger"
|
||||
@click=${() => {
|
||||
return new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsDuoList({})
|
||||
.then((devices) => {
|
||||
if (devices.results.length < 1) {
|
||||
return;
|
||||
}
|
||||
// TODO: Handle multiple devices, currently we assume only one TOTP Device
|
||||
return new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsDuoDestroy({
|
||||
id: devices.results[0].pk || 0,
|
||||
})
|
||||
.then(() => {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(EVENT_REFRESH, {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
}}
|
||||
>
|
||||
${t`Disable Duo authenticator`}
|
||||
</button>
|
||||
</div>`;
|
||||
}
|
||||
|
||||
renderDisabled(): TemplateResult {
|
||||
return html` <div class="pf-c-card__body">
|
||||
<p>
|
||||
${t`Status: Disabled`}
|
||||
<i class="pf-icon pf-icon-error-circle-o"></i>
|
||||
</p>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
${this.configureUrl
|
||||
? html`<a
|
||||
href="${this.configureUrl}?next=/%23%2Fuser"
|
||||
class="pf-c-button pf-m-primary"
|
||||
>${t`Enable Duo authenticator`}
|
||||
</a>`
|
||||
: html``}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${t`Duo`}</div>
|
||||
${until(
|
||||
new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsDuoList({}).then((devices) => {
|
||||
return devices.results.length > 0
|
||||
? this.renderEnabled()
|
||||
: this.renderDisabled();
|
||||
}),
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
import { CSSResult, customElement, html, TemplateResult } from "lit-element";
|
||||
import { t } from "@lingui/macro";
|
||||
import { AuthenticatorsApi, WebAuthnDevice } from "@goauthentik/api";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import PFDataList from "@patternfly/patternfly/components/DataList/data-list.css";
|
||||
import "../../../elements/buttons/ModalButton";
|
||||
import "../../../elements/buttons/SpinnerButton";
|
||||
import "../../../elements/forms/DeleteForm";
|
||||
import "../../../elements/forms/Form";
|
||||
import "../../../elements/forms/ModalForm";
|
||||
import "../../../elements/forms/HorizontalFormElement";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
import { EVENT_REFRESH } from "../../../constants";
|
||||
|
||||
@customElement("ak-user-settings-authenticator-webauthn")
|
||||
export class UserSettingsAuthenticatorWebAuthn extends BaseUserSettings {
|
||||
static get styles(): CSSResult[] {
|
||||
return super.styles.concat(PFDataList);
|
||||
}
|
||||
|
||||
renderDelete(device: WebAuthnDevice): TemplateResult {
|
||||
return html`<ak-forms-delete
|
||||
.obj=${device}
|
||||
objectLabel=${t`Authenticator`}
|
||||
.delete=${() => {
|
||||
return new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsWebauthnDestroy({
|
||||
id: device.pk || 0,
|
||||
})
|
||||
.then(() => {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent(EVENT_REFRESH, {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
}}
|
||||
>
|
||||
<button slot="trigger" class="pf-c-button pf-m-danger">${t`Delete`}</button>
|
||||
</ak-forms-delete>`;
|
||||
}
|
||||
|
||||
renderUpdate(device: WebAuthnDevice): TemplateResult {
|
||||
return html`<ak-forms-modal>
|
||||
<span slot="submit"> ${t`Update`} </span>
|
||||
<span slot="header"> ${t`Update`} </span>
|
||||
<ak-form
|
||||
slot="form"
|
||||
successMessage=${t`Successfully updated device.`}
|
||||
.send=${(data: unknown) => {
|
||||
return new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsWebauthnUpdate({
|
||||
id: device.pk || 0,
|
||||
webAuthnDeviceRequest: data as WebAuthnDevice,
|
||||
})
|
||||
.then(() => {
|
||||
this.requestUpdate();
|
||||
});
|
||||
}}
|
||||
>
|
||||
<form class="pf-c-form pf-m-horizontal">
|
||||
<ak-form-element-horizontal
|
||||
label=${t`Device name`}
|
||||
?required=${true}
|
||||
name="name"
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
value="${ifDefined(device.name)}"
|
||||
class="pf-c-form-control"
|
||||
required
|
||||
/>
|
||||
</ak-form-element-horizontal>
|
||||
</form>
|
||||
</ak-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${t`Update`}</button>
|
||||
</ak-forms-modal>`;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${t`WebAuthn Devices`}</div>
|
||||
<div class="pf-c-card__body">
|
||||
<ul class="pf-c-data-list" role="list">
|
||||
${until(
|
||||
new AuthenticatorsApi(DEFAULT_CONFIG)
|
||||
.authenticatorsWebauthnList({})
|
||||
.then((devices) => {
|
||||
return devices.results.map((device) => {
|
||||
return html`<li class="pf-c-data-list__item">
|
||||
<div class="pf-c-data-list__item-row">
|
||||
<div class="pf-c-data-list__item-content">
|
||||
<div class="pf-c-data-list__cell">
|
||||
${device.name || "-"}
|
||||
</div>
|
||||
<div class="pf-c-data-list__cell">
|
||||
${t`Created ${device.createdOn?.toLocaleString()}`}
|
||||
</div>
|
||||
<div class="pf-c-data-list__cell">
|
||||
${this.renderUpdate(device)}
|
||||
${this.renderDelete(device)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>`;
|
||||
});
|
||||
}),
|
||||
)}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pf-c-card__footer">
|
||||
${this.configureUrl
|
||||
? html`<a
|
||||
href="${this.configureUrl}?next=/%23%2Fuser"
|
||||
class="pf-c-button pf-m-primary"
|
||||
>${t`Configure WebAuthn`}
|
||||
</a>`
|
||||
: html``}
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
import { customElement, html, TemplateResult } from "lit-element";
|
||||
import { t } from "@lingui/macro";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
|
||||
@customElement("ak-user-settings-password")
|
||||
export class UserSettingsPassword extends BaseUserSettings {
|
||||
render(): TemplateResult {
|
||||
// For this stage we don't need to check for a configureFlow,
|
||||
// as the stage won't return any UI Elements if no configureFlow is set.
|
||||
return html`<div class="pf-c-card">
|
||||
<div class="pf-c-card__title">${t`Change your password`}</div>
|
||||
<div class="pf-c-card__body">
|
||||
<a href="${ifDefined(this.configureUrl)}" class="pf-c-button pf-m-primary">
|
||||
${t`Change password`}
|
||||
</a>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
import { SourcesApi, UserSetting } from "@goauthentik/api";
|
||||
import { t } from "@lingui/macro";
|
||||
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { EVENT_REFRESH } from "../../../constants";
|
||||
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
|
||||
import "../../../elements/EmptyState";
|
||||
import "./SourceSettingsOAuth";
|
||||
import "./SourceSettingsPlex";
|
||||
|
||||
@customElement("ak-user-settings-source")
|
||||
export class UserSourceSettingsPage extends LitElement {
|
||||
@property({ attribute: false })
|
||||
sourceSettings?: Promise<UserSetting[]>;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [PFGrid];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener(EVENT_REFRESH, () => {
|
||||
this.firstUpdated();
|
||||
});
|
||||
}
|
||||
|
||||
firstUpdated(): void {
|
||||
this.sourceSettings = new SourcesApi(DEFAULT_CONFIG).sourcesAllUserSettingsList();
|
||||
}
|
||||
|
||||
renderSourceSettings(source: UserSetting): TemplateResult {
|
||||
switch (source.component) {
|
||||
case "ak-user-settings-source-oauth":
|
||||
return html`<ak-user-settings-source-oauth
|
||||
objectId=${source.objectUid}
|
||||
title=${source.title}
|
||||
.configureUrl=${source.configureUrl}
|
||||
>
|
||||
</ak-user-settings-source-oauth>`;
|
||||
case "ak-user-settings-source-plex":
|
||||
return html`<ak-user-settings-source-plex
|
||||
objectId=${source.objectUid}
|
||||
title=${source.title}
|
||||
>
|
||||
</ak-user-settings-source-plex>`;
|
||||
default:
|
||||
return html`<p>${t`Error: unsupported source settings: ${source.component}`}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-l-grid pf-m-gutter">
|
||||
${until(
|
||||
this.sourceSettings?.then((source) => {
|
||||
return source.map((stage) => {
|
||||
return html`<div class="pf-l-grid__item pf-m-6-col pf-m-4-col-on-xl">
|
||||
${this.renderSourceSettings(stage)}
|
||||
</div>`;
|
||||
});
|
||||
}),
|
||||
html`<ak-empty-state ?loading="${true}" header=${t`Loading`}> </ak-empty-state>`,
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { customElement, html, property, TemplateResult } from "lit-element";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { BaseUserSettings } from "../BaseUserSettings";
|
||||
import { SourcesApi } from "@goauthentik/api";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
|
@ -1,5 +1,5 @@
|
|||
import { customElement, html, property, TemplateResult } from "lit-element";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { BaseUserSettings } from "../BaseUserSettings";
|
||||
import { SourcesApi } from "@goauthentik/api";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
|
@ -0,0 +1,87 @@
|
|||
import { StagesApi, UserSetting } from "@goauthentik/api";
|
||||
import { t } from "@lingui/macro";
|
||||
import { CSSResult, customElement, html, LitElement, property, TemplateResult } from "lit-element";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { EVENT_REFRESH } from "../../../constants";
|
||||
import PFStack from "@patternfly/patternfly/layouts/Stack/stack.css";
|
||||
|
||||
import "../../../elements/EmptyState";
|
||||
import "./UserSettingsAuthenticatorDuo";
|
||||
import "./UserSettingsAuthenticatorStatic";
|
||||
import "./UserSettingsAuthenticatorTOTP";
|
||||
import "./UserSettingsAuthenticatorWebAuthn";
|
||||
import "./UserSettingsPassword";
|
||||
|
||||
@customElement("ak-user-settings-stage")
|
||||
export class UserStageSettingsPage extends LitElement {
|
||||
@property({ attribute: false })
|
||||
userSettings?: Promise<UserSetting[]>;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return [PFStack];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener(EVENT_REFRESH, () => {
|
||||
this.firstUpdated();
|
||||
});
|
||||
}
|
||||
|
||||
firstUpdated(): void {
|
||||
this.userSettings = new StagesApi(DEFAULT_CONFIG).stagesAllUserSettingsList();
|
||||
}
|
||||
|
||||
renderStageSettings(stage: UserSetting): TemplateResult {
|
||||
switch (stage.component) {
|
||||
case "ak-user-settings-authenticator-webauthn":
|
||||
return html`<ak-user-settings-authenticator-webauthn
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-webauthn>`;
|
||||
case "ak-user-settings-password":
|
||||
return html`<ak-user-settings-password
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-password>`;
|
||||
case "ak-user-settings-authenticator-totp":
|
||||
return html`<ak-user-settings-authenticator-totp
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-totp>`;
|
||||
case "ak-user-settings-authenticator-static":
|
||||
return html`<ak-user-settings-authenticator-static
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-static>`;
|
||||
case "ak-user-settings-authenticator-duo":
|
||||
return html`<ak-user-settings-authenticator-duo
|
||||
objectId=${stage.objectUid}
|
||||
.configureUrl=${stage.configureUrl}
|
||||
>
|
||||
</ak-user-settings-authenticator-duo>`;
|
||||
default:
|
||||
return html`<p>${t`Error: unsupported stage settings: ${stage.component}`}</p>`;
|
||||
}
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-l-stack pf-m-gutter">
|
||||
${until(
|
||||
this.userSettings?.then((stages) => {
|
||||
return stages.map((stage) => {
|
||||
return html`<div class="pf-l-stack__item">
|
||||
${this.renderStageSettings(stage)}
|
||||
</div>`;
|
||||
});
|
||||
}),
|
||||
html`<ak-empty-state ?loading="${true}" header=${t`Loading`}></ak-empty-state>`,
|
||||
)}
|
||||
</div>`;
|
||||
}
|
||||
}
|
|
@ -3,7 +3,7 @@ import { t } from "@lingui/macro";
|
|||
import { customElement, html, TemplateResult } from "lit-element";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { BaseUserSettings } from "../BaseUserSettings";
|
||||
import { EVENT_REFRESH } from "../../../constants";
|
||||
|
||||
@customElement("ak-user-settings-authenticator-duo")
|
|
@ -4,7 +4,7 @@ import { CSSResult, customElement, html, TemplateResult } from "lit-element";
|
|||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { STATIC_TOKEN_STYLE } from "../../../flows/stages/authenticator_static/AuthenticatorStaticStage";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { BaseUserSettings } from "../BaseUserSettings";
|
||||
import { EVENT_REFRESH } from "../../../constants";
|
||||
|
||||
@customElement("ak-user-settings-authenticator-static")
|
|
@ -3,7 +3,7 @@ import { t } from "@lingui/macro";
|
|||
import { customElement, html, TemplateResult } from "lit-element";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { BaseUserSettings } from "../BaseUserSettings";
|
||||
import { EVENT_REFRESH } from "../../../constants";
|
||||
|
||||
@customElement("ak-user-settings-authenticator-totp")
|
|
@ -3,7 +3,7 @@ import { t } from "@lingui/macro";
|
|||
import { AuthenticatorsApi, WebAuthnDevice } from "@goauthentik/api";
|
||||
import { until } from "lit-html/directives/until";
|
||||
import { DEFAULT_CONFIG } from "../../../api/Config";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { BaseUserSettings } from "../BaseUserSettings";
|
||||
import PFDataList from "@patternfly/patternfly/components/DataList/data-list.css";
|
||||
import "../../../elements/buttons/ModalButton";
|
||||
import "../../../elements/buttons/SpinnerButton";
|
|
@ -1,6 +1,6 @@
|
|||
import { customElement, html, TemplateResult } from "lit-element";
|
||||
import { t } from "@lingui/macro";
|
||||
import { BaseUserSettings } from "./BaseUserSettings";
|
||||
import { BaseUserSettings } from "../BaseUserSettings";
|
||||
import { ifDefined } from "lit-html/directives/if-defined";
|
||||
|
||||
@customElement("ak-user-settings-password")
|
|
@ -77,7 +77,7 @@ export class UserTokenList extends Table<Token> {
|
|||
</dt>
|
||||
<dd class="pf-c-description-list__description">
|
||||
<div class="pf-c-description-list__text">
|
||||
${item.user?.username}
|
||||
${item.userObj?.username}
|
||||
</div>
|
||||
</dd>
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,14 @@ slug: "2021.9"
|
|||
|
||||
## Headline Changes
|
||||
|
||||
- Split user interface
|
||||
|
||||
This release splits the administration interface from the end-user interface. This makes things clearer for end-users, as all their options are layed out more clearly.
|
||||
|
||||
Additionally, the new end-user interface will be more customisable than the admin interface, allowing Administrators to configure what their users can see.
|
||||
|
||||
The admin interface remains the same, and familiar buttons will redirect you between interfaces.
|
||||
|
||||
- New proxy
|
||||
|
||||
The proxy outpost has been rewritten from scratch. This replaces the old proxy, which was based on oauth2_proxy. The new proxy allows us a much greater degree of flexibility, is much lighter and reports errors better.
|
||||
|
|
|
@ -69,6 +69,16 @@ rules:
|
|||
- delete
|
||||
- list
|
||||
- patch
|
||||
- apiGroups:
|
||||
- monitoring.coreos.com
|
||||
resources:
|
||||
- servicemonitors
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- delete
|
||||
- list
|
||||
- patch
|
||||
- apiGroups:
|
||||
- apiextensions.k8s.io
|
||||
resources:
|
||||
|
|
Reference in New Issue