From 13e2eea72fa8b7f9bfba4b745154acf060656eec Mon Sep 17 00:00:00 2001 From: Jens L Date: Thu, 16 Sep 2021 22:17:05 +0200 Subject: [PATCH] web/user: new end-user interface (#1404) * web/user: migrate to top navbar Signed-off-by: Jens Langhammer * web/user: prepare config from server Signed-off-by: Jens Langhammer * re-sort Signed-off-by: Jens Langhammer * remove old interface Signed-off-by: Jens Langhammer * update issue template Signed-off-by: Jens Langhammer * use notification badge Signed-off-by: Jens Langhammer * web/user: re-add go-to-admin button Signed-off-by: Jens Langhammer * *: fix remaining redirects directly to admin Signed-off-by: Jens Langhammer * make settings better Signed-off-by: Jens Langhammer * api: ensure sources and stages are sorted Signed-off-by: Jens Langhammer * web/user: add sessions and consent Signed-off-by: Jens Langhammer * providers/oauth2: add post wrapper to stage Signed-off-by: Jens Langhammer * website/docs: add new interface to release notes Signed-off-by: Jens Langhammer --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- .github/ISSUE_TEMPLATE/question.md | 2 +- authentik/core/api/authenticated_sessions.py | 8 +- authentik/core/api/sources.py | 4 +- authentik/core/sources/flow_manager.py | 6 +- authentik/core/templates/if/end_session.html | 2 +- authentik/core/tests/test_impersonation.py | 2 +- authentik/core/views/impersonate.py | 4 +- authentik/flows/api/stages.py | 2 +- authentik/providers/oauth2/views/authorize.py | 4 + authentik/recovery/views.py | 2 +- authentik/sources/saml/processors/response.py | 2 +- authentik/sources/saml/views.py | 2 +- web/src/elements/router/Route.ts | 9 + web/src/elements/sidebar/SidebarUser.ts | 2 +- web/src/interfaces/AdminInterface.ts | 2 +- web/src/interfaces/UserInterface.ts | 229 +++++++++++++----- web/src/locales/en.po | 219 +++++++---------- web/src/locales/pseudo-LOCALE.po | 219 +++++++---------- web/src/pages/LibraryPage.ts | 170 ------------- web/src/pages/user-settings/UserSelfForm.ts | 100 -------- .../pages/user-settings/UserSettingsPage.ts | 186 -------------- .../settings/BaseUserSettings.ts | 19 -- .../UserSettingsAuthenticatorStatic.ts | 100 -------- .../settings/UserSettingsAuthenticatorTOTP.ts | 79 ------ .../user-settings/tokens/UserTokenForm.ts | 62 ----- .../user-settings/tokens/UserTokenList.ts | 156 ------------ web/src/routesAdmin.ts | 5 +- web/src/routesUser.ts | 2 +- web/src/user/LibraryPage.ts | 54 +++-- web/src/user/config.ts | 31 +++ .../{settings => }/BaseUserSettings.ts | 2 +- web/src/user/user-settings/UserSelfForm.ts | 2 +- .../user/user-settings/UserSettingsPage.ts | 170 ++++--------- .../settings/SourceSettingsOAuth.ts | 50 ---- .../settings/SourceSettingsPlex.ts | 46 ---- .../settings/UserSettingsAuthenticatorDuo.ts | 79 ------ .../UserSettingsAuthenticatorWebAuthn.ts | 125 ---------- .../settings/UserSettingsPassword.ts | 20 -- .../user-settings/sources/SourceSettings.ts | 67 +++++ .../sources}/SourceSettingsOAuth.ts | 2 +- .../sources}/SourceSettingsPlex.ts | 2 +- .../user-settings/stages/StageSettings.ts | 87 +++++++ .../stages}/UserSettingsAuthenticatorDuo.ts | 2 +- .../UserSettingsAuthenticatorStatic.ts | 2 +- .../UserSettingsAuthenticatorTOTP.ts | 2 +- .../UserSettingsAuthenticatorWebAuthn.ts | 2 +- .../stages}/UserSettingsPassword.ts | 2 +- .../user-settings/tokens/UserTokenList.ts | 2 +- website/docs/releases/v2021.9.md | 8 + website/static/service-account.yaml | 10 + 51 files changed, 660 insertions(+), 1708 deletions(-) delete mode 100644 web/src/pages/LibraryPage.ts delete mode 100644 web/src/pages/user-settings/UserSelfForm.ts delete mode 100644 web/src/pages/user-settings/UserSettingsPage.ts delete mode 100644 web/src/pages/user-settings/settings/BaseUserSettings.ts delete mode 100644 web/src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts delete mode 100644 web/src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts delete mode 100644 web/src/pages/user-settings/tokens/UserTokenForm.ts delete mode 100644 web/src/pages/user-settings/tokens/UserTokenList.ts create mode 100644 web/src/user/config.ts rename web/src/user/user-settings/{settings => }/BaseUserSettings.ts (93%) delete mode 100644 web/src/user/user-settings/settings/SourceSettingsOAuth.ts delete mode 100644 web/src/user/user-settings/settings/SourceSettingsPlex.ts delete mode 100644 web/src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts delete mode 100644 web/src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts delete mode 100644 web/src/user/user-settings/settings/UserSettingsPassword.ts create mode 100644 web/src/user/user-settings/sources/SourceSettings.ts rename web/src/{pages/user-settings/settings => user/user-settings/sources}/SourceSettingsOAuth.ts (97%) rename web/src/{pages/user-settings/settings => user/user-settings/sources}/SourceSettingsPlex.ts (96%) create mode 100644 web/src/user/user-settings/stages/StageSettings.ts rename web/src/{pages/user-settings/settings => user/user-settings/stages}/UserSettingsAuthenticatorDuo.ts (98%) rename web/src/user/user-settings/{settings => stages}/UserSettingsAuthenticatorStatic.ts (98%) rename web/src/user/user-settings/{settings => stages}/UserSettingsAuthenticatorTOTP.ts (98%) rename web/src/{pages/user-settings/settings => user/user-settings/stages}/UserSettingsAuthenticatorWebAuthn.ts (98%) rename web/src/{pages/user-settings/settings => user/user-settings/stages}/UserSettingsPassword.ts (93%) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 79b68b549..9c373e495 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -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** diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md index 608c96340..dd31a59ae 100644 --- a/.github/ISSUE_TEMPLATE/question.md +++ b/.github/ISSUE_TEMPLATE/question.md @@ -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** diff --git a/authentik/core/api/authenticated_sessions.py b/authentik/core/api/authenticated_sessions.py index 1745811a3..7ff71b6ce 100644 --- a/authentik/core/api/authenticated_sessions.py +++ b/authentik/core/api/authenticated_sessions.py @@ -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() diff --git a/authentik/core/api/sources.py b/authentik/core/api/sources.py index e4f8feb38..18239ee16 100644 --- a/authentik/core/api/sources.py +++ b/authentik/core/api/sources.py @@ -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 diff --git a/authentik/core/sources/flow_manager.py b/authentik/core/sources/flow_manager.py index 0cac12440..f91fa4b70 100644 --- a/authentik/core/sources/flow_manager.py +++ b/authentik/core/sources/flow_manager.py @@ -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( diff --git a/authentik/core/templates/if/end_session.html b/authentik/core/templates/if/end_session.html index 9d98f1af4..e4699b610 100644 --- a/authentik/core/templates/if/end_session.html +++ b/authentik/core/templates/if/end_session.html @@ -21,7 +21,7 @@ You've logged out of {{ application }}. {% endblocktrans %}

- {% trans 'Go back to overview' %} + {% trans 'Go back to overview' %} {% trans 'Log out of authentik' %} diff --git a/authentik/core/tests/test_impersonation.py b/authentik/core/tests/test_impersonation.py index 164c902c8..9a5bbdd22 100644 --- a/authentik/core/tests/test_impersonation.py +++ b/authentik/core/tests/test_impersonation.py @@ -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")) diff --git a/authentik/core/views/impersonate.py b/authentik/core/views/impersonate.py index ddeb4f940..96d66d4df 100644 --- a/authentik/core/views/impersonate.py +++ b/authentik/core/views/impersonate.py @@ -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] diff --git a/authentik/flows/api/stages.py b/authentik/flows/api/stages.py index e9706caac..dc9a34128 100644 --- a/authentik/flows/api/stages.py +++ b/authentik/flows/api/stages.py @@ -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 diff --git a/authentik/providers/oauth2/views/authorize.py b/authentik/providers/oauth2/views/authorize.py index f451fe5ee..cd9ee752b 100644 --- a/authentik/providers/oauth2/views/authorize.py +++ b/authentik/providers/oauth2/views/authorize.py @@ -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""" diff --git a/authentik/recovery/views.py b/authentik/recovery/views.py index 3253ab332..200b44f52 100644 --- a/authentik/recovery/views.py +++ b/authentik/recovery/views.py @@ -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") diff --git a/authentik/sources/saml/processors/response.py b/authentik/sources/saml/processors/response.py index c2537770c..6f8702c95 100644 --- a/authentik/sources/saml/processors/response.py +++ b/authentik/sources/saml/processors/response.py @@ -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 diff --git a/authentik/sources/saml/views.py b/authentik/sources/saml/views.py index ef304c0b2..3afc75ab1 100644 --- a/authentik/sources/saml/views.py +++ b/authentik/sources/saml/views.py @@ -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( { diff --git a/web/src/elements/router/Route.ts b/web/src/elements/router/Route.ts index bf4b61301..90ac2b64e 100644 --- a/web/src/elements/router/Route.ts +++ b/web/src/elements/router/Route.ts @@ -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; diff --git a/web/src/elements/sidebar/SidebarUser.ts b/web/src/elements/sidebar/SidebarUser.ts index 90bc3161b..276f3c4e1 100644 --- a/web/src/elements/sidebar/SidebarUser.ts +++ b/web/src/elements/sidebar/SidebarUser.ts @@ -32,7 +32,7 @@ export class SidebarUser extends LitElement { render(): TemplateResult { return html` - + ${until( me().then((u) => { return html` - ${t`Go to user interface`} + ${t`User interface`} ${t`Overview`} diff --git a/web/src/interfaces/UserInterface.ts b/web/src/interfaces/UserInterface.ts index 584ab552c..7dd11ebd0 100644 --- a/web/src/interfaces/UserInterface.ts +++ b/web/src/interfaces/UserInterface.ts @@ -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; + @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`
- - ${this.renderSidebarItems()} - +
+ +
+
+ ${until( + uiConfig().then((config) => { + if (!config.enabledFeatures.apiDrawer) { + return html``; + } + return html`
+ +
`; + }), + )} + ${until( + uiConfig().then((config) => { + if (!config.enabledFeatures.notificationDrawer) { + return html``; + } + return html` + + `; + }), + )} + ${until( + uiConfig().then((config) => { + if (!config.enabledFeatures.settings) { + return html``; + } + return html`
+ + + +
`; + }), + )} + + + + ${until( + me().then((u) => { + if (!u.user.isSuperuser) return html``; + return html` + + ${t`Admin interface`} + + `; + }), + )} +
+
+
+ ${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; + } + }); + }), + )} + +
+
+ ${until( + me().then((me) => { + return html`${t`Avatar image`}`; + }), + )} +
+
`; } - - renderSidebarItems(): TemplateResult { - return html` - ${until( - this.version.then((version) => { - if (version.versionCurrent !== VERSION) { - return html` - ${t`A newer version of the frontend is available.`} - `; - } - return html``; - }), - )} - ${until( - me().then((u) => { - if (u.original) { - return html` - ${t`You're currently impersonating ${u.user.username}. Click to stop.`} - `; - } - return html``; - }), - )} - - ${t`Go to admin interface`} - - - ${t`Library`} - - `; - } } diff --git a/web/src/locales/en.po b/web/src/locales/en.po index a08de843f..e8b5e7478 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -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." diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index 9d20942df..2b7ea0deb 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -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 "" diff --git a/web/src/pages/LibraryPage.ts b/web/src/pages/LibraryPage.ts deleted file mode 100644 index a87b8ddc6..000000000 --- a/web/src/pages/LibraryPage.ts +++ /dev/null @@ -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``; - } - return html`
-
- ${this.application.metaIcon - ? html`Application Icon` - : html``} - ${until( - me().then((u) => { - if (!u.user.isSuperuser) return html``; - return html` - - - - `; - }), - )} -
-
-

- ${this.application.name} -

-
- ${this.application.metaPublisher} -
-
-
${truncate(this.application.metaDescription, 35)}
-
`; - } -} - -@customElement("ak-library") -export class LibraryPage extends LitElement { - @property({ attribute: false }) - apps?: AKResponse; - - 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`
-
- -

${t`No Applications available.`}

-
- ${t`Either no applications are defined, or you don't have access to any.`} -
-
-
`; - } - - renderApps(): TemplateResult { - return html``; - } - - render(): TemplateResult { - return html`
- - -
- ${loading( - this.apps, - html`${(this.apps?.results.length || 0) > 0 - ? this.renderApps() - : this.renderEmptyState()}`, - )} -
-
`; - } -} diff --git a/web/src/pages/user-settings/UserSelfForm.ts b/web/src/pages/user-settings/UserSelfForm.ts deleted file mode 100644 index ffacc10f6..000000000 --- a/web/src/pages/user-settings/UserSelfForm.ts +++ /dev/null @@ -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 { - viewportCheck = false; - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - loadInstance(pk: number): Promise { - return new CoreApi(DEFAULT_CONFIG).coreUsersMeRetrieve().then((su) => { - return su.user; - }); - } - - getSuccessMessage(): string { - return t`Successfully updated details.`; - } - - send = (data: UserSelf): Promise => { - return new CoreApi(DEFAULT_CONFIG) - .coreUsersUpdateSelfUpdate({ - userSelfRequest: data, - }) - .then((su) => { - return su.user; - }); - }; - - renderForm(): TemplateResult { - if (!this.instance) { - return html` `; - } - return html`
- - -

- ${t`Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.`} -

-
- - -

${t`User's display name.`}

-
- - - - -
-
-
- - ${until( - tenant().then((tenant) => { - if (tenant.flowUnenrollment) { - return html` - ${t`Delete account`} - `; - } - return html``; - }), - )} -
-
-
-
`; - } -} diff --git a/web/src/pages/user-settings/UserSettingsPage.ts b/web/src/pages/user-settings/UserSettingsPage.ts deleted file mode 100644 index e7b627857..000000000 --- a/web/src/pages/user-settings/UserSettingsPage.ts +++ /dev/null @@ -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; - - @property({ attribute: false }) - sourceSettings?: Promise; - - 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` - `; - case "ak-user-settings-password": - return html` - `; - case "ak-user-settings-authenticator-totp": - return html` - `; - case "ak-user-settings-authenticator-static": - return html` - `; - case "ak-user-settings-authenticator-duo": - return html` - `; - default: - return html`

${t`Error: unsupported stage settings: ${stage.component}`}

`; - } - } - - renderSourceSettings(source: UserSetting): TemplateResult { - switch (source.component) { - case "ak-user-settings-source-oauth": - return html` - `; - case "ak-user-settings-source-plex": - return html` - `; - default: - return html`

${t`Error: unsupported source settings: ${source.component}`}

`; - } - } - - render(): TemplateResult { - return html`
-
- - - -
-
-
${t`Update details`}
-
- -
-
-
-
- -
- ${until( - this.userSettings?.then((stages) => { - return stages.map((stage) => { - return html`
- ${this.renderStageSettings(stage)} -
`; - }); - }), - )} - ${until( - this.sourceSettings?.then((source) => { - return source.map((stage) => { - return html`
- ${this.renderSourceSettings(stage)} -
`; - }); - }), - )} -
-
-
`; - } -} diff --git a/web/src/pages/user-settings/settings/BaseUserSettings.ts b/web/src/pages/user-settings/settings/BaseUserSettings.ts deleted file mode 100644 index 7b7863d9d..000000000 --- a/web/src/pages/user-settings/settings/BaseUserSettings.ts +++ /dev/null @@ -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]; - } -} diff --git a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts b/web/src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts deleted file mode 100644 index 077980a92..000000000 --- a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorStatic.ts +++ /dev/null @@ -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`
-

- ${t`Status: Enabled`} - -

-
    - ${until( - new AuthenticatorsApi(DEFAULT_CONFIG) - .authenticatorsStaticList({}) - .then((devices) => { - if (devices.results.length < 1) { - return; - } - return devices.results[0].tokenSet?.map((token) => { - return html`
  • ${token.token}
  • `; - }); - }), - )} -
-
- `; - } - - renderDisabled(): TemplateResult { - return html`
-

- ${t`Status: Disabled`} - -

-
- `; - } - - render(): TemplateResult { - return html`
-
${t`Static tokens`}
- ${until( - new AuthenticatorsApi(DEFAULT_CONFIG) - .authenticatorsStaticList({}) - .then((devices) => { - return devices.results.length > 0 - ? this.renderEnabled() - : this.renderDisabled(); - }), - )} -
`; - } -} diff --git a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts b/web/src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts deleted file mode 100644 index 827973df1..000000000 --- a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorTOTP.ts +++ /dev/null @@ -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`
-

- ${t`Status: Enabled`} - -

-
- `; - } - - renderDisabled(): TemplateResult { - return html`
-

- ${t`Status: Disabled`} - -

-
- `; - } - - render(): TemplateResult { - return html`
-
${t`Time-based One-Time Passwords`}
- ${until( - new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsTotpList({}).then((devices) => { - return devices.results.length > 0 - ? this.renderEnabled() - : this.renderDisabled(); - }), - )} -
`; - } -} diff --git a/web/src/pages/user-settings/tokens/UserTokenForm.ts b/web/src/pages/user-settings/tokens/UserTokenForm.ts deleted file mode 100644 index 3c4ffd4c2..000000000 --- a/web/src/pages/user-settings/tokens/UserTokenForm.ts +++ /dev/null @@ -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 { - @property() - intent: IntentEnum = IntentEnum.Api; - - loadInstance(pk: string): Promise { - 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 => { - 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`
- - - - - - -
`; - } -} diff --git a/web/src/pages/user-settings/tokens/UserTokenList.ts b/web/src/pages/user-settings/tokens/UserTokenList.ts deleted file mode 100644 index b9e6fc5c1..000000000 --- a/web/src/pages/user-settings/tokens/UserTokenList.ts +++ /dev/null @@ -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 { - searchEnabled(): boolean { - return true; - } - - expandable = true; - checkbox = true; - - @property() - order = "expires"; - - apiEndpoint(page: number): Promise> { - 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` - - ${t`Create`} - ${t`Create Token`} - - - - - ${t`Create`} - ${t`Create App password`} - - - - - ${super.renderToolbar()} - `; - } - - renderExpanded(item: Token): TemplateResult { - return html` -
-
-
-
- ${t`User`} -
-
-
- ${item.user?.username} -
-
-
-
-
- ${t`Expiring`} -
-
-
- ${item.expiring ? t`Yes` : t`No`} -
-
-
-
-
- ${t`Expiring`} -
-
-
- ${item.expiring ? item.expires?.toLocaleString() : "-"} -
-
-
-
-
- ${t`Intent`} -
-
-
- ${IntentToLabel(item.intent || IntentEnum.Api)} -
-
-
-
-
- - `; - } - - renderToolbarSelected(): TemplateResult { - const disabled = this.selectedElements.length < 1; - return html` { - return new CoreApi(DEFAULT_CONFIG).coreTokensDestroy({ - identifier: item.identifier, - }); - }} - > - - `; - } - - row(item: Token): TemplateResult[] { - return [ - html`${item.identifier}`, - html` - - ${t`Update`} - ${t`Update Token`} - - - - - - ${t`Copy Key`} - - `, - ]; - } -} diff --git a/web/src/routesAdmin.ts b/web/src/routesAdmin.ts index 58462a1e4..abd01e74f 100644 --- a/web/src/routesAdmin.ts +++ b/web/src/routesAdmin.ts @@ -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``), + new Route(new RegExp("^/library$")).redirectRaw("/if/user/"), new Route( new RegExp("^/administration/overview$"), html``, @@ -112,5 +110,4 @@ export const ROUTES: Route[] = [ new RegExp("^/crypto/certificates$"), html``, ), - new Route(new RegExp("^/user$"), html``), ]; diff --git a/web/src/routesUser.ts b/web/src/routesUser.ts index fc69c25e6..44f17b46c 100644 --- a/web/src/routesUser.ts +++ b/web/src/routesUser.ts @@ -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``), - new Route(new RegExp("^/user$"), html``), + new Route(new RegExp("^/settings$"), html``), ]; diff --git a/web/src/user/LibraryPage.ts b/web/src/user/LibraryPage.ts index a87b8ddc6..cdd2fb68e 100644 --- a/web/src/user/LibraryPage.ts +++ b/web/src/user/LibraryPage.ts @@ -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,16 +80,21 @@ export class LibraryApplication extends LitElement { />` : html``} ${until( - me().then((u) => { - if (!u.user.isSuperuser) return html``; - return html` - - - - `; + uiConfig().then((config) => { + if (!config.enabledFeatures.applicationEdit) { + return html``; + } + return me().then((u) => { + if (!u.user.isSuperuser) return html``; + return html` + + + + `; + }); }), )}
@@ -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``; } render(): TemplateResult { return html`
- - +
+

${t`My applications`}

+
${loading( this.apps, diff --git a/web/src/user/config.ts b/web/src/user/config.ts new file mode 100644 index 000000000..5108a3ca3 --- /dev/null +++ b/web/src/user/config.ts @@ -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 { + return Promise.resolve(DefaultUIConfig); +} diff --git a/web/src/user/user-settings/settings/BaseUserSettings.ts b/web/src/user/user-settings/BaseUserSettings.ts similarity index 93% rename from web/src/user/user-settings/settings/BaseUserSettings.ts rename to web/src/user/user-settings/BaseUserSettings.ts index 7b7863d9d..a5eb6d713 100644 --- a/web/src/user/user-settings/settings/BaseUserSettings.ts +++ b/web/src/user/user-settings/BaseUserSettings.ts @@ -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"; diff --git a/web/src/user/user-settings/UserSelfForm.ts b/web/src/user/user-settings/UserSelfForm.ts index ffacc10f6..de4781f3b 100644 --- a/web/src/user/user-settings/UserSelfForm.ts +++ b/web/src/user/user-settings/UserSelfForm.ts @@ -77,7 +77,7 @@ export class UserSelfForm extends ModelForm { }} class="pf-c-button pf-m-primary" > - ${t`Update`} + ${t`Save`} ${until( tenant().then((tenant) => { diff --git a/web/src/user/user-settings/UserSettingsPage.ts b/web/src/user/user-settings/UserSettingsPage.ts index e7b627857..faaad67b2 100644 --- a/web/src/user/user-settings/UserSettingsPage.ts +++ b/web/src/user/user-settings/UserSettingsPage.ts @@ -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; - - @property({ attribute: false }) - sourceSettings?: Promise; - - 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` - `; - case "ak-user-settings-password": - return html` - `; - case "ak-user-settings-authenticator-totp": - return html` - `; - case "ak-user-settings-authenticator-static": - return html` - `; - case "ak-user-settings-authenticator-duo": - return html` - `; - default: - return html`

${t`Error: unsupported stage settings: ${stage.component}`}

`; - } - } - - renderSourceSettings(source: UserSetting): TemplateResult { - switch (source.component) { - case "ak-user-settings-source-oauth": - return html` - `; - case "ak-user-settings-source-plex": - return html` - `; - default: - return html`

${t`Error: unsupported source settings: ${source.component}`}

`; - } - } - render(): TemplateResult { return html`
- - - +
+
+ ${until( + me().then((u) => { + return html``; + }), + )} +
+
+ ${until( + me().then((u) => { + return html``; + }), + )} +
+
+ +
+
+ +
- ${until( - this.userSettings?.then((stages) => { - return stages.map((stage) => { - return html`
- ${this.renderStageSettings(stage)} -
`; - }); - }), - )} - ${until( - this.sourceSettings?.then((source) => { - return source.map((stage) => { - return html`
- ${this.renderSourceSettings(stage)} -
`; - }); - }), - )}
`; diff --git a/web/src/user/user-settings/settings/SourceSettingsOAuth.ts b/web/src/user/user-settings/settings/SourceSettingsOAuth.ts deleted file mode 100644 index 42ada8723..000000000 --- a/web/src/user/user-settings/settings/SourceSettingsOAuth.ts +++ /dev/null @@ -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`
-
${t`Source ${this.title}`}
-
${this.renderInner()}
-
`; - } - - renderInner(): TemplateResult { - return html`${until( - new SourcesApi(DEFAULT_CONFIG) - .sourcesUserConnectionsOauthList({ - sourceSlug: this.objectId, - }) - .then((connection) => { - if (connection.results.length > 0) { - return html`

${t`Connected.`}

- `; - } - return html`

${t`Not connected.`}

- - ${t`Connect`} - `; - }), - )}`; - } -} diff --git a/web/src/user/user-settings/settings/SourceSettingsPlex.ts b/web/src/user/user-settings/settings/SourceSettingsPlex.ts deleted file mode 100644 index cd015b6a2..000000000 --- a/web/src/user/user-settings/settings/SourceSettingsPlex.ts +++ /dev/null @@ -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`
-
${t`Source ${this.title}`}
-
${this.renderInner()}
-
`; - } - - renderInner(): TemplateResult { - return html`${until( - new SourcesApi(DEFAULT_CONFIG) - .sourcesUserConnectionsPlexList({ - sourceSlug: this.objectId, - }) - .then((connection) => { - if (connection.results.length > 0) { - return html`

${t`Connected.`}

- `; - } - return html`

${t`Not connected.`}

`; - }), - )}`; - } -} diff --git a/web/src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts b/web/src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts deleted file mode 100644 index 86f34c66b..000000000 --- a/web/src/user/user-settings/settings/UserSettingsAuthenticatorDuo.ts +++ /dev/null @@ -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`
-

- ${t`Status: Enabled`} - -

-
- `; - } - - renderDisabled(): TemplateResult { - return html`
-

- ${t`Status: Disabled`} - -

-
- `; - } - - render(): TemplateResult { - return html`
-
${t`Duo`}
- ${until( - new AuthenticatorsApi(DEFAULT_CONFIG).authenticatorsDuoList({}).then((devices) => { - return devices.results.length > 0 - ? this.renderEnabled() - : this.renderDisabled(); - }), - )} -
`; - } -} diff --git a/web/src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts b/web/src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts deleted file mode 100644 index 8436125fe..000000000 --- a/web/src/user/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts +++ /dev/null @@ -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` { - return new AuthenticatorsApi(DEFAULT_CONFIG) - .authenticatorsWebauthnDestroy({ - id: device.pk || 0, - }) - .then(() => { - this.dispatchEvent( - new CustomEvent(EVENT_REFRESH, { - bubbles: true, - composed: true, - }), - ); - }); - }} - > - - `; - } - - renderUpdate(device: WebAuthnDevice): TemplateResult { - return html` - ${t`Update`} - ${t`Update`} - { - return new AuthenticatorsApi(DEFAULT_CONFIG) - .authenticatorsWebauthnUpdate({ - id: device.pk || 0, - webAuthnDeviceRequest: data as WebAuthnDevice, - }) - .then(() => { - this.requestUpdate(); - }); - }} - > -
- - - -
-
- -
`; - } - - render(): TemplateResult { - return html`
-
${t`WebAuthn Devices`}
-
-
    - ${until( - new AuthenticatorsApi(DEFAULT_CONFIG) - .authenticatorsWebauthnList({}) - .then((devices) => { - return devices.results.map((device) => { - return html`
  • -
    -
    -
    - ${device.name || "-"} -
    -
    - ${t`Created ${device.createdOn?.toLocaleString()}`} -
    -
    - ${this.renderUpdate(device)} - ${this.renderDelete(device)} -
    -
    -
    -
  • `; - }); - }), - )} -
-
- -
`; - } -} diff --git a/web/src/user/user-settings/settings/UserSettingsPassword.ts b/web/src/user/user-settings/settings/UserSettingsPassword.ts deleted file mode 100644 index f92f4eecc..000000000 --- a/web/src/user/user-settings/settings/UserSettingsPassword.ts +++ /dev/null @@ -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`
-
${t`Change your password`}
- -
`; - } -} diff --git a/web/src/user/user-settings/sources/SourceSettings.ts b/web/src/user/user-settings/sources/SourceSettings.ts new file mode 100644 index 000000000..1e192f087 --- /dev/null +++ b/web/src/user/user-settings/sources/SourceSettings.ts @@ -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; + + 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` + `; + case "ak-user-settings-source-plex": + return html` + `; + default: + return html`

${t`Error: unsupported source settings: ${source.component}`}

`; + } + } + + render(): TemplateResult { + return html`
+ ${until( + this.sourceSettings?.then((source) => { + return source.map((stage) => { + return html`
+ ${this.renderSourceSettings(stage)} +
`; + }); + }), + html` `, + )} +
`; + } +} diff --git a/web/src/pages/user-settings/settings/SourceSettingsOAuth.ts b/web/src/user/user-settings/sources/SourceSettingsOAuth.ts similarity index 97% rename from web/src/pages/user-settings/settings/SourceSettingsOAuth.ts rename to web/src/user/user-settings/sources/SourceSettingsOAuth.ts index 42ada8723..1f8a47fb9 100644 --- a/web/src/pages/user-settings/settings/SourceSettingsOAuth.ts +++ b/web/src/user/user-settings/sources/SourceSettingsOAuth.ts @@ -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"; diff --git a/web/src/pages/user-settings/settings/SourceSettingsPlex.ts b/web/src/user/user-settings/sources/SourceSettingsPlex.ts similarity index 96% rename from web/src/pages/user-settings/settings/SourceSettingsPlex.ts rename to web/src/user/user-settings/sources/SourceSettingsPlex.ts index cd015b6a2..c660c7609 100644 --- a/web/src/pages/user-settings/settings/SourceSettingsPlex.ts +++ b/web/src/user/user-settings/sources/SourceSettingsPlex.ts @@ -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"; diff --git a/web/src/user/user-settings/stages/StageSettings.ts b/web/src/user/user-settings/stages/StageSettings.ts new file mode 100644 index 000000000..41062d8e4 --- /dev/null +++ b/web/src/user/user-settings/stages/StageSettings.ts @@ -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; + + 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` + `; + case "ak-user-settings-password": + return html` + `; + case "ak-user-settings-authenticator-totp": + return html` + `; + case "ak-user-settings-authenticator-static": + return html` + `; + case "ak-user-settings-authenticator-duo": + return html` + `; + default: + return html`

${t`Error: unsupported stage settings: ${stage.component}`}

`; + } + } + + render(): TemplateResult { + return html`
+ ${until( + this.userSettings?.then((stages) => { + return stages.map((stage) => { + return html`
+ ${this.renderStageSettings(stage)} +
`; + }); + }), + html``, + )} +
`; + } +} diff --git a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts b/web/src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts similarity index 98% rename from web/src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts rename to web/src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts index 86f34c66b..fe53067cb 100644 --- a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorDuo.ts +++ b/web/src/user/user-settings/stages/UserSettingsAuthenticatorDuo.ts @@ -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") diff --git a/web/src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts b/web/src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts similarity index 98% rename from web/src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts rename to web/src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts index 077980a92..df4b8ce29 100644 --- a/web/src/user/user-settings/settings/UserSettingsAuthenticatorStatic.ts +++ b/web/src/user/user-settings/stages/UserSettingsAuthenticatorStatic.ts @@ -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") diff --git a/web/src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts b/web/src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts similarity index 98% rename from web/src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts rename to web/src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts index 827973df1..12541cef2 100644 --- a/web/src/user/user-settings/settings/UserSettingsAuthenticatorTOTP.ts +++ b/web/src/user/user-settings/stages/UserSettingsAuthenticatorTOTP.ts @@ -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") diff --git a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts b/web/src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts similarity index 98% rename from web/src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts rename to web/src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts index 8436125fe..2ee2434dd 100644 --- a/web/src/pages/user-settings/settings/UserSettingsAuthenticatorWebAuthn.ts +++ b/web/src/user/user-settings/stages/UserSettingsAuthenticatorWebAuthn.ts @@ -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"; diff --git a/web/src/pages/user-settings/settings/UserSettingsPassword.ts b/web/src/user/user-settings/stages/UserSettingsPassword.ts similarity index 93% rename from web/src/pages/user-settings/settings/UserSettingsPassword.ts rename to web/src/user/user-settings/stages/UserSettingsPassword.ts index f92f4eecc..ed14e9239 100644 --- a/web/src/pages/user-settings/settings/UserSettingsPassword.ts +++ b/web/src/user/user-settings/stages/UserSettingsPassword.ts @@ -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") diff --git a/web/src/user/user-settings/tokens/UserTokenList.ts b/web/src/user/user-settings/tokens/UserTokenList.ts index 26ae7e605..54c7ce936 100644 --- a/web/src/user/user-settings/tokens/UserTokenList.ts +++ b/web/src/user/user-settings/tokens/UserTokenList.ts @@ -77,7 +77,7 @@ export class UserTokenList extends Table {
- ${item.user?.username} + ${item.userObj?.username}
diff --git a/website/docs/releases/v2021.9.md b/website/docs/releases/v2021.9.md index 46634a37c..c6c2652d7 100644 --- a/website/docs/releases/v2021.9.md +++ b/website/docs/releases/v2021.9.md @@ -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. diff --git a/website/static/service-account.yaml b/website/static/service-account.yaml index 722d0970f..92b54bfa0 100644 --- a/website/static/service-account.yaml +++ b/website/static/service-account.yaml @@ -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: