diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 363bab7c1..f30d7888d 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2021.4.2 +current_version = 2021.4.4 tag = True commit = True parse = (?P\d+)\.(?P\d+)\.(?P\d+)\-?(?P.*) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index afea61725..393c72c93 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,11 +18,11 @@ jobs: - name: Building Docker Image run: docker build --no-cache - -t beryju/authentik:2021.4.2 + -t beryju/authentik:2021.4.4 -t beryju/authentik:latest -f Dockerfile . - name: Push Docker Container to Registry (versioned) - run: docker push beryju/authentik:2021.4.2 + run: docker push beryju/authentik:2021.4.4 - name: Push Docker Container to Registry (latest) run: docker push beryju/authentik:latest build-proxy: @@ -48,11 +48,11 @@ jobs: cd outpost/ docker build \ --no-cache \ - -t beryju/authentik-proxy:2021.4.2 \ + -t beryju/authentik-proxy:2021.4.4 \ -t beryju/authentik-proxy:latest \ -f proxy.Dockerfile . - name: Push Docker Container to Registry (versioned) - run: docker push beryju/authentik-proxy:2021.4.2 + run: docker push beryju/authentik-proxy:2021.4.4 - name: Push Docker Container to Registry (latest) run: docker push beryju/authentik-proxy:latest build-static: @@ -72,11 +72,11 @@ jobs: cd web/ docker build \ --no-cache \ - -t beryju/authentik-static:2021.4.2 \ + -t beryju/authentik-static:2021.4.4 \ -t beryju/authentik-static:latest \ -f Dockerfile . - name: Push Docker Container to Registry (versioned) - run: docker push beryju/authentik-static:2021.4.2 + run: docker push beryju/authentik-static:2021.4.4 - name: Push Docker Container to Registry (latest) run: docker push beryju/authentik-static:latest test-release: @@ -110,5 +110,5 @@ jobs: SENTRY_PROJECT: authentik SENTRY_URL: https://sentry.beryju.org with: - tagName: 2021.4.2 + tagName: 2021.4.4 environment: beryjuorg-prod diff --git a/Pipfile.lock b/Pipfile.lock index 4e705873b..5710a5415 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -116,18 +116,18 @@ }, "boto3": { "hashes": [ - "sha256:1d26f6e7ae3c940cb07119077ac42485dcf99164350da0ab50d0f5ad345800cd", - "sha256:3bf3305571f3c8b738a53e9e7dcff59137dffe94670046c084a17f9fa4599ff3" + "sha256:1e55df93aa47a84e2a12a639c7f145e16e6e9ef959542d69d5526d50d2e92692", + "sha256:eab42daaaf68cdad5b112d31dcb0684162098f6558ba7b64156be44f993525fa" ], "index": "pypi", - "version": "==1.17.53" + "version": "==1.17.54" }, "botocore": { "hashes": [ - "sha256:d5e70d17b91c9b5867be7d6de0caa7dde9ed789bed62f03ea9b60718dc9350bf", - "sha256:e303500c4e80f6a706602da53daa6f751cfa8f491665c99a24ee732ab6321573" + "sha256:20a864fc6570ba11d52532c72c3ccabab5c71a9b4a9418601a313d56f1d2ce5b", + "sha256:37ec76ea2df8609540ba6cb0fe360ae1c589d2e1ee91eb642fd767823f3fcedd" ], - "version": "==1.20.53" + "version": "==1.20.54" }, "cachetools": { "hashes": [ @@ -1106,10 +1106,10 @@ }, "s3transfer": { "hashes": [ - "sha256:35627b86af8ff97e7ac27975fe0a98a312814b46c6333d8a6b889627bcd80994", - "sha256:efa5bd92a897b6a8d5c1383828dca3d52d0790e0756d49740563a3fb6ed03246" + "sha256:af1af6384bd7fb8208b06480f9be73d0295d965c4c073a5c95ea5b6661dccc18", + "sha256:f3dfd791cad2799403e3c8051810a7ca6ee1d2e630e5d2a8f9649d892bdb3db6" ], - "version": "==0.3.7" + "version": "==0.4.0" }, "sentry-sdk": { "hashes": [ diff --git a/README.md b/README.md index a7c987450..d8e24a50a 100644 --- a/README.md +++ b/README.md @@ -5,12 +5,12 @@ --- [![](https://img.shields.io/discord/809154715984199690?label=Discord&style=flat-square)](https://discord.gg/jg33eMhnj6) -[![CI Build status](https://img.shields.io/azure-devops/build/beryjuorg/authentik/1?style=flat-square)](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=1) -[![Tests](https://img.shields.io/azure-devops/tests/beryjuorg/authentik/1?compact_message&style=flat-square)](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=1) -[![Code Coverage](https://img.shields.io/codecov/c/gh/beryju/authentik?style=flat-square)](https://codecov.io/gh/BeryJu/authentik) +[![CI Build status](https://img.shields.io/azure-devops/build/beryjuorg/authentik/6?style=flat-square)](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=6) +[![Tests](https://img.shields.io/azure-devops/tests/beryjuorg/authentik/6?compact_message&style=flat-square)](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=6) +[![Code Coverage](https://img.shields.io/codecov/c/gh/goauthentik/authentik?style=flat-square)](https://codecov.io/gh/goauthentik/authentik) ![Docker pulls](https://img.shields.io/docker/pulls/beryju/authentik.svg?style=flat-square) ![Latest version](https://img.shields.io/docker/v/beryju/authentik?sort=semver&style=flat-square) -![LGTM Grade](https://img.shields.io/lgtm/grade/python/github/BeryJu/authentik?style=flat-square) +![LGTM Grade](https://img.shields.io/lgtm/grade/python/github/goauthentik/authentik?style=flat-square) ## What is authentik? diff --git a/authentik/__init__.py b/authentik/__init__.py index 48be121bd..3a291052b 100644 --- a/authentik/__init__.py +++ b/authentik/__init__.py @@ -1,3 +1,3 @@ """authentik""" -__version__ = "2021.4.2" +__version__ = "2021.4.4" ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" diff --git a/authentik/admin/settings.py b/authentik/admin/settings.py index 57e0de6e6..3072c339e 100644 --- a/authentik/admin/settings.py +++ b/authentik/admin/settings.py @@ -4,7 +4,7 @@ from celery.schedules import crontab CELERY_BEAT_SCHEDULE = { "admin_latest_version": { "task": "authentik.admin.tasks.update_latest_version", - "schedule": crontab(minute=0), # Run every hour + "schedule": crontab(minute="*/60"), # Run every hour "options": {"queue": "authentik_scheduled"}, } } diff --git a/authentik/admin/tasks.py b/authentik/admin/tasks.py index bc20cf684..dcb52601a 100644 --- a/authentik/admin/tasks.py +++ b/authentik/admin/tasks.py @@ -23,7 +23,9 @@ URL_FINDER = URLValidator.regex.pattern[1:] def update_latest_version(self: MonitoredTask): """Update latest version info""" try: - response = get("https://api.github.com/repos/beryju/authentik/releases/latest") + response = get( + "https://api.github.com/repos/goauthentik/authentik/releases/latest" + ) response.raise_for_status() data = response.json() tag_name = data.get("tag_name") diff --git a/authentik/api/v2/urls.py b/authentik/api/v2/urls.py index 714ff9afe..0b71a2857 100644 --- a/authentik/api/v2/urls.py +++ b/authentik/api/v2/urls.py @@ -196,7 +196,8 @@ info = openapi.Info( default_version="v2beta", contact=openapi.Contact(email="hello@beryju.org"), license=openapi.License( - name="GNU GPLv3", url="https://github.com/BeryJu/authentik/blob/master/LICENSE" + name="GNU GPLv3", + url="https://github.com/goauthentik/authentik/blob/master/LICENSE", ), ) SchemaView = get_schema_view(info, public=True, permission_classes=(AllowAny,)) diff --git a/authentik/flows/views.py b/authentik/flows/views.py index 437857dff..c843a88a6 100644 --- a/authentik/flows/views.py +++ b/authentik/flows/views.py @@ -14,6 +14,7 @@ from drf_yasg import openapi from drf_yasg.utils import no_body, swagger_auto_schema from rest_framework.permissions import AllowAny from rest_framework.views import APIView +from sentry_sdk import capture_exception from structlog.stdlib import BoundLogger, get_logger from authentik.core.models import USER_ATTRIBUTE_DEBUG @@ -152,7 +153,8 @@ class FlowExecutorView(APIView): stage_response = self.current_stage_view.get(request, *args, **kwargs) return to_stage_response(request, stage_response) except Exception as exc: # pylint: disable=broad-except - self._logger.exception(exc) + capture_exception(exc) + self._logger.warning(exc) return to_stage_response(request, FlowErrorResponse(request, exc)) @swagger_auto_schema( @@ -180,7 +182,8 @@ class FlowExecutorView(APIView): stage_response = self.current_stage_view.post(request, *args, **kwargs) return to_stage_response(request, stage_response) except Exception as exc: # pylint: disable=broad-except - self._logger.exception(exc) + capture_exception(exc) + self._logger.warning(exc) return to_stage_response(request, FlowErrorResponse(request, exc)) def _initiate_plan(self) -> FlowPlan: diff --git a/authentik/lib/sentry.py b/authentik/lib/sentry.py index 0decc5f6c..df3704ba9 100644 --- a/authentik/lib/sentry.py +++ b/authentik/lib/sentry.py @@ -6,7 +6,7 @@ from billiard.exceptions import WorkerLostError from botocore.client import ClientError from celery.exceptions import CeleryError from channels_redis.core import ChannelFull -from django.core.exceptions import DisallowedHost, ValidationError +from django.core.exceptions import SuspiciousOperation, ValidationError from django.db import InternalError, OperationalError, ProgrammingError from django_redis.exceptions import ConnectionInterrupted from docker.errors import DockerException @@ -36,7 +36,7 @@ def before_send(event: dict, hint: dict) -> Optional[dict]: OperationalError, InternalError, ProgrammingError, - DisallowedHost, + SuspiciousOperation, ValidationError, # Redis errors RedisConnectionError, diff --git a/authentik/outposts/apps.py b/authentik/outposts/apps.py index 02cce0e16..ac93c2ab6 100644 --- a/authentik/outposts/apps.py +++ b/authentik/outposts/apps.py @@ -1,17 +1,8 @@ """authentik outposts app config""" from importlib import import_module -from os import R_OK, access -from os.path import expanduser -from pathlib import Path -from socket import gethostname -from urllib.parse import urlparse -import yaml from django.apps import AppConfig from django.db import ProgrammingError -from docker.constants import DEFAULT_UNIX_SOCKET -from kubernetes.config.incluster_config import SERVICE_TOKEN_FILENAME -from kubernetes.config.kube_config import KUBE_CONFIG_DEFAULT_LOCATION from structlog.stdlib import get_logger LOGGER = get_logger() @@ -27,49 +18,8 @@ class AuthentikOutpostConfig(AppConfig): def ready(self): import_module("authentik.outposts.signals") try: - AuthentikOutpostConfig.init_local_connection() + from authentik.outposts.tasks import outpost_local_connection + + outpost_local_connection.delay() except ProgrammingError: pass - - @staticmethod - def init_local_connection(): - """Check if local kubernetes or docker connections should be created""" - from authentik.outposts.models import ( - DockerServiceConnection, - KubernetesServiceConnection, - ) - - # Explicitly check against token filename, as thats - # only present when the integration is enabled - if Path(SERVICE_TOKEN_FILENAME).exists(): - LOGGER.debug("Detected in-cluster Kubernetes Config") - if not KubernetesServiceConnection.objects.filter(local=True).exists(): - LOGGER.debug("Created Service Connection for in-cluster") - KubernetesServiceConnection.objects.create( - name="Local Kubernetes Cluster", local=True, kubeconfig={} - ) - # For development, check for the existence of a kubeconfig file - kubeconfig_path = expanduser(KUBE_CONFIG_DEFAULT_LOCATION) - if Path(kubeconfig_path).exists(): - LOGGER.debug("Detected kubeconfig") - kubeconfig_local_name = f"k8s-{gethostname()}" - if not KubernetesServiceConnection.objects.filter( - name=kubeconfig_local_name - ).exists(): - LOGGER.debug("Creating kubeconfig Service Connection") - with open(kubeconfig_path, "r") as _kubeconfig: - KubernetesServiceConnection.objects.create( - name=kubeconfig_local_name, - kubeconfig=yaml.safe_load(_kubeconfig), - ) - unix_socket_path = urlparse(DEFAULT_UNIX_SOCKET).path - socket = Path(unix_socket_path) - if socket.exists() and access(socket, R_OK): - LOGGER.debug("Detected local docker socket") - if len(DockerServiceConnection.objects.filter(local=True)) == 0: - LOGGER.debug("Created Service Connection for docker") - DockerServiceConnection.objects.create( - name="Local Docker connection", - local=True, - url=unix_socket_path, - ) diff --git a/authentik/outposts/settings.py b/authentik/outposts/settings.py index f02d4fa2a..617274295 100644 --- a/authentik/outposts/settings.py +++ b/authentik/outposts/settings.py @@ -9,7 +9,7 @@ CELERY_BEAT_SCHEDULE = { }, "outposts_service_connection_check": { "task": "authentik.outposts.tasks.outpost_service_connection_monitor", - "schedule": crontab(minute=0, hour="*"), + "schedule": crontab(minute="*/60"), "options": {"queue": "authentik_scheduled"}, }, "outpost_token_ensurer": { @@ -17,4 +17,9 @@ CELERY_BEAT_SCHEDULE = { "schedule": crontab(minute="*/5"), "options": {"queue": "authentik_scheduled"}, }, + "outpost_local_connection": { + "task": "authentik.outposts.tasks.outpost_local_connection", + "schedule": crontab(minute="*/60"), + "options": {"queue": "authentik_scheduled"}, + }, } diff --git a/authentik/outposts/tasks.py b/authentik/outposts/tasks.py index 1c5426eb9..ece820add 100644 --- a/authentik/outposts/tasks.py +++ b/authentik/outposts/tasks.py @@ -1,11 +1,20 @@ """outpost tasks""" +from os import R_OK, access +from os.path import expanduser +from pathlib import Path +from socket import gethostname from typing import Any +from urllib.parse import urlparse +import yaml from asgiref.sync import async_to_sync from channels.layers import get_channel_layer from django.core.cache import cache from django.db.models.base import Model from django.utils.text import slugify +from docker.constants import DEFAULT_UNIX_SOCKET +from kubernetes.config.incluster_config import SERVICE_TOKEN_FILENAME +from kubernetes.config.kube_config import KUBE_CONFIG_DEFAULT_LOCATION from structlog.stdlib import get_logger from authentik.events.monitored_tasks import MonitoredTask, TaskResult, TaskResultStatus @@ -185,3 +194,42 @@ def _outpost_single_update(outpost: Outpost, layer=None): for state in OutpostState.for_outpost(outpost): LOGGER.debug("sending update", channel=state.uid, outpost=outpost) async_to_sync(layer.send)(state.uid, {"type": "event.update"}) + + +@CELERY_APP.task() +def outpost_local_connection(): + """Checks the local environment and create Service connections.""" + # Explicitly check against token filename, as thats + # only present when the integration is enabled + if Path(SERVICE_TOKEN_FILENAME).exists(): + LOGGER.debug("Detected in-cluster Kubernetes Config") + if not KubernetesServiceConnection.objects.filter(local=True).exists(): + LOGGER.debug("Created Service Connection for in-cluster") + KubernetesServiceConnection.objects.create( + name="Local Kubernetes Cluster", local=True, kubeconfig={} + ) + # For development, check for the existence of a kubeconfig file + kubeconfig_path = expanduser(KUBE_CONFIG_DEFAULT_LOCATION) + if Path(kubeconfig_path).exists(): + LOGGER.debug("Detected kubeconfig") + kubeconfig_local_name = f"k8s-{gethostname()}" + if not KubernetesServiceConnection.objects.filter( + name=kubeconfig_local_name + ).exists(): + LOGGER.debug("Creating kubeconfig Service Connection") + with open(kubeconfig_path, "r") as _kubeconfig: + KubernetesServiceConnection.objects.create( + name=kubeconfig_local_name, + kubeconfig=yaml.safe_load(_kubeconfig), + ) + unix_socket_path = urlparse(DEFAULT_UNIX_SOCKET).path + socket = Path(unix_socket_path) + if socket.exists() and access(socket, R_OK): + LOGGER.debug("Detected local docker socket") + if len(DockerServiceConnection.objects.filter(local=True)) == 0: + LOGGER.debug("Created Service Connection for docker") + DockerServiceConnection.objects.create( + name="Local Docker connection", + local=True, + url=unix_socket_path, + ) diff --git a/authentik/providers/oauth2/tests/test_views_authorize.py b/authentik/providers/oauth2/tests/test_views_authorize.py index 92435a484..cc2b5b82d 100644 --- a/authentik/providers/oauth2/tests/test_views_authorize.py +++ b/authentik/providers/oauth2/tests/test_views_authorize.py @@ -166,7 +166,7 @@ class TestViewsAuthorize(TestCase): name="test", client_id="test", authorization_flow=flow, - redirect_uris="http://localhost", + redirect_uris="foo://localhost", ) Application.objects.create(name="app", slug="app", provider=provider) state = generate_client_id() @@ -179,7 +179,7 @@ class TestViewsAuthorize(TestCase): "response_type": "code", "client_id": "test", "state": state, - "redirect_uri": "http://localhost", + "redirect_uri": "foo://localhost", }, ) response = self.client.get( @@ -190,7 +190,7 @@ class TestViewsAuthorize(TestCase): force_str(response.content), { "type": ChallengeTypes.REDIRECT.value, - "to": f"http://localhost?code={code.code}&state={state}", + "to": f"foo://localhost?code={code.code}&state={state}", }, ) diff --git a/authentik/providers/oauth2/tests/test_views_token.py b/authentik/providers/oauth2/tests/test_views_token.py index 5e4dcae64..d021b1a5e 100644 --- a/authentik/providers/oauth2/tests/test_views_token.py +++ b/authentik/providers/oauth2/tests/test_views_token.py @@ -153,10 +153,61 @@ class TestViewsToken(TestCase): "redirect_uri": "http://local.invalid", }, HTTP_AUTHORIZATION=f"Basic {header}", + HTTP_ORIGIN="http://local.invalid", ) new_token: RefreshToken = ( RefreshToken.objects.filter(user=user).exclude(pk=token.pk).first() ) + self.assertEqual(response["Access-Control-Allow-Credentials"], "true") + self.assertEqual( + response["Access-Control-Allow-Origin"], "http://local.invalid" + ) + self.assertJSONEqual( + force_str(response.content), + { + "access_token": new_token.access_token, + "refresh_token": new_token.refresh_token, + "token_type": "bearer", + "expires_in": 600, + "id_token": provider.encode( + new_token.id_token.to_dict(), + ), + }, + ) + + def test_refresh_token_view_invalid_origin(self): + """test request param""" + provider = OAuth2Provider.objects.create( + name="test", + client_id=generate_client_id(), + client_secret=generate_client_secret(), + authorization_flow=Flow.objects.first(), + redirect_uris="http://local.invalid", + ) + header = b64encode( + f"{provider.client_id}:{provider.client_secret}".encode() + ).decode() + user = User.objects.get(username="akadmin") + token: RefreshToken = RefreshToken.objects.create( + provider=provider, + user=user, + refresh_token=generate_client_id(), + ) + response = self.client.post( + reverse("authentik_providers_oauth2:token"), + data={ + "grant_type": GRANT_TYPE_REFRESH_TOKEN, + "refresh_token": token.refresh_token, + "redirect_uri": "http://local.invalid", + }, + HTTP_AUTHORIZATION=f"Basic {header}", + HTTP_ORIGIN="http://another.invalid", + ) + new_token: RefreshToken = ( + RefreshToken.objects.filter(user=user).exclude(pk=token.pk).first() + ) + self.assertNotIn("Access-Control-Allow-Credentials", response) + self.assertNotIn("Access-Control-Allow-Origin", response) self.assertJSONEqual( force_str(response.content), { diff --git a/authentik/providers/oauth2/utils.py b/authentik/providers/oauth2/utils.py index 919633788..a022ef04d 100644 --- a/authentik/providers/oauth2/utils.py +++ b/authentik/providers/oauth2/utils.py @@ -2,10 +2,11 @@ import re from base64 import b64decode from binascii import Error -from typing import Optional +from typing import Any, Optional from urllib.parse import urlparse from django.http import HttpRequest, HttpResponse, JsonResponse +from django.http.response import HttpResponseRedirect from django.utils.cache import patch_vary_headers from structlog.stdlib import get_logger @@ -26,8 +27,8 @@ class TokenResponse(JsonResponse): self["Pragma"] = "no-cache" -def cors_allow_any(request: HttpRequest, response: HttpResponse, *allowed_origins: str): - """Add headers to permit CORS requests from any origin, with or without credentials, +def cors_allow(request: HttpRequest, response: HttpResponse, *allowed_origins: str): + """Add headers to permit CORS requests from allowed_origins, with or without credentials, with any headers.""" origin = request.META.get("HTTP_ORIGIN") if not origin: @@ -161,3 +162,18 @@ def protected_resource_view(scopes: list[str]): return view_wrapper return wrapper + + +class HttpResponseRedirectScheme(HttpResponseRedirect): + """HTTP Response to redirect, can be to a non-http scheme""" + + def __init__( + self, + redirect_to: str, + *args: Any, + allowed_schemes: Optional[list[str]] = None, + **kwargs: Any, + ) -> None: + self.allowed_schemes = allowed_schemes or ["http", "https", "ftp"] + # pyright: reportGeneralTypeIssues=false + super().__init__(redirect_to, *args, **kwargs) diff --git a/authentik/providers/oauth2/views/authorize.py b/authentik/providers/oauth2/views/authorize.py index 538595ec0..12265f992 100644 --- a/authentik/providers/oauth2/views/authorize.py +++ b/authentik/providers/oauth2/views/authorize.py @@ -2,12 +2,12 @@ from dataclasses import dataclass, field from datetime import timedelta from typing import Optional -from urllib.parse import parse_qs, urlencode, urlsplit, urlunsplit +from urllib.parse import parse_qs, urlencode, urlparse, urlsplit, urlunsplit from uuid import uuid4 from django.http import HttpRequest, HttpResponse from django.http.response import Http404, HttpResponseBadRequest, HttpResponseRedirect -from django.shortcuts import get_object_or_404, redirect +from django.shortcuts import get_object_or_404 from django.utils import timezone from django.utils.translation import gettext as _ from structlog.stdlib import get_logger @@ -46,6 +46,7 @@ from authentik.providers.oauth2.models import ( OAuth2Provider, ResponseTypes, ) +from authentik.providers.oauth2.utils import HttpResponseRedirectScheme from authentik.providers.oauth2.views.userinfo import UserInfoView from authentik.stages.consent.models import ConsentMode, ConsentStage from authentik.stages.consent.stage import ( @@ -233,6 +234,11 @@ class OAuthFulfillmentStage(StageView): params: OAuthAuthorizationParams provider: OAuth2Provider + def redirect(self, uri: str) -> HttpResponse: + """Redirect using HttpResponseRedirectScheme, compatible with non-http schemes""" + parsed = urlparse(uri) + return HttpResponseRedirectScheme(uri, allowed_schemes=[parsed.scheme]) + # pylint: disable=unused-argument def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse: """final Stage of an OAuth2 Flow""" @@ -261,7 +267,7 @@ class OAuthFulfillmentStage(StageView): flow=self.executor.plan.flow_pk, scopes=", ".join(self.params.scope), ).from_http(self.request) - return redirect(self.create_response_uri()) + return self.redirect(self.create_response_uri()) except (ClientIdError, RedirectUriError) as error: error.to_event(application=application).from_http(request) self.executor.stage_invalid() @@ -270,7 +276,7 @@ class OAuthFulfillmentStage(StageView): except AuthorizeError as error: error.to_event(application=application).from_http(request) self.executor.stage_invalid() - return redirect(error.create_uri()) + return self.redirect(error.create_uri()) def create_response_uri(self) -> str: """Create a final Response URI the user is redirected to.""" @@ -304,7 +310,7 @@ class OAuthFulfillmentStage(StageView): return urlunsplit(uri) raise OAuth2Error() except OAuth2Error as error: - LOGGER.exception("Error when trying to create response uri", error=error) + LOGGER.warning("Error when trying to create response uri", error=error) raise AuthorizeError( self.params.redirect_uri, "server_error", diff --git a/authentik/providers/oauth2/views/provider.py b/authentik/providers/oauth2/views/provider.py index 3adb6c436..aafa69958 100644 --- a/authentik/providers/oauth2/views/provider.py +++ b/authentik/providers/oauth2/views/provider.py @@ -19,7 +19,7 @@ from authentik.providers.oauth2.models import ( ResponseTypes, ScopeMapping, ) -from authentik.providers.oauth2.utils import cors_allow_any +from authentik.providers.oauth2.utils import cors_allow LOGGER = get_logger() @@ -112,5 +112,5 @@ class ProviderInfoView(View): OAuth2Provider, pk=application.provider_id ) response = super().dispatch(request, *args, **kwargs) - cors_allow_any(request, response, *self.provider.redirect_uris.split("\n")) + cors_allow(request, response, *self.provider.redirect_uris.split("\n")) return response diff --git a/authentik/providers/oauth2/views/token.py b/authentik/providers/oauth2/views/token.py index 5360c0f9e..dc71beec9 100644 --- a/authentik/providers/oauth2/views/token.py +++ b/authentik/providers/oauth2/views/token.py @@ -19,7 +19,11 @@ from authentik.providers.oauth2.models import ( OAuth2Provider, RefreshToken, ) -from authentik.providers.oauth2.utils import TokenResponse, extract_client_auth +from authentik.providers.oauth2.utils import ( + TokenResponse, + cors_allow, + extract_client_auth, +) LOGGER = get_logger() @@ -154,7 +158,18 @@ class TokenParams: class TokenView(View): """Generate tokens for clients""" - params: TokenParams + params: Optional[TokenParams] = None + + def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: + response = super().dispatch(request, *args, **kwargs) + allowed_origins = [] + if self.params: + allowed_origins = self.params.provider.redirect_uris.split("\n") + cors_allow(self.request, response, *allowed_origins) + return response + + def options(self, request: HttpRequest) -> HttpResponse: + return TokenResponse({}) def post(self, request: HttpRequest) -> HttpResponse: """Generate tokens for clients""" diff --git a/authentik/providers/oauth2/views/userinfo.py b/authentik/providers/oauth2/views/userinfo.py index fe7d7e121..75f5135dd 100644 --- a/authentik/providers/oauth2/views/userinfo.py +++ b/authentik/providers/oauth2/views/userinfo.py @@ -14,7 +14,7 @@ from authentik.providers.oauth2.constants import ( SCOPE_GITHUB_USER_READ, ) from authentik.providers.oauth2.models import RefreshToken, ScopeMapping -from authentik.providers.oauth2.utils import TokenResponse, cors_allow_any +from authentik.providers.oauth2.utils import TokenResponse, cors_allow LOGGER = get_logger() @@ -88,7 +88,7 @@ class UserInfoView(View): allowed_origins = [] if self.token: allowed_origins = self.token.provider.redirect_uris.split("\n") - cors_allow_any(self.request, response, *allowed_origins) + cors_allow(self.request, response, *allowed_origins) return response def options(self, request: HttpRequest) -> HttpResponse: diff --git a/authentik/root/settings.py b/authentik/root/settings.py index eb6a99048..238f42b49 100644 --- a/authentik/root/settings.py +++ b/authentik/root/settings.py @@ -337,7 +337,7 @@ if CONFIG.y("postgresql.s3_backup"): # Sentry integration _ERROR_REPORTING = CONFIG.y_bool("error_reporting.enabled", False) -if not DEBUG and _ERROR_REPORTING: +if _ERROR_REPORTING: # pylint: disable=abstract-class-instantiated sentry_init( dsn="https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8", diff --git a/authentik/sources/ldap/settings.py b/authentik/sources/ldap/settings.py index 4acdfbfdf..850e9a04d 100644 --- a/authentik/sources/ldap/settings.py +++ b/authentik/sources/ldap/settings.py @@ -8,7 +8,7 @@ AUTHENTICATION_BACKENDS = [ CELERY_BEAT_SCHEDULE = { "sources_ldap_sync": { "task": "authentik.sources.ldap.tasks.ldap_sync_all", - "schedule": crontab(minute=0), # Run every hour + "schedule": crontab(minute="*/60"), # Run every hour "options": {"queue": "authentik_scheduled"}, } } diff --git a/authentik/sources/oauth/clients/base.py b/authentik/sources/oauth/clients/base.py index 533411ad0..c62bb285e 100644 --- a/authentik/sources/oauth/clients/base.py +++ b/authentik/sources/oauth/clients/base.py @@ -40,8 +40,11 @@ class BaseOAuthClient: def get_profile_info(self, token: dict[str, str]) -> Optional[dict[str, Any]]: "Fetch user profile information." + profile_url = self.source.type.profile_url or "" + if self.source.type.urls_customizable and self.source.profile_url: + profile_url = self.source.profile_url try: - response = self.do_request("get", self.source.profile_url, token=token) + response = self.do_request("get", profile_url, token=token) response.raise_for_status() except RequestException as exc: LOGGER.warning("Unable to fetch user profile", exc=exc) @@ -60,16 +63,16 @@ class BaseOAuthClient: args.update(additional) params = urlencode(args) LOGGER.info("redirect args", **args) - base_url = self.source.type.authorization_url - if self.source.authorization_url: - base_url = self.source.authorization_url - if base_url == "": + authorization_url = self.source.type.authorization_url or "" + if self.source.type.urls_customizable and self.source.authorization_url: + authorization_url = self.source.authorization_url + if authorization_url == "": Event.new( EventAction.CONFIGURATION_ERROR, source=self.source, message="Source has an empty authorization URL.", ).save() - return f"{base_url}?{params}" + return f"{authorization_url}?{params}" def parse_raw_token(self, raw_token: str) -> dict[str, Any]: "Parse token and secret from raw token response." diff --git a/authentik/sources/oauth/clients/oauth1.py b/authentik/sources/oauth/clients/oauth1.py index 5be26c5cc..771f4cbc5 100644 --- a/authentik/sources/oauth/clients/oauth1.py +++ b/authentik/sources/oauth/clients/oauth1.py @@ -28,8 +28,8 @@ class OAuthClient(BaseOAuthClient): if raw_token is not None and verifier is not None: token = self.parse_raw_token(raw_token) try: - access_token_url: str = self.source.type.access_token_url or "" - if self.source.access_token_url: + access_token_url = self.source.type.access_token_url or "" + if self.source.type.urls_customizable and self.source.access_token_url: access_token_url = self.source.access_token_url response = self.do_request( "post", @@ -51,8 +51,8 @@ class OAuthClient(BaseOAuthClient): "Fetch the OAuth request token. Only required for OAuth 1.0." callback = self.request.build_absolute_uri(self.callback) try: - request_token_url: str = self.source.type.request_token_url or "" - if self.source.request_token_url: + request_token_url = self.source.type.request_token_url or "" + if self.source.type.urls_customizable and self.source.request_token_url: request_token_url = self.source.request_token_url response = self.do_request( "post", diff --git a/authentik/sources/oauth/clients/oauth2.py b/authentik/sources/oauth/clients/oauth2.py index c6a6f4248..27443de2b 100644 --- a/authentik/sources/oauth/clients/oauth2.py +++ b/authentik/sources/oauth/clients/oauth2.py @@ -57,7 +57,7 @@ class OAuth2Client(BaseOAuthClient): return None try: access_token_url = self.source.type.access_token_url or "" - if self.source.access_token_url: + if self.source.type.urls_customizable and self.source.access_token_url: access_token_url = self.source.access_token_url response = self.session.request( "post", diff --git a/authentik/sources/oauth/types/azure_ad.py b/authentik/sources/oauth/types/azure_ad.py index 1e23516d4..fbd81f08f 100644 --- a/authentik/sources/oauth/types/azure_ad.py +++ b/authentik/sources/oauth/types/azure_ad.py @@ -1,5 +1,5 @@ """AzureAD OAuth2 Views""" -from typing import Any +from typing import Any, Optional from uuid import UUID from authentik.sources.oauth.models import OAuthSource, UserOAuthSourceConnection @@ -10,8 +10,11 @@ from authentik.sources.oauth.views.callback import OAuthCallback class AzureADOAuthCallback(OAuthCallback): """AzureAD OAuth2 Callback""" - def get_user_id(self, source: OAuthSource, info: dict[str, Any]) -> str: - return str(UUID(info.get("objectId")).int) + def get_user_id(self, source: OAuthSource, info: dict[str, Any]) -> Optional[str]: + try: + return str(UUID(info.get("objectId")).int) + except TypeError: + return None def get_user_enroll_context( self, diff --git a/authentik/sources/oauth/views/base.py b/authentik/sources/oauth/views/base.py index bfdd73faa..0ab379301 100644 --- a/authentik/sources/oauth/views/base.py +++ b/authentik/sources/oauth/views/base.py @@ -2,12 +2,15 @@ from typing import Optional, Type from django.http.request import HttpRequest +from structlog.stdlib import get_logger from authentik.sources.oauth.clients.base import BaseOAuthClient from authentik.sources.oauth.clients.oauth1 import OAuthClient from authentik.sources.oauth.clients.oauth2 import OAuth2Client from authentik.sources.oauth.models import OAuthSource +LOGGER = get_logger() + # pylint: disable=too-few-public-methods class OAuthClientMixin: @@ -22,6 +25,9 @@ class OAuthClientMixin: if self.client_class is not None: # pylint: disable=not-callable return self.client_class(source, self.request, **kwargs) - if source.request_token_url: - return OAuthClient(source, self.request, **kwargs) - return OAuth2Client(source, self.request, **kwargs) + if source.type.request_token_url or source.request_token_url: + client = OAuthClient(source, self.request, **kwargs) + else: + client = OAuth2Client(source, self.request, **kwargs) + LOGGER.debug("Using client for oauth request", client=client) + return client diff --git a/authentik/sources/saml/processors/response.py b/authentik/sources/saml/processors/response.py index 74793ba8d..8ecb62e95 100644 --- a/authentik/sources/saml/processors/response.py +++ b/authentik/sources/saml/processors/response.py @@ -39,13 +39,13 @@ from authentik.sources.saml.processors.constants import ( from authentik.sources.saml.processors.request import SESSION_REQUEST_ID from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND from authentik.stages.prompt.stage import PLAN_CONTEXT_PROMPT +from authentik.stages.user_login.stage import DEFAULT_BACKEND LOGGER = get_logger() if TYPE_CHECKING: from xml.etree.ElementTree import Element # nosec CACHE_SEEN_REQUEST_ID = "authentik_saml_seen_ids_%s" -DEFAULT_BACKEND = "django.contrib.auth.backends.ModelBackend" class ResponseProcessor: diff --git a/authentik/stages/identification/stage.py b/authentik/stages/identification/stage.py index 87f416789..fb56cc21b 100644 --- a/authentik/stages/identification/stage.py +++ b/authentik/stages/identification/stage.py @@ -1,5 +1,6 @@ """Identification stage logic""" from dataclasses import asdict +from time import sleep from typing import Optional from django.db.models import Q @@ -46,6 +47,7 @@ class IdentificationChallengeResponse(ChallengeResponse): """Validate that user exists""" pre_user = self.stage.get_user(value) if not pre_user: + sleep(0.150) LOGGER.debug("invalid_login", identifier=value) raise ValidationError("Failed to authenticate.") self.pre_user = pre_user @@ -68,7 +70,7 @@ class IdentificationStageView(ChallengeStageView): else: model_field += "__exact" query |= Q(**{model_field: uid_value}) - users = User.objects.filter(query) + users = User.objects.filter(query, is_active=True) if users.exists(): LOGGER.debug("Found user", user=users.first(), query=query) return users.first() diff --git a/authentik/stages/user_login/stage.py b/authentik/stages/user_login/stage.py index bc9601066..13881d073 100644 --- a/authentik/stages/user_login/stage.py +++ b/authentik/stages/user_login/stage.py @@ -11,6 +11,7 @@ from authentik.lib.utils.time import timedelta_from_string from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND LOGGER = get_logger() +DEFAULT_BACKEND = "django.contrib.auth.backends.ModelBackend" class UserLoginStageView(StageView): @@ -23,12 +24,9 @@ class UserLoginStageView(StageView): messages.error(request, message) LOGGER.debug(message) return self.executor.stage_invalid() - if PLAN_CONTEXT_AUTHENTICATION_BACKEND not in self.executor.plan.context: - message = _("Pending user has no backend.") - messages.error(request, message) - LOGGER.debug(message) - return self.executor.stage_invalid() - backend = self.executor.plan.context[PLAN_CONTEXT_AUTHENTICATION_BACKEND] + backend = self.executor.plan.context.get( + PLAN_CONTEXT_AUTHENTICATION_BACKEND, DEFAULT_BACKEND + ) login( self.request, self.executor.plan.context[PLAN_CONTEXT_PENDING_USER], diff --git a/authentik/stages/user_login/tests.py b/authentik/stages/user_login/tests.py index b2e636802..98da7ab45 100644 --- a/authentik/stages/user_login/tests.py +++ b/authentik/stages/user_login/tests.py @@ -12,7 +12,6 @@ from authentik.flows.models import Flow, FlowDesignation, FlowStageBinding from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan from authentik.flows.tests.test_views import TO_STAGE_RESPONSE_MOCK from authentik.flows.views import SESSION_KEY_PLAN -from authentik.stages.password.stage import PLAN_CONTEXT_AUTHENTICATION_BACKEND from authentik.stages.user_login.models import UserLoginStage @@ -38,9 +37,6 @@ class TestUserLoginStage(TestCase): flow_pk=self.flow.pk.hex, stages=[self.stage], markers=[StageMarker()] ) plan.context[PLAN_CONTEXT_PENDING_USER] = self.user - plan.context[ - PLAN_CONTEXT_AUTHENTICATION_BACKEND - ] = "django.contrib.auth.backends.ModelBackend" session = self.client.session session[SESSION_KEY_PLAN] = plan session.save() @@ -82,32 +78,3 @@ class TestUserLoginStage(TestCase): "type": ChallengeTypes.NATIVE.value, }, ) - - @patch( - "authentik.flows.views.to_stage_response", - TO_STAGE_RESPONSE_MOCK, - ) - def test_without_backend(self): - """Test a plan with pending user, without backend, resulting in a denied""" - plan = FlowPlan( - flow_pk=self.flow.pk.hex, stages=[self.stage], markers=[StageMarker()] - ) - plan.context[PLAN_CONTEXT_PENDING_USER] = self.user - session = self.client.session - session[SESSION_KEY_PLAN] = plan - session.save() - - response = self.client.get( - reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}) - ) - - self.assertEqual(response.status_code, 200) - self.assertJSONEqual( - force_str(response.content), - { - "component": "ak-stage-access-denied", - "error_message": None, - "title": "", - "type": ChallengeTypes.NATIVE.value, - }, - ) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 54490ff0d..80539fae6 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -369,8 +369,6 @@ stages: coverage-unittest/unittest.xml mergeTestResults: true - task: CmdLine@2 - env: - CODECOV_TOKEN: $(CODECOV_TOKEN) inputs: script: bash <(curl -s https://codecov.io/bash) - stage: Build diff --git a/docker-compose.yml b/docker-compose.yml index 49838df91..932e03d2d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -20,7 +20,7 @@ services: networks: - internal server: - image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.4.2} + image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.4.4} restart: unless-stopped command: server environment: @@ -48,7 +48,7 @@ services: env_file: - .env worker: - image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.4.2} + image: ${AUTHENTIK_IMAGE:-beryju/authentik}:${AUTHENTIK_TAG:-2021.4.4} restart: unless-stopped command: worker networks: @@ -68,7 +68,7 @@ services: env_file: - .env static: - image: ${AUTHENTIK_IMAGE_STATIC:-beryju/authentik-static}:${AUTHENTIK_TAG:-2021.4.2} + image: ${AUTHENTIK_IMAGE_STATIC:-beryju/authentik-static}:${AUTHENTIK_TAG:-2021.4.4} restart: unless-stopped networks: - internal diff --git a/helm/Chart.yaml b/helm/Chart.yaml index 9924f6a21..8507e293d 100644 --- a/helm/Chart.yaml +++ b/helm/Chart.yaml @@ -3,9 +3,9 @@ description: authentik is an open-source Identity Provider focused on flexibilit name: authentik home: https://goauthentik.io sources: - - https://github.com/BeryJu/authentik -version: "2021.4.2" -icon: https://raw.githubusercontent.com/BeryJu/authentik/master/web/icons/icon.svg + - https://github.com/goauthentik/authentik +version: "2021.4.4" +icon: https://raw.githubusercontent.com/goauthentik/authentik/master/web/icons/icon.svg dependencies: - name: postgresql version: 9.4.1 diff --git a/helm/README.md b/helm/README.md index 167a1a484..fbb2aadb2 100644 --- a/helm/README.md +++ b/helm/README.md @@ -4,7 +4,7 @@ |-----------------------------------|-------------------------|-------------| | image.name | beryju/authentik | Image used to run the authentik server and worker | | image.name_static | beryju/authentik-static | Image used to run the authentik static server (CSS and JS Files) | -| image.tag | 2021.4.2 | Image tag | +| image.tag | 2021.4.4 | Image tag | | image.pullPolicy | IfNotPresent | Image Pull Policy used for all deployments | | serverReplicas | 1 | Replicas for the Server deployment | | workerReplicas | 1 | Replicas for the Worker deployment | diff --git a/helm/values.yaml b/helm/values.yaml index f911a53b5..640cd8d83 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -5,7 +5,7 @@ image: name: beryju/authentik name_static: beryju/authentik-static name_outposts: beryju/authentik # Prefix used for Outpost deployments, Outpost type and version is appended - tag: 2021.4.2 + tag: 2021.4.4 pullPolicy: IfNotPresent serverReplicas: 1 diff --git a/outpost/README.md b/outpost/README.md index 1df7663b6..ead8007f8 100644 --- a/outpost/README.md +++ b/outpost/README.md @@ -1,6 +1,6 @@ # authentik outpost -[![CI Build status](https://img.shields.io/azure-devops/build/beryjuorg/authentik/3?style=flat-square)](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=3) +[![CI Build status](https://img.shields.io/azure-devops/build/beryjuorg/authentik/3?style=flat-square)](https://dev.azure.com/beryjuorg/authentik/_build?definitionId=8) ![Docker pulls (proxy)](https://img.shields.io/docker/pulls/beryju/authentik-proxy.svg?style=flat-square) Reverse Proxy based on [oauth2_proxy](https://github.com/oauth2-proxy/oauth2-proxy), completely managed and monitored by authentik. diff --git a/outpost/pkg/ak/api.go b/outpost/pkg/ak/api.go index d8d0a8d14..c4ead9265 100644 --- a/outpost/pkg/ak/api.go +++ b/outpost/pkg/ak/api.go @@ -31,8 +31,7 @@ type APIController struct { Server Outpost - lastBundleHash string - logger *log.Entry + logger *log.Entry reloadOffset time.Duration @@ -71,18 +70,12 @@ func NewAPIController(akURL url.URL, token string) *APIController { logger: log, reloadOffset: time.Duration(rand.Intn(10)) * time.Second, - - lastBundleHash: "", } ac.logger.Debugf("HA Reload offset: %s", ac.reloadOffset) ac.initWS(akURL, outpost.Pk) return ac } -func (a *APIController) GetLastBundleHash() string { - return a.lastBundleHash -} - // Start Starts all handlers, non-blocking func (a *APIController) Start() error { err := a.Server.Refresh() diff --git a/outpost/pkg/ak/api_update.go b/outpost/pkg/ak/api_update.go index d3211ef1b..48dbbd1db 100644 --- a/outpost/pkg/ak/api_update.go +++ b/outpost/pkg/ak/api_update.go @@ -1,10 +1,6 @@ package ak import ( - "crypto/sha512" - "encoding/hex" - "encoding/json" - "goauthentik.io/outpost/pkg/client/outposts" "goauthentik.io/outpost/pkg/models" ) @@ -15,16 +11,5 @@ func (a *APIController) Update() ([]*models.ProxyOutpostConfig, error) { a.logger.WithError(err).Error("Failed to fetch providers") return nil, err } - // Check provider hash to see if anything is changed - hasher := sha512.New() - out, err := json.Marshal(providers.Payload.Results) - if err != nil { - return nil, nil - } - hash := hex.EncodeToString(hasher.Sum(out)) - if hash == a.lastBundleHash { - return nil, nil - } - a.lastBundleHash = hash return providers.Payload.Results, nil } diff --git a/outpost/pkg/ak/api_ws.go b/outpost/pkg/ak/api_ws.go index 851266aa9..235247ec1 100644 --- a/outpost/pkg/ak/api_ws.go +++ b/outpost/pkg/ak/api_ws.go @@ -15,9 +15,9 @@ import ( "goauthentik.io/outpost/pkg" ) -func (ac *APIController) initWS(pbURL url.URL, outpostUUID strfmt.UUID) { +func (ac *APIController) initWS(akURL url.URL, outpostUUID strfmt.UUID) { pathTemplate := "%s://%s/ws/outpost/%s/" - scheme := strings.ReplaceAll(pbURL.Scheme, "http", "ws") + scheme := strings.ReplaceAll(akURL.Scheme, "http", "ws") authHeader := fmt.Sprintf("Bearer %s", ac.token) @@ -37,7 +37,7 @@ func (ac *APIController) initWS(pbURL url.URL, outpostUUID strfmt.UUID) { InsecureSkipVerify: strings.ToLower(value) == "true", }, } - ws.Dial(fmt.Sprintf(pathTemplate, scheme, pbURL.Host, outpostUUID.String()), header) + ws.Dial(fmt.Sprintf(pathTemplate, scheme, akURL.Host, outpostUUID.String()), header) ac.logger.WithField("logger", "authentik.outpost.ak-ws").WithField("outpost", outpostUUID.String()).Debug("connecting to authentik") diff --git a/outpost/pkg/proxy/middleware.go b/outpost/pkg/proxy/middleware.go index 3e9e924fc..7c938ea77 100644 --- a/outpost/pkg/proxy/middleware.go +++ b/outpost/pkg/proxy/middleware.go @@ -107,7 +107,7 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { duration := float64(time.Since(t)) / float64(time.Millisecond) h.logger.WithFields(log.Fields{ "host": req.RemoteAddr, - "vhost": req.Host, + "vhost": getHost(req), "request_protocol": req.Proto, "runtime": fmt.Sprintf("%0.3f", duration), "method": req.Method, diff --git a/outpost/pkg/proxy/oauth.go b/outpost/pkg/proxy/oauth.go index 9ee0bcadd..9d1d894fa 100644 --- a/outpost/pkg/proxy/oauth.go +++ b/outpost/pkg/proxy/oauth.go @@ -161,7 +161,7 @@ func (p *OAuthProxy) OAuthStart(rw http.ResponseWriter, req *http.Request) { p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", err.Error()) return } - redirectURI := p.GetRedirectURI(req.Host) + redirectURI := p.GetRedirectURI(getHost(req)) http.Redirect(rw, req, p.provider.GetLoginURL(redirectURI, fmt.Sprintf("%v:%v", nonce, redirect)), http.StatusFound) } @@ -184,7 +184,7 @@ func (p *OAuthProxy) OAuthCallback(rw http.ResponseWriter, req *http.Request) { return } - session, err := p.redeemCode(req.Context(), req.Host, req.Form.Get("code")) + session, err := p.redeemCode(req.Context(), getHost(req), req.Form.Get("code")) if err != nil { p.logger.Errorf("Error redeeming code during OAuth2 callback: %v", err) p.ErrorPage(rw, http.StatusInternalServerError, "Internal Server Error", "Internal Error") diff --git a/outpost/pkg/proxy/server.go b/outpost/pkg/proxy/server.go index e01dbee95..44a355b51 100644 --- a/outpost/pkg/proxy/server.go +++ b/outpost/pkg/proxy/server.go @@ -42,7 +42,8 @@ func (s *Server) handler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(204) return } - handler, ok := s.Handlers[r.Host] + host := getHost(r) + handler, ok := s.Handlers[host] if !ok { // If we only have one handler, host name switching doesn't matter if len(s.Handlers) == 1 { @@ -56,7 +57,7 @@ func (s *Server) handler(w http.ResponseWriter, r *http.Request) { for k := range s.Handlers { hostKeys = append(hostKeys, k) } - s.logger.WithField("host", r.Host).WithField("known-hosts", strings.Join(hostKeys, ", ")).Debug("Host header does not match any we know of") + s.logger.WithField("host", host).WithField("known-hosts", strings.Join(hostKeys, ", ")).Debug("Host header does not match any we know of") w.WriteHeader(404) return } diff --git a/outpost/pkg/proxy/utils.go b/outpost/pkg/proxy/utils.go new file mode 100644 index 000000000..d9e4602a9 --- /dev/null +++ b/outpost/pkg/proxy/utils.go @@ -0,0 +1,12 @@ +package proxy + +import "net/http" + +var xForwardedHost = http.CanonicalHeaderKey("X-Forwarded-Host") + +func getHost(req *http.Request) string { + if req.Header.Get(xForwardedHost) != "" { + return req.Header.Get(xForwardedHost) + } + return req.Host +} diff --git a/outpost/pkg/version.go b/outpost/pkg/version.go index 74e4aa4a0..11d1a3651 100644 --- a/outpost/pkg/version.go +++ b/outpost/pkg/version.go @@ -1,3 +1,3 @@ package pkg -const VERSION = "2021.4.2" +const VERSION = "2021.4.4" diff --git a/swagger.yaml b/swagger.yaml index 584cb99fd..a505326de 100755 --- a/swagger.yaml +++ b/swagger.yaml @@ -5,7 +5,7 @@ info: email: hello@beryju.org license: name: GNU GPLv3 - url: https://github.com/BeryJu/authentik/blob/master/LICENSE + url: https://github.com/goauthentik/authentik/blob/master/LICENSE version: v2beta basePath: /api/v2beta consumes: diff --git a/tests/e2e/test_provider_proxy.py b/tests/e2e/test_provider_proxy.py index 1e5554eaf..cbced9b70 100644 --- a/tests/e2e/test_provider_proxy.py +++ b/tests/e2e/test_provider_proxy.py @@ -13,13 +13,13 @@ from selenium.webdriver.common.by import By from authentik import __version__ from authentik.core.models import Application from authentik.flows.models import Flow -from authentik.outposts.apps import AuthentikOutpostConfig from authentik.outposts.models import ( DockerServiceConnection, Outpost, OutpostConfig, OutpostType, ) +from authentik.outposts.tasks import outpost_local_connection from authentik.providers.proxy.models import ProxyProvider from tests.e2e.utils import SeleniumTestCase, apply_migration, object_manager, retry @@ -117,7 +117,7 @@ class TestProviderProxyConnect(ChannelsLiveServerTestCase): @object_manager def test_proxy_connectivity(self): """Test proxy connectivity over websocket""" - AuthentikOutpostConfig.init_local_connection() + outpost_local_connection() proxy: ProxyProvider = ProxyProvider.objects.create( name="proxy_provider", authorization_flow=Flow.objects.get( diff --git a/tests/e2e/test_source_oauth.py b/tests/e2e/test_source_oauth.py index c3646a7f7..faeeea221 100644 --- a/tests/e2e/test_source_oauth.py +++ b/tests/e2e/test_source_oauth.py @@ -4,6 +4,7 @@ from sys import platform from time import sleep from typing import Any, Optional from unittest.case import skipUnless +from unittest.mock import Mock, patch from django.test import override_settings from docker.models.containers import Container @@ -22,12 +23,31 @@ from authentik.providers.oauth2.generators import ( generate_client_secret, ) from authentik.sources.oauth.models import OAuthSource +from authentik.sources.oauth.types.manager import SourceType +from authentik.sources.oauth.types.twitter import TwitterOAuthCallback from tests.e2e.utils import SeleniumTestCase, apply_migration, object_manager, retry CONFIG_PATH = "/tmp/dex.yml" # nosec LOGGER = get_logger() +class OAUth1Type(SourceType): + """Twitter Type definition""" + + callback_view = TwitterOAuthCallback + name = "Twitter" + slug = "twitter" + + request_token_url = "http://localhost:5000/oauth/request_token" # nosec + access_token_url = "http://localhost:5000/oauth/access_token" # nosec + authorization_url = "http://localhost:5000/oauth/authorize" + profile_url = "http://localhost:5000/api/me" + urls_customizable = False + + +SOURCE_TYPE_MOCK = Mock(return_value=OAUth1Type()) + + @skipUnless(platform.startswith("linux"), "requires local docker") class TestSourceOAuth2(SeleniumTestCase): """test OAuth Source flow""" @@ -291,10 +311,6 @@ class TestSourceOAuth1(SeleniumTestCase): authentication_flow=authentication_flow, enrollment_flow=enrollment_flow, provider_type="twitter", - request_token_url="http://localhost:5000/oauth/request_token", - access_token_url="http://localhost:5000/oauth/access_token", - authorization_url="http://localhost:5000/oauth/authorize", - profile_url="http://localhost:5000/api/me", consumer_key=self.client_id, consumer_secret=self.client_secret, ) @@ -304,6 +320,10 @@ class TestSourceOAuth1(SeleniumTestCase): @apply_migration("authentik_flows", "0008_default_flows") @apply_migration("authentik_flows", "0009_source_flows") @apply_migration("authentik_crypto", "0002_create_self_signed_kp") + @patch( + "authentik.sources.oauth.types.manager.SourceTypeManager.find_type", + SOURCE_TYPE_MOCK, + ) @object_manager def test_oauth_enroll(self): """test OAuth Source With With OIDC""" diff --git a/tests/integration/test_outpost_docker.py b/tests/integration/test_outpost_docker.py index 8a1c4dc69..82cdfe84c 100644 --- a/tests/integration/test_outpost_docker.py +++ b/tests/integration/test_outpost_docker.py @@ -12,9 +12,9 @@ from docker.types.healthcheck import Healthcheck from authentik import __version__ from authentik.crypto.models import CertificateKeyPair from authentik.flows.models import Flow -from authentik.outposts.apps import AuthentikOutpostConfig from authentik.outposts.controllers.docker import DockerController from authentik.outposts.models import DockerServiceConnection, Outpost, OutpostType +from authentik.outposts.tasks import outpost_local_connection from authentik.providers.proxy.models import ProxyProvider @@ -53,7 +53,7 @@ class OutpostDockerTests(TestCase): self.ssl_folder = mkdtemp() self.container = self._start_container(self.ssl_folder) # Ensure that local connection have been created - AuthentikOutpostConfig.init_local_connection() + outpost_local_connection() self.provider: ProxyProvider = ProxyProvider.objects.create( name="test", internal_host="http://localhost", diff --git a/tests/integration/test_outpost_kubernetes.py b/tests/integration/test_outpost_kubernetes.py index 99345849c..a82261854 100644 --- a/tests/integration/test_outpost_kubernetes.py +++ b/tests/integration/test_outpost_kubernetes.py @@ -3,11 +3,11 @@ from django.test import TestCase from authentik.flows.models import Flow from authentik.lib.config import CONFIG -from authentik.outposts.apps import AuthentikOutpostConfig from authentik.outposts.controllers.k8s.base import NeedsUpdate from authentik.outposts.controllers.k8s.deployment import DeploymentReconciler from authentik.outposts.controllers.kubernetes import KubernetesController from authentik.outposts.models import KubernetesServiceConnection, Outpost, OutpostType +from authentik.outposts.tasks import outpost_local_connection from authentik.providers.proxy.models import ProxyProvider @@ -17,7 +17,7 @@ class OutpostKubernetesTests(TestCase): def setUp(self): super().setUp() # Ensure that local connection have been created - AuthentikOutpostConfig.init_local_connection() + outpost_local_connection() self.provider: ProxyProvider = ProxyProvider.objects.create( name="test", internal_host="http://localhost", diff --git a/tests/integration/test_proxy_docker.py b/tests/integration/test_proxy_docker.py index 532810230..b52bb8c73 100644 --- a/tests/integration/test_proxy_docker.py +++ b/tests/integration/test_proxy_docker.py @@ -12,8 +12,8 @@ from docker.types.healthcheck import Healthcheck from authentik import __version__ from authentik.crypto.models import CertificateKeyPair from authentik.flows.models import Flow -from authentik.outposts.apps import AuthentikOutpostConfig from authentik.outposts.models import DockerServiceConnection, Outpost, OutpostType +from authentik.outposts.tasks import outpost_local_connection from authentik.providers.proxy.controllers.docker import DockerController from authentik.providers.proxy.models import ProxyProvider @@ -53,7 +53,7 @@ class TestProxyDocker(TestCase): self.ssl_folder = mkdtemp() self.container = self._start_container(self.ssl_folder) # Ensure that local connection have been created - AuthentikOutpostConfig.init_local_connection() + outpost_local_connection() self.provider: ProxyProvider = ProxyProvider.objects.create( name="test", internal_host="http://localhost", diff --git a/tests/integration/test_proxy_kubernetes.py b/tests/integration/test_proxy_kubernetes.py index 61b9a92aa..11b319696 100644 --- a/tests/integration/test_proxy_kubernetes.py +++ b/tests/integration/test_proxy_kubernetes.py @@ -3,8 +3,8 @@ import yaml from django.test import TestCase from authentik.flows.models import Flow -from authentik.outposts.apps import AuthentikOutpostConfig from authentik.outposts.models import KubernetesServiceConnection, Outpost, OutpostType +from authentik.outposts.tasks import outpost_local_connection from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController from authentik.providers.proxy.models import ProxyProvider @@ -14,7 +14,7 @@ class TestProxyKubernetes(TestCase): def setUp(self): # Ensure that local connection have been created - AuthentikOutpostConfig.init_local_connection() + outpost_local_connection() def test_kubernetes_controller_static(self): """Test Kubernetes Controller""" diff --git a/web/nginx.conf b/web/nginx.conf index e992b7ce6..39292954a 100644 --- a/web/nginx.conf +++ b/web/nginx.conf @@ -81,7 +81,7 @@ http { location /static/ { expires 31d; add_header Cache-Control "public, no-transform"; - add_header X-authentik-version "2021.4.2"; + add_header X-authentik-version "2021.4.4"; add_header Vary X-authentik-version; } diff --git a/web/package-lock.json b/web/package-lock.json index bdcbda6d8..54017ddd0 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -26,19 +26,19 @@ "integrity": "sha512-3eJJ841uKxeV8dcN/2yGEUy+RfgQspPEgQat85umsE1rotuquQ2AbIub4S6j7c50a2d+4myc+zSlnXeIHrOnhQ==" }, "@babel/core": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.15.tgz", - "integrity": "sha512-6GXmNYeNjS2Uz+uls5jalOemgIhnTMeaXo+yBUA72kC2uX/8VW6XyhVIo2L8/q0goKQA3EVKx0KOQpVKSeWadQ==", + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.13.16.tgz", + "integrity": "sha512-sXHpixBiWWFti0AV2Zq7avpTasr6sIAu7Y396c608541qAU2ui4a193m0KSQmfPSKFZLnQ3cvlKDOm3XkuXm3Q==", "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", - "@babel/helper-compilation-targets": "^7.13.13", + "@babel/generator": "^7.13.16", + "@babel/helper-compilation-targets": "^7.13.16", "@babel/helper-module-transforms": "^7.13.14", - "@babel/helpers": "^7.13.10", - "@babel/parser": "^7.13.15", + "@babel/helpers": "^7.13.16", + "@babel/parser": "^7.13.16", "@babel/template": "^7.12.13", "@babel/traverse": "^7.13.15", - "@babel/types": "^7.13.14", + "@babel/types": "^7.13.16", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -55,6 +55,32 @@ "@babel/highlight": "^7.12.13" } }, + "@babel/compat-data": { + "version": "7.13.15", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.13.15.tgz", + "integrity": "sha512-ltnibHKR1VnrU4ymHyQ/CXtNXI6yZC0oJThyW78Hft8XndANwi+9H+UIklBDraIjFEJzw8wmcM427oDd9KS5wA==" + }, + "@babel/generator": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", + "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", + "requires": { + "@babel/types": "^7.13.16", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", + "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + } + }, "@babel/helper-validator-identifier": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", @@ -71,25 +97,34 @@ } }, "@babel/parser": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.15.tgz", - "integrity": "sha512-b9COtcAlVEQljy/9fbcMHpG+UIW9ReF+gpaxDHTlZd0c6/UU9ng8zdySAW9sRTzpvcdCHn6bUcbuYUgGzLAWVQ==" + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", + "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==" }, "@babel/traverse": { - "version": "7.13.15", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.15.tgz", - "integrity": "sha512-/mpZMNvj6bce59Qzl09fHEs8Bt8NnpEDQYleHUPZQ3wXUMvXi+HJPLars68oAbmp839fGoOkv2pSL2z9ajCIaQ==", + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", + "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", "requires": { "@babel/code-frame": "^7.12.13", - "@babel/generator": "^7.13.9", + "@babel/generator": "^7.13.16", "@babel/helper-function-name": "^7.12.13", "@babel/helper-split-export-declaration": "^7.12.13", - "@babel/parser": "^7.13.15", - "@babel/types": "^7.13.14", + "@babel/parser": "^7.13.16", + "@babel/types": "^7.13.17", "debug": "^4.1.0", "globals": "^11.1.0" } }, + "@babel/types": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", + "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "to-fast-properties": "^2.0.0" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -355,13 +390,87 @@ } }, "@babel/helpers": { - "version": "7.13.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.10.tgz", - "integrity": "sha512-4VO883+MWPDUVRF3PhiLBUFHoX/bsLTGFpFK/HqvvfBZz2D57u9XzPVNFVBTc0PW/CWR9BXTOKt8NF4DInUHcQ==", + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.13.17.tgz", + "integrity": "sha512-Eal4Gce4kGijo1/TGJdqp3WuhllaMLSrW6XcL0ulyUAQOuxHcCafZE8KHg9857gcTehsm/v7RcOx2+jp0Ryjsg==", "requires": { "@babel/template": "^7.12.13", - "@babel/traverse": "^7.13.0", - "@babel/types": "^7.13.0" + "@babel/traverse": "^7.13.17", + "@babel/types": "^7.13.17" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/generator": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.13.16.tgz", + "integrity": "sha512-grBBR75UnKOcUWMp8WoDxNsWCFl//XCK6HWTrBQKTr5SV9f5g0pNOjdyzi/DTBv12S9GnYPInIXQBTky7OXEMg==", + "requires": { + "@babel/types": "^7.13.16", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" + }, + "@babel/highlight": { + "version": "7.13.10", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.13.10.tgz", + "integrity": "sha512-5aPpe5XQPzflQrFwL1/QoeHkP2MsA4JCntcXHRhEsdsfPVkvPi2w7Qix4iV7t5S/oC9OodGrggd8aco1g3SZFg==", + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.16.tgz", + "integrity": "sha512-6bAg36mCwuqLO0hbR+z7PHuqWiCeP7Dzg73OpQwsAB1Eb8HnGEz5xYBzCfbu+YjoaJsJs+qheDxVAuqbt3ILEw==" + }, + "@babel/traverse": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.13.17.tgz", + "integrity": "sha512-BMnZn0R+X6ayqm3C3To7o1j7Q020gWdqdyP50KEoVqaCO2c/Im7sYZSmVgvefp8TTMQ+9CtwuBp0Z1CZ8V3Pvg==", + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.13.16", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.13.16", + "@babel/types": "^7.13.17", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.13.17", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.17.tgz", + "integrity": "sha512-RawydLgxbOPDlTLJNtoIypwdmAy//uQIzlKt2+iBiJaRlVuI6QLUxVAyWGNfOzp8Yu4L4lLIacoCyTNtpb4wiA==", + "requires": { + "@babel/helper-validator-identifier": "^7.12.11", + "to-fast-properties": "^2.0.0" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + } } }, "@babel/highlight": { @@ -1336,86 +1445,28 @@ } }, "@lingui/babel-plugin-extract-messages": { - "version": "3.8.9", - "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.8.9.tgz", - "integrity": "sha512-zPpSl89nvUrLyGHfVosZHCP9fylfCfkEMc29wGdjE6f0U+frJ59NRLilWMy7xaE8uz97cD5vkhYaaF1wnavhxA==", + "version": "3.8.10", + "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.8.10.tgz", + "integrity": "sha512-16EnNRb1HXNjdDLMY3xS7jh0wKA00x21LC1CIKRAki80u92jvkSMOJYk+lD6yhdrcl0dH5OMAbdluAm1+rpEPw==", "requires": { "@babel/generator": "^7.11.6", "@babel/runtime": "^7.11.2", - "@lingui/conf": "^3.8.9", + "@lingui/conf": "^3.8.10", "mkdirp": "^1.0.4" - }, - "dependencies": { - "@lingui/conf": { - "version": "3.8.9", - "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.8.9.tgz", - "integrity": "sha512-r0RGchwiALjCE6CSOtOKbOqVrNg1EQ78AXjyvbrtJoPWVlChDasWCckXEF0BSnsoZaRP6nQCAI+dsQiGW1deWg==", - "requires": { - "@babel/runtime": "^7.11.2", - "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", - "chalk": "^4.1.0", - "cosmiconfig": "^7.0.0", - "jest-validate": "^26.5.2", - "lodash.get": "^4.4.2" - } - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { - "has-flag": "^4.0.0" - } - } } }, "@lingui/cli": { - "version": "3.8.9", - "resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.8.9.tgz", - "integrity": "sha512-UccLtfwrTjXrZcTxpqA4ggYhuUMbXZtzbUVks8nDVt3emVqU56C3VMvVD8WKXLL8Qmq9cEDXPwIZy7IKRL4mEQ==", + "version": "3.8.10", + "resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.8.10.tgz", + "integrity": "sha512-YLkT5e6JRwVcXEwLD0++/m1p/wvRQbLj/+m8geXfrcFfrsQyT3uhHNZRFK0GdsjyDslSqJYbalYibJUbgC2sOA==", "requires": { "@babel/generator": "^7.11.6", "@babel/parser": "^7.11.5", "@babel/plugin-syntax-jsx": "^7.10.4", "@babel/runtime": "^7.11.2", "@babel/types": "^7.11.5", - "@lingui/babel-plugin-extract-messages": "^3.8.9", - "@lingui/conf": "^3.8.9", + "@lingui/babel-plugin-extract-messages": "^3.8.10", + "@lingui/conf": "^3.8.10", "babel-plugin-macros": "^3.0.1", "bcp-47": "^1.0.7", "chalk": "^4.1.0", @@ -1442,19 +1493,6 @@ "ramda": "^0.27.1" }, "dependencies": { - "@lingui/conf": { - "version": "3.8.9", - "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.8.9.tgz", - "integrity": "sha512-r0RGchwiALjCE6CSOtOKbOqVrNg1EQ78AXjyvbrtJoPWVlChDasWCckXEF0BSnsoZaRP6nQCAI+dsQiGW1deWg==", - "requires": { - "@babel/runtime": "^7.11.2", - "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", - "chalk": "^4.1.0", - "cosmiconfig": "^7.0.0", - "jest-validate": "^26.5.2", - "lodash.get": "^4.4.2" - } - }, "ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -1531,9 +1569,9 @@ } }, "@lingui/conf": { - "version": "3.8.9", - "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.8.9.tgz", - "integrity": "sha512-r0RGchwiALjCE6CSOtOKbOqVrNg1EQ78AXjyvbrtJoPWVlChDasWCckXEF0BSnsoZaRP6nQCAI+dsQiGW1deWg==", + "version": "3.8.10", + "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.8.10.tgz", + "integrity": "sha512-4KdH+23WXZ5g+LRlvvise3z3mdd41zLgqSJ/PUCMGk60RfElvTrTdxpnm2tOF/2hr+OyGCQEy6kLq606y639qw==", "requires": { "@babel/runtime": "^7.11.2", "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", @@ -1589,9 +1627,9 @@ } }, "@lingui/core": { - "version": "3.8.9", - "resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.8.9.tgz", - "integrity": "sha512-QmEfgukR7w/4/4USZT0LGNt7Yq/RgirFl4088wEta0vgroidxaCRgUXr8RXcdFVjTdtG5dc86JTEj4inZECKvg==", + "version": "3.8.10", + "resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.8.10.tgz", + "integrity": "sha512-1OzZW8iP5yAXxz49pY/WZ1acLvkekd6HgDh8zH3jMA2Hbig2jk6VGVERMO7lwEwJiyEuxaQpe8fRrhCTB7wA3A==", "requires": { "@babel/runtime": "^7.11.2", "make-plural": "^6.2.2", @@ -1599,12 +1637,12 @@ } }, "@lingui/macro": { - "version": "3.8.9", - "resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.8.9.tgz", - "integrity": "sha512-9LhlbkJ9wOtOLhlaVRLHCRL55S5wOFyyqEhUM+ujUmCskTmMmXzjnRsw5f11nJTK1JJETMT/VlUB5/p7D7Edkw==", + "version": "3.8.10", + "resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.8.10.tgz", + "integrity": "sha512-oZZ/F7HsNQkDsnHFroxzGFuEIXM624H72RIj8j2ClpR64nt+xYDxXYC6TYFicQLtBGcKKBTBoM+zbDaoIv74qQ==", "requires": { "@babel/runtime": "^7.11.2", - "@lingui/conf": "^3.8.9", + "@lingui/conf": "^3.8.10", "ramda": "^0.27.1" } }, @@ -1828,13 +1866,13 @@ } }, "@sentry/browser": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.2.5.tgz", - "integrity": "sha512-nlvaE+D7oaj4MxoY9ikw+krQDOjftnDYJQnOwOraXPk7KYM6YwmkakLuE+x/AkaH3FQVTQF330VAa9d6SWETlA==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.3.0.tgz", + "integrity": "sha512-Rse9j5XwN9n7GnfW1mNscTS4YQ0oiBNJcaSk3Mw/vQT872Wh60yKyx5wxAw5GujFZI0NgdyPlZwZ/tGQwirRxA==", "requires": { - "@sentry/core": "6.2.5", - "@sentry/types": "6.2.5", - "@sentry/utils": "6.2.5", + "@sentry/core": "6.3.0", + "@sentry/types": "6.3.0", + "@sentry/utils": "6.3.0", "tslib": "^1.9.3" }, "dependencies": { @@ -1846,14 +1884,14 @@ } }, "@sentry/core": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.2.5.tgz", - "integrity": "sha512-I+AkgIFO6sDUoHQticP6I27TT3L+i6TUS03in3IEtpBcSeP2jyhlxI8l/wdA7gsBqUPdQ4GHOOaNgtFIcr8qag==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.3.0.tgz", + "integrity": "sha512-voot/lJ9gRXB6bx6tVqbEbD6jOd4Sx6Rfmm6pzfpom9C0q+fjIZTatTLq8GdXj8DzxaH1MBDSwtaq/eC3NqYpA==", "requires": { - "@sentry/hub": "6.2.5", - "@sentry/minimal": "6.2.5", - "@sentry/types": "6.2.5", - "@sentry/utils": "6.2.5", + "@sentry/hub": "6.3.0", + "@sentry/minimal": "6.3.0", + "@sentry/types": "6.3.0", + "@sentry/utils": "6.3.0", "tslib": "^1.9.3" }, "dependencies": { @@ -1865,12 +1903,12 @@ } }, "@sentry/hub": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.2.5.tgz", - "integrity": "sha512-YlEFdEhcfqpl2HC+/dWXBsBJEljyMzFS7LRRjCk8QANcOdp9PhwQjwebUB4/ulOBjHPP2WZk7fBBd/IKDasTUg==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.3.0.tgz", + "integrity": "sha512-lAnW3Om66t9IR+t1wya1NpOF9lGbvYG6Ca8wxJJGJ1t2PxKwyxpZKzRx0q8M1QFhlZ5cETCzxmM7lBEZ4QVCBg==", "requires": { - "@sentry/types": "6.2.5", - "@sentry/utils": "6.2.5", + "@sentry/types": "6.3.0", + "@sentry/utils": "6.3.0", "tslib": "^1.9.3" }, "dependencies": { @@ -1882,12 +1920,12 @@ } }, "@sentry/minimal": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.2.5.tgz", - "integrity": "sha512-RKP4Qx3p7Cv0oX1cPKAkNVFYM7p2k1t32cNk1+rrVQS4hwlJ7Eg6m6fsqsO+85jd6Ne/FnyYsfo9cDD3ImTlWQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.3.0.tgz", + "integrity": "sha512-ZdPUwdPQkaKroy67NkwQRqmnfKyd/C1OyouM9IqYKyBjAInjOijwwc/Rd91PMHalvCOGfp1scNZYbZ+YFs/qQQ==", "requires": { - "@sentry/hub": "6.2.5", - "@sentry/types": "6.2.5", + "@sentry/hub": "6.3.0", + "@sentry/types": "6.3.0", "tslib": "^1.9.3" }, "dependencies": { @@ -1899,17 +1937,51 @@ } }, "@sentry/tracing": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.2.5.tgz", - "integrity": "sha512-j/hM0BoHxfrNLxPeEJ5Vq4R34hO/TOHMEpLR3FdnunBXbsmjoKMMygIkPxnpML5XWtvukAehbwpDXldwMYz83w==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.3.0.tgz", + "integrity": "sha512-3UNGgQOrDKBoDqLc4vt+0n27Zv3lbNEoCbBydq4IvGfuYq7ozWMsaTcelsotMsd4ckDuOEh8V/nJTqrDjvL76g==", "requires": { - "@sentry/hub": "6.2.5", - "@sentry/minimal": "6.2.5", - "@sentry/types": "6.2.5", - "@sentry/utils": "6.2.5", + "@sentry/hub": "6.3.0", + "@sentry/minimal": "6.3.0", + "@sentry/types": "6.3.0", + "@sentry/utils": "6.3.0", "tslib": "^1.9.3" }, "dependencies": { + "@sentry/hub": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.3.0.tgz", + "integrity": "sha512-lAnW3Om66t9IR+t1wya1NpOF9lGbvYG6Ca8wxJJGJ1t2PxKwyxpZKzRx0q8M1QFhlZ5cETCzxmM7lBEZ4QVCBg==", + "requires": { + "@sentry/types": "6.3.0", + "@sentry/utils": "6.3.0", + "tslib": "^1.9.3" + } + }, + "@sentry/minimal": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.3.0.tgz", + "integrity": "sha512-ZdPUwdPQkaKroy67NkwQRqmnfKyd/C1OyouM9IqYKyBjAInjOijwwc/Rd91PMHalvCOGfp1scNZYbZ+YFs/qQQ==", + "requires": { + "@sentry/hub": "6.3.0", + "@sentry/types": "6.3.0", + "tslib": "^1.9.3" + } + }, + "@sentry/types": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.3.0.tgz", + "integrity": "sha512-xWyCYDmFPjS5ex60kxOOHbHEs4vs00qHbm0iShQfjl4OSg9S2azkcWofDmX8Xbn0FSOUXgdPCjNJW1B0bPVhCA==" + }, + "@sentry/utils": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.3.0.tgz", + "integrity": "sha512-NZzw4oLelgvCsVBG2e+ZtFtaBvgA7rZYtcGFbZTphhAlYoJ6JMCQUzYk0iwJK79yR1quh510x4UE0jynvvToWg==", + "requires": { + "@sentry/types": "6.3.0", + "tslib": "^1.9.3" + } + }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -1918,16 +1990,16 @@ } }, "@sentry/types": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.2.5.tgz", - "integrity": "sha512-1Sux6CLYrV9bETMsGP/HuLFLouwKoX93CWzG8BjMueW+Di0OGxZphYjXrGuDs8xO8bAKEVGCHgVQdcB2jevS0w==" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.3.0.tgz", + "integrity": "sha512-xWyCYDmFPjS5ex60kxOOHbHEs4vs00qHbm0iShQfjl4OSg9S2azkcWofDmX8Xbn0FSOUXgdPCjNJW1B0bPVhCA==" }, "@sentry/utils": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.2.5.tgz", - "integrity": "sha512-fJoLUZHrd5MPylV1dT4qL74yNFDl1Ur/dab+pKNSyvnHPnbZ/LRM7aJ8VaRY/A7ZdpRowU+E14e/Yeem2c6gtQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.3.0.tgz", + "integrity": "sha512-NZzw4oLelgvCsVBG2e+ZtFtaBvgA7rZYtcGFbZTphhAlYoJ6JMCQUzYk0iwJK79yR1quh510x4UE0jynvvToWg==", "requires": { - "@sentry/types": "6.2.5", + "@sentry/types": "6.3.0", "tslib": "^1.9.3" }, "dependencies": { @@ -2775,9 +2847,9 @@ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=" }, "codemirror": { - "version": "5.60.0", - "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.60.0.tgz", - "integrity": "sha512-AEL7LhFOlxPlCL8IdTcJDblJm8yrAGib7I+DErJPdZd4l6imx8IMgKK3RblVgBQqz3TZJR4oknQ03bz+uNjBYA==" + "version": "5.61.0", + "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.61.0.tgz", + "integrity": "sha512-D3wYH90tYY1BsKlUe0oNj2JAhQ9TepkD51auk3N7q+4uz7A/cgJ5JsWHreT0PqieW1QhOuqxQ2reCXV1YXzecg==" }, "collection-visit": { "version": "1.0.0", @@ -2921,9 +2993,9 @@ } }, "date-fns": { - "version": "2.20.1", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.20.1.tgz", - "integrity": "sha512-8P5M8Kxbnovd0zfvOs7ipkiVJ3/zZQ0F/nrBW4x5E+I0uAZVZ80h6CKd24fSXQ5TLK5hXMtI4yb2O5rEZdUt2A==" + "version": "2.21.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.21.1.tgz", + "integrity": "sha512-m1WR0xGiC6j6jNFAyW4Nvh4WxAi4JF4w9jRJwSI8nBmNcyZXPcP9VUQG+6gHQXAmqaGEKDKhOqAtENDC941UkA==" }, "debug": { "version": "4.3.1", diff --git a/web/package.json b/web/package.json index 4e5bd2601..f75c35cd8 100644 --- a/web/package.json +++ b/web/package.json @@ -35,23 +35,23 @@ ] }, "dependencies": { - "@babel/core": "^7.13.15", + "@babel/core": "^7.13.16", "@babel/plugin-proposal-decorators": "^7.13.15", "@babel/plugin-transform-runtime": "^7.13.15", "@babel/preset-env": "^7.13.15", "@babel/preset-typescript": "^7.13.0", "@fortawesome/fontawesome-free": "^5.15.3", - "@lingui/cli": "^3.8.9", - "@lingui/core": "^3.8.9", - "@lingui/macro": "^3.8.9", + "@lingui/cli": "^3.8.10", + "@lingui/core": "^3.8.10", + "@lingui/macro": "^3.8.10", "@patternfly/patternfly": "^4.96.2", "@polymer/iron-form": "^3.0.1", "@polymer/paper-input": "^3.2.1", "@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-replace": "^2.4.2", "@rollup/plugin-typescript": "^8.2.1", - "@sentry/browser": "^6.2.5", - "@sentry/tracing": "^6.2.5", + "@sentry/browser": "^6.3.0", + "@sentry/tracing": "^6.3.0", "@types/chart.js": "^2.9.32", "@types/codemirror": "0.0.109", "@types/grecaptcha": "^3.0.1", @@ -62,7 +62,7 @@ "base64-js": "^1.5.1", "chart.js": "^3.1.1", "chartjs-adapter-moment": "^1.0.0", - "codemirror": "^5.60.0", + "codemirror": "^5.61.0", "construct-style-sheets-polyfill": "^2.4.16", "eslint": "^7.24.0", "eslint-config-google": "^0.14.0", diff --git a/web/security.txt b/web/security.txt index 54de4014a..8e62db8c1 100644 --- a/web/security.txt +++ b/web/security.txt @@ -1,4 +1,4 @@ Contact: mailto:security@beryju.org Expires: Sat, 1 Jan 2022 00:00 +0200 Preferred-Languages: en, de -Policy: https://github.com/BeryJu/authentik/blob/master/SECURITY.md \ No newline at end of file +Policy: https://github.com/goauthentik/authentik/blob/master/SECURITY.md diff --git a/web/src/api/Config.ts b/web/src/api/Config.ts index 7a47ed0d4..488e758bf 100644 --- a/web/src/api/Config.ts +++ b/web/src/api/Config.ts @@ -1,4 +1,4 @@ -import { Configuration, Middleware, ResponseContext } from "authentik-api"; +import { Config, Configuration, Middleware, ResponseContext, RootApi } from "authentik-api"; import { getCookie } from "../utils"; import { API_DRAWER_MIDDLEWARE } from "../elements/notifications/APIDrawer"; import { MessageMiddleware } from "../elements/messages/Middleware"; @@ -12,6 +12,14 @@ export class LoggingMiddleware implements Middleware { } +let globalConfigPromise: Promise; +export function config(): Promise { + if (!globalConfigPromise) { + globalConfigPromise = new RootApi(DEFAULT_CONFIG).rootConfigList(); + } + return globalConfigPromise; +} + export const DEFAULT_CONFIG = new Configuration({ basePath: "/api/v2beta", headers: { diff --git a/web/src/api/Sentry.ts b/web/src/api/Sentry.ts index 8b3f304d1..ef7f9f2e4 100644 --- a/web/src/api/Sentry.ts +++ b/web/src/api/Sentry.ts @@ -2,12 +2,12 @@ import * as Sentry from "@sentry/browser"; import { Integrations } from "@sentry/tracing"; import { VERSION } from "../constants"; import { SentryIgnoredError } from "../common/errors"; -import { Config, RootApi } from "authentik-api"; import { me } from "./Users"; -import { DEFAULT_CONFIG } from "./Config"; +import { config } from "./Config"; +import { Config } from "authentik-api"; export function configureSentry(): Promise { - return new RootApi(DEFAULT_CONFIG).rootConfigList().then((config) => { + return config().then((config) => { if (config.errorReportingEnabled) { Sentry.init({ dsn: "https://a579bb09306d4f8b8d8847c052d3a1d3@sentry.beryju.org/8", @@ -19,10 +19,19 @@ export function configureSentry(): Promise { ], tracesSampleRate: 0.6, environment: config.errorReportingEnvironment, - beforeSend(event: Sentry.Event, hint: Sentry.EventHint) { + beforeSend: async (event: Sentry.Event, hint: Sentry.EventHint): Promise => { if (hint.originalException instanceof SentryIgnoredError) { return null; } + if (hint.originalException instanceof Response) { + const response = hint.originalException as Response; + // We only care about server errors + if (response.status < 500) { + return null; + } + const body = await response.json(); + event.message = `${response.status} ${response.url}: ${JSON.stringify(body)}` + } if (event.exception) { me().then(user => { Sentry.showReportDialog({ diff --git a/web/src/api/Users.ts b/web/src/api/Users.ts index 64c30b16b..a0201c7cc 100644 --- a/web/src/api/Users.ts +++ b/web/src/api/Users.ts @@ -1,15 +1,21 @@ import { CoreApi, SessionUser } from "authentik-api"; import { DEFAULT_CONFIG } from "./Config"; -let _globalMePromise: Promise; +let globalMePromise: Promise; export function me(): Promise { - if (!_globalMePromise) { - _globalMePromise = new CoreApi(DEFAULT_CONFIG).coreUsersMe().catch((ex) => { + if (!globalMePromise) { + globalMePromise = new CoreApi(DEFAULT_CONFIG).coreUsersMe().catch((ex) => { + const defaultUser: SessionUser = { + user: { + username: "", + name: "" + } + }; if (ex.status === 401 || ex.status === 403) { window.location.assign("/"); } - return ex; + return defaultUser; }); } - return _globalMePromise; + return globalMePromise; } diff --git a/web/src/constants.ts b/web/src/constants.ts index e726de6e7..09c5208e8 100644 --- a/web/src/constants.ts +++ b/web/src/constants.ts @@ -3,11 +3,11 @@ export const SUCCESS_CLASS = "pf-m-success"; export const ERROR_CLASS = "pf-m-danger"; export const PROGRESS_CLASS = "pf-m-in-progress"; export const CURRENT_CLASS = "pf-m-current"; -export const VERSION = "2021.4.2"; +export const VERSION = "2021.4.4"; export const PAGE_SIZE = 20; export const EVENT_REFRESH = "ak-refresh"; export const EVENT_NOTIFICATION_TOGGLE = "ak-notification-toggle"; export const EVENT_SIDEBAR_TOGGLE = "ak-sidebar-toggle"; export const EVENT_API_DRAWER_REFRESH = "ak-api-drawer-refresh"; -export const TITLE_SUFFIX = "authentik"; +export const TITLE_DEFAULT = "authentik"; export const ROUTE_SEPARATOR = ";"; diff --git a/web/src/elements/PageHeader.ts b/web/src/elements/PageHeader.ts index 87cc379b6..7be03f728 100644 --- a/web/src/elements/PageHeader.ts +++ b/web/src/elements/PageHeader.ts @@ -4,7 +4,8 @@ import PFContent from "@patternfly/patternfly/components/Content/content.css"; import AKGlobal from "../authentik.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFButton from "@patternfly/patternfly/components/Button/button.css"; -import { EVENT_SIDEBAR_TOGGLE, TITLE_SUFFIX } from "../constants"; +import { EVENT_SIDEBAR_TOGGLE, TITLE_DEFAULT } from "../constants"; +import { config } from "../api/Config"; @customElement("ak-page-header") export class PageHeader extends LitElement { @@ -17,11 +18,13 @@ export class PageHeader extends LitElement { @property() set header(value: string) { - if (value !== "") { - document.title = `${value} - ${TITLE_SUFFIX}`; - } else { - document.title = TITLE_SUFFIX; - } + config().then(config => { + if (value !== "") { + document.title = `${value} - ${config.brandingTitle}`; + } else { + document.title = config.brandingTitle || TITLE_DEFAULT; + } + }); this._header = value; } diff --git a/web/src/flows/FlowExecutor.ts b/web/src/flows/FlowExecutor.ts index 24a87fc98..2e44b01e7 100644 --- a/web/src/flows/FlowExecutor.ts +++ b/web/src/flows/FlowExecutor.ts @@ -36,13 +36,14 @@ import { AuthenticatorValidateStageChallenge } from "./stages/authenticator_vali import { WebAuthnAuthenticatorRegisterChallenge } from "./stages/authenticator_webauthn/WebAuthnAuthenticatorRegisterStage"; import { CaptchaChallenge } from "./stages/captcha/CaptchaStage"; import { StageHost } from "./stages/base"; -import { Challenge, ChallengeTypeEnum, Config, FlowsApi, RootApi } from "authentik-api"; -import { DEFAULT_CONFIG } from "../api/Config"; +import { Challenge, ChallengeTypeEnum, Config, FlowsApi } from "authentik-api"; +import { config, DEFAULT_CONFIG } from "../api/Config"; import { ifDefined } from "lit-html/directives/if-defined"; import { until } from "lit-html/directives/until"; import { AccessDeniedChallenge } from "./access_denied/FlowAccessDenied"; import { PFSize } from "../elements/Spinner"; -import { TITLE_SUFFIX } from "../constants"; +import { TITLE_DEFAULT } from "../constants"; +import { configureSentry } from "../api/Sentry"; @customElement("ak-flow-executor") export class FlowExecutor extends LitElement implements StageHost { @@ -98,11 +99,13 @@ export class FlowExecutor extends LitElement implements StageHost { } private postUpdate(): void { - if (this.challenge?.title) { - document.title = `${this.challenge.title} - ${TITLE_SUFFIX}`; - } else { - document.title = TITLE_SUFFIX; - } + config().then(config => { + if (this.challenge?.title) { + document.title = `${this.challenge.title} - ${config.brandingTitle}`; + } else { + document.title = config.brandingTitle || TITLE_DEFAULT; + } + }); } submit(formData?: T): Promise { @@ -124,7 +127,7 @@ export class FlowExecutor extends LitElement implements StageHost { } firstUpdated(): void { - new RootApi(DEFAULT_CONFIG).rootConfigList().then((config) => { + configureSentry().then((config) => { this.config = config; }); this.loading = true; diff --git a/web/src/locales/en.po b/web/src/locales/en.po index cb5893738..aaa1f86a9 100644 --- a/web/src/locales/en.po +++ b/web/src/locales/en.po @@ -13,7 +13,7 @@ msgstr "" "Language-Team: \n" "Plural-Forms: \n" -#: src/pages/policies/BoundPoliciesList.ts:55 +#: src/pages/policies/BoundPoliciesList.ts:59 msgid "-" msgstr "-" @@ -64,7 +64,7 @@ msgstr "API Requests" msgid "API request failed" msgstr "API request failed" -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:87 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:88 msgid "Access Key" msgstr "Access Key" @@ -105,8 +105,8 @@ msgstr "Additional group DN, prepended to the Base DN." msgid "Additional user DN, prepended to the Base DN." msgstr "Additional user DN, prepended to the Base DN." -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:131 -#: src/pages/providers/proxy/ProxyProviderForm.ts:128 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:132 +#: src/pages/providers/proxy/ProxyProviderForm.ts:130 #: src/pages/providers/saml/SAMLProviderForm.ts:117 #: src/pages/sources/saml/SAMLSourceForm.ts:134 msgid "Advanced protocol settings" @@ -125,7 +125,7 @@ msgstr "Affected model:" msgid "Alert" msgstr "Alert" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:152 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:153 msgid "Algorithm used to sign the JWT Tokens." msgstr "Algorithm used to sign the JWT Tokens." @@ -259,7 +259,7 @@ msgstr "Attempted to log in as {0}" msgid "Attribute name used for SAML Assertions. Can be a URN OID, a schema reference, or a any other string. If this property mapping is used for NameID Property, this field is discarded." msgstr "Attribute name used for SAML Assertions. Can be a URN OID, a schema reference, or a any other string. If this property mapping is used for NameID Property, this field is discarded." -#: src/pages/groups/GroupForm.ts:135 +#: src/pages/groups/GroupForm.ts:134 #: src/pages/stages/invitation/InvitationForm.ts:52 #: src/pages/users/UserForm.ts:77 msgid "Attributes" @@ -293,7 +293,7 @@ msgid "Authorization Code" msgstr "Authorization Code" #: src/pages/sources/oauth/OAuthSourceForm.ts:66 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:95 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:96 msgid "Authorization URL" msgstr "Authorization URL" @@ -342,19 +342,19 @@ msgstr "Backup status" msgid "Base DN" msgstr "Base DN" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:204 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:203 msgid "Based on the Hashed User ID" msgstr "Based on the Hashed User ID" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:210 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:209 msgid "Based on the User's Email. This is recommended over the UPN method." msgstr "Based on the User's Email. This is recommended over the UPN method." -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:213 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:212 msgid "Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains." msgstr "Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains." -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:207 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:206 msgid "Based on the username" msgstr "Based on the username" @@ -405,7 +405,7 @@ msgstr "Cached Flows" msgid "Cached Policies" msgstr "Cached Policies" -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:79 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:80 msgid "Callback URL" msgstr "Callback URL" @@ -426,7 +426,7 @@ msgid "Case insensitive matching" msgstr "Case insensitive matching" #: src/pages/crypto/CertificateKeyPairForm.ts:51 -#: src/pages/providers/proxy/ProxyProviderForm.ts:132 +#: src/pages/providers/proxy/ProxyProviderForm.ts:134 msgid "Certificate" msgstr "Certificate" @@ -472,7 +472,7 @@ msgstr "Change your password" #: src/pages/providers/proxy/ProxyProviderViewPage.ts:135 #: src/pages/providers/saml/SAMLProviderViewPage.ts:129 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:113 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:132 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:133 #: src/pages/sources/saml/SAMLSourceViewPage.ts:119 #: src/pages/users/UserViewPage.ts:185 msgid "Changelog" @@ -596,7 +596,7 @@ msgstr "Configure WebAuthn" msgid "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected." msgstr "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected." -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:242 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:241 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." @@ -604,7 +604,7 @@ msgstr "Configure how the issuer field of the ID Token should be filled." msgid "Configure settings relevant to your user profile." msgstr "Configure settings relevant to your user profile." -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:217 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:216 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." @@ -660,8 +660,8 @@ msgstr "Consumer secret" #: src/pages/events/EventInfo.ts:79 #: src/pages/events/EventInfo.ts:148 #: src/pages/events/EventInfo.ts:167 -#: src/pages/policies/PolicyTestForm.ts:74 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:63 +#: src/pages/policies/PolicyTestForm.ts:75 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:65 msgid "Context" msgstr "Context" @@ -708,15 +708,15 @@ msgstr "Copy Key" #: src/pages/flows/BoundStagesList.ts:167 #: src/pages/flows/FlowListPage.ts:109 #: src/pages/flows/FlowListPage.ts:117 -#: src/pages/groups/GroupListPage.ts:91 -#: src/pages/groups/GroupListPage.ts:99 +#: src/pages/groups/GroupListPage.ts:90 +#: src/pages/groups/GroupListPage.ts:98 #: src/pages/outposts/OutpostListPage.ts:101 #: src/pages/outposts/OutpostListPage.ts:109 #: src/pages/outposts/ServiceConnectionListPage.ts:110 #: src/pages/outposts/ServiceConnectionListPage.ts:119 -#: src/pages/policies/BoundPoliciesList.ts:158 -#: src/pages/policies/BoundPoliciesList.ts:185 -#: src/pages/policies/BoundPoliciesList.ts:206 +#: src/pages/policies/BoundPoliciesList.ts:162 +#: src/pages/policies/BoundPoliciesList.ts:189 +#: src/pages/policies/BoundPoliciesList.ts:210 #: src/pages/policies/PolicyListPage.ts:124 #: src/pages/policies/PolicyListPage.ts:133 #: src/pages/property-mappings/PropertyMappingListPage.ts:113 @@ -747,10 +747,10 @@ msgstr "Create" msgid "Create Application" msgstr "Create Application" -#: src/pages/policies/BoundPoliciesList.ts:161 -#: src/pages/policies/BoundPoliciesList.ts:166 -#: src/pages/policies/BoundPoliciesList.ts:209 -#: src/pages/policies/BoundPoliciesList.ts:214 +#: src/pages/policies/BoundPoliciesList.ts:165 +#: src/pages/policies/BoundPoliciesList.ts:170 +#: src/pages/policies/BoundPoliciesList.ts:213 +#: src/pages/policies/BoundPoliciesList.ts:218 msgid "Create Binding" msgstr "Create Binding" @@ -762,7 +762,7 @@ msgstr "Create Certificate-Key Pair" msgid "Create Flow" msgstr "Create Flow" -#: src/pages/groups/GroupListPage.ts:94 +#: src/pages/groups/GroupListPage.ts:93 msgid "Create Group" msgstr "Create Group" @@ -786,7 +786,7 @@ msgstr "Create Notification Transport" msgid "Create Outpost" msgstr "Create Outpost" -#: src/pages/policies/BoundPoliciesList.ts:176 +#: src/pages/policies/BoundPoliciesList.ts:180 msgid "Create Policy" msgstr "Create Policy" @@ -819,7 +819,7 @@ msgstr "Create provider" #: src/pages/applications/ApplicationForm.ts:123 #: src/pages/flows/BoundStagesList.ts:149 #: src/pages/outposts/ServiceConnectionListPage.ts:122 -#: src/pages/policies/BoundPoliciesList.ts:188 +#: src/pages/policies/BoundPoliciesList.ts:192 #: src/pages/policies/PolicyListPage.ts:136 #: src/pages/property-mappings/PropertyMappingListPage.ts:125 #: src/pages/providers/ProviderListPage.ts:119 @@ -873,7 +873,7 @@ msgstr "Define how notifications are sent to users, like Email or Webhook." #: src/pages/events/RuleListPage.ts:82 #: src/pages/events/TransportListPage.ts:86 #: src/pages/flows/FlowListPage.ts:86 -#: src/pages/groups/GroupListPage.ts:82 +#: src/pages/groups/GroupListPage.ts:81 #: src/pages/outposts/OutpostListPage.ts:87 #: src/pages/outposts/ServiceConnectionListPage.ts:101 #: src/pages/policies/PolicyListPage.ts:115 @@ -895,7 +895,7 @@ msgid "Delete Authorization Code" msgstr "Delete Authorization Code" #: src/pages/flows/BoundStagesList.ts:91 -#: src/pages/policies/BoundPoliciesList.ts:145 +#: src/pages/policies/BoundPoliciesList.ts:149 msgid "Delete Binding" msgstr "Delete Binding" @@ -1010,7 +1010,7 @@ msgstr "Download" msgid "Dummy stage used for testing. Shows a simple continue button and always passes." msgstr "Dummy stage used for testing. Shows a simple continue button and always passes." -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:235 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:234 msgid "Each provider has a different issuer, based on the application slug." msgstr "Each provider has a different issuer, based on the application slug." @@ -1021,7 +1021,7 @@ msgstr "Each provider has a different issuer, based on the application slug." #: src/pages/events/RuleListPage.ts:70 #: src/pages/events/TransportListPage.ts:74 #: src/pages/flows/FlowListPage.ts:74 -#: src/pages/groups/GroupListPage.ts:70 +#: src/pages/groups/GroupListPage.ts:69 #: src/pages/outposts/OutpostListPage.ts:75 #: src/pages/outposts/ServiceConnectionListPage.ts:89 #: src/pages/policies/PolicyListPage.ts:90 @@ -1032,7 +1032,7 @@ msgstr "Each provider has a different issuer, based on the application slug." #: src/pages/providers/saml/SAMLProviderViewPage.ts:121 #: src/pages/sources/SourcesListPage.ts:82 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:105 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:124 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:125 #: src/pages/sources/saml/SAMLSourceViewPage.ts:111 #: src/pages/stages/StageListPage.ts:98 #: src/pages/stages/prompt/PromptListPage.ts:75 @@ -1043,15 +1043,15 @@ msgid "Edit" msgstr "Edit" #: src/pages/flows/BoundStagesList.ts:79 -#: src/pages/policies/BoundPoliciesList.ts:133 +#: src/pages/policies/BoundPoliciesList.ts:137 msgid "Edit Binding" msgstr "Edit Binding" -#: src/pages/policies/BoundPoliciesList.ts:92 +#: src/pages/policies/BoundPoliciesList.ts:96 msgid "Edit Group" msgstr "Edit Group" -#: src/pages/policies/BoundPoliciesList.ts:77 +#: src/pages/policies/BoundPoliciesList.ts:81 msgid "Edit Policy" msgstr "Edit Policy" @@ -1059,7 +1059,7 @@ msgstr "Edit Policy" msgid "Edit Stage" msgstr "Edit Stage" -#: src/pages/policies/BoundPoliciesList.ts:107 +#: src/pages/policies/BoundPoliciesList.ts:111 msgid "Edit User" msgstr "Edit User" @@ -1104,8 +1104,8 @@ msgstr "Enable Static Tokens" msgid "Enable TOTP" msgstr "Enable TOTP" -#: src/pages/policies/BoundPoliciesList.ts:37 -#: src/pages/policies/PolicyBindingForm.ts:198 +#: src/pages/policies/BoundPoliciesList.ts:41 +#: src/pages/policies/PolicyBindingForm.ts:199 #: src/pages/sources/ldap/LDAPSourceForm.ts:69 #: src/pages/sources/oauth/OAuthSourceForm.ts:115 #: src/pages/sources/saml/SAMLSourceForm.ts:69 @@ -1247,10 +1247,10 @@ msgstr "Export" msgid "Expression" msgstr "Expression" -#: src/pages/policies/expression/ExpressionPolicyForm.ts:84 -#: src/pages/property-mappings/PropertyMappingLDAPForm.ts:70 -#: src/pages/property-mappings/PropertyMappingSAMLForm.ts:80 -#: src/pages/property-mappings/PropertyMappingScopeForm.ts:77 +#: src/pages/policies/expression/ExpressionPolicyForm.ts:85 +#: src/pages/property-mappings/PropertyMappingLDAPForm.ts:71 +#: src/pages/property-mappings/PropertyMappingSAMLForm.ts:81 +#: src/pages/property-mappings/PropertyMappingScopeForm.ts:78 msgid "Expression using Python." msgstr "Expression using Python." @@ -1262,7 +1262,7 @@ msgstr "External Applications which use authentik as Identity-Provider, utilizin msgid "External Host" msgstr "External Host" -#: src/pages/providers/proxy/ProxyProviderForm.ts:118 +#: src/pages/providers/proxy/ProxyProviderForm.ts:119 msgid "External host" msgstr "External host" @@ -1420,9 +1420,9 @@ msgid "Go to previous page" msgstr "Go to previous page" #: src/pages/events/RuleForm.ts:65 -#: src/pages/groups/GroupListPage.ts:75 -#: src/pages/policies/PolicyBindingForm.ts:132 -#: src/pages/policies/PolicyBindingForm.ts:160 +#: src/pages/groups/GroupListPage.ts:74 +#: src/pages/policies/PolicyBindingForm.ts:125 +#: src/pages/policies/PolicyBindingForm.ts:161 msgid "Group" msgstr "Group" @@ -1442,7 +1442,7 @@ msgstr "Group object filter" msgid "Group users together and give them permissions based on the membership." msgstr "Group users together and give them permissions based on the membership." -#: src/pages/policies/BoundPoliciesList.ts:49 +#: src/pages/policies/BoundPoliciesList.ts:53 msgid "Group {0}" msgstr "Group {0}" @@ -1451,7 +1451,7 @@ msgstr "Group {0}" msgid "Groups" msgstr "Groups" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:149 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:150 msgid "HS256 (Symmetric Encryption)" msgstr "HS256 (Symmetric Encryption)" @@ -1476,7 +1476,7 @@ msgid "Hide managed mappings" msgstr "Hide managed mappings" #: src/pages/events/RuleForm.ts:93 -#: src/pages/groups/GroupForm.ts:132 +#: src/pages/groups/GroupForm.ts:131 #: src/pages/outposts/OutpostForm.ts:98 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:178 #: src/pages/providers/saml/SAMLProviderForm.ts:177 @@ -1552,11 +1552,11 @@ msgstr "Import certificates of external providers or create certificates to sign msgid "In case you can't access any other method." msgstr "In case you can't access any other method." -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:227 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:226 msgid "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint." msgstr "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint." -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:224 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:223 msgid "Include claims in id_token" msgstr "Include claims in id_token" @@ -1572,7 +1572,7 @@ msgstr "Internal application name, used in URLs." msgid "Internal host" msgstr "Internal host" -#: src/pages/providers/proxy/ProxyProviderForm.ts:112 +#: src/pages/providers/proxy/ProxyProviderForm.ts:113 msgid "Internal host SSL Validation" msgstr "Internal host SSL Validation" @@ -1600,15 +1600,15 @@ msgstr "Is superuser" msgid "Issuer" msgstr "Issuer" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:230 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:229 msgid "Issuer mode" msgstr "Issuer mode" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:141 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:142 msgid "JWT Algorithm" msgstr "JWT Algorithm" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:196 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:195 msgid "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256." msgstr "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256." @@ -1665,8 +1665,8 @@ msgid "Library" msgstr "Library" #: src/elements/table/Table.ts:120 -#: src/flows/FlowExecutor.ts:164 -#: src/flows/FlowExecutor.ts:210 +#: src/flows/FlowExecutor.ts:167 +#: src/flows/FlowExecutor.ts:213 #: src/flows/access_denied/FlowAccessDenied.ts:27 #: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts:43 #: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts:33 @@ -1694,23 +1694,23 @@ msgstr "Loading" #: src/pages/flows/StageBindingForm.ts:89 #: src/pages/flows/StageBindingForm.ts:106 #: src/pages/groups/GroupForm.ts:77 -#: src/pages/groups/GroupForm.ts:128 +#: src/pages/groups/GroupForm.ts:127 #: src/pages/outposts/OutpostForm.ts:74 #: src/pages/outposts/OutpostForm.ts:96 #: src/pages/outposts/ServiceConnectionDockerForm.ts:87 #: src/pages/outposts/ServiceConnectionDockerForm.ts:104 -#: src/pages/policies/PolicyBindingForm.ts:156 -#: src/pages/policies/PolicyBindingForm.ts:172 -#: src/pages/policies/PolicyBindingForm.ts:188 -#: src/pages/policies/PolicyTestForm.ts:70 +#: src/pages/policies/PolicyBindingForm.ts:157 +#: src/pages/policies/PolicyBindingForm.ts:173 +#: src/pages/policies/PolicyBindingForm.ts:189 +#: src/pages/policies/PolicyTestForm.ts:71 #: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:88 #: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:108 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:59 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:61 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:74 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:175 -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:194 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:193 #: src/pages/providers/proxy/ProxyProviderForm.ts:92 -#: src/pages/providers/proxy/ProxyProviderForm.ts:143 +#: src/pages/providers/proxy/ProxyProviderForm.ts:145 #: src/pages/providers/saml/SAMLProviderForm.ts:71 #: src/pages/providers/saml/SAMLProviderForm.ts:133 #: src/pages/providers/saml/SAMLProviderForm.ts:149 @@ -1803,7 +1803,7 @@ msgid "Members" msgstr "Members" #: src/pages/events/EventInfo.ts:174 -#: src/pages/policies/PolicyTestForm.ts:43 +#: src/pages/policies/PolicyTestForm.ts:44 #: src/pages/system-tasks/SystemTaskListPage.ts:80 msgid "Messages" msgstr "Messages" @@ -1889,7 +1889,7 @@ msgstr "Monitor" #: src/pages/sources/ldap/LDAPSourceForm.ts:54 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:64 #: src/pages/sources/oauth/OAuthSourceForm.ts:100 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:63 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:64 #: src/pages/sources/saml/SAMLSourceForm.ts:54 #: src/pages/sources/saml/SAMLSourceViewPage.ts:66 #: src/pages/stages/StageListPage.ts:65 @@ -1939,11 +1939,11 @@ msgid "New version available!" msgstr "New version available!" #: src/pages/crypto/CertificateKeyPairListPage.ts:61 -#: src/pages/groups/GroupListPage.ts:58 +#: src/pages/groups/GroupListPage.ts:57 #: src/pages/groups/MemberSelectModal.ts:57 #: src/pages/outposts/ServiceConnectionListPage.ts:64 -#: src/pages/policies/BoundPoliciesList.ts:118 -#: src/pages/policies/PolicyTestForm.ts:38 +#: src/pages/policies/BoundPoliciesList.ts:122 +#: src/pages/policies/PolicyTestForm.ts:39 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:108 #: src/pages/tokens/TokenListPage.ts:56 #: src/pages/user-settings/tokens/UserTokenList.ts:83 @@ -1960,7 +1960,7 @@ msgstr "No Applications available." msgid "No Events found." msgstr "No Events found." -#: src/pages/policies/BoundPoliciesList.ts:151 +#: src/pages/policies/BoundPoliciesList.ts:155 msgid "No Policies bound." msgstr "No Policies bound." @@ -1989,7 +1989,7 @@ msgstr "No form found" msgid "No matching events could be found." msgstr "No matching events could be found." -#: src/pages/policies/BoundPoliciesList.ts:153 +#: src/pages/policies/BoundPoliciesList.ts:157 msgid "No policies are currently bound to this object." msgstr "No policies are currently bound to this object." @@ -2161,8 +2161,8 @@ msgstr "Optionally set the 'FriendlyName' value of the Assertion attribute." #: src/pages/flows/BoundStagesList.ts:38 #: src/pages/flows/StageBindingForm.ts:110 -#: src/pages/policies/BoundPoliciesList.ts:38 -#: src/pages/policies/PolicyBindingForm.ts:203 +#: src/pages/policies/BoundPoliciesList.ts:42 +#: src/pages/policies/PolicyBindingForm.ts:204 #: src/pages/stages/prompt/PromptForm.ts:119 #: src/pages/stages/prompt/PromptListPage.ts:49 msgid "Order" @@ -2199,7 +2199,7 @@ msgstr "Outposts are deployments of authentik components to support different en #: src/pages/providers/proxy/ProxyProviderViewPage.ts:56 #: src/pages/providers/saml/SAMLProviderViewPage.ts:58 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:56 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:55 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:56 #: src/pages/sources/saml/SAMLSourceViewPage.ts:58 #: src/pages/users/UserViewPage.ts:74 msgid "Overview" @@ -2219,7 +2219,7 @@ msgid "Pass policy?" msgstr "Pass policy?" #: src/pages/events/EventInfo.ts:173 -#: src/pages/policies/PolicyTestForm.ts:35 +#: src/pages/policies/PolicyTestForm.ts:36 msgid "Passing" msgstr "Passing" @@ -2254,7 +2254,6 @@ msgid "Please enter your password" msgstr "Please enter your password" #: src/interfaces/AdminInterface.ts:26 -#: src/pages/admin-overview/AdminOverviewPage.ts:48 #: src/pages/flows/FlowListPage.ts:50 #: src/pages/policies/PolicyListPage.ts:38 msgid "Policies" @@ -2264,24 +2263,28 @@ msgstr "Policies" msgid "Policies without binding exist." msgstr "Policies without binding exist." -#: src/pages/policies/PolicyBindingForm.ts:124 -#: src/pages/policies/PolicyBindingForm.ts:147 +#: src/pages/policies/PolicyBindingForm.ts:108 +#: src/pages/policies/PolicyBindingForm.ts:117 +#: src/pages/policies/PolicyBindingForm.ts:148 #: src/pages/policies/PolicyListPage.ts:108 msgid "Policy" msgstr "Policy" -#: src/pages/policies/BoundPoliciesList.ts:36 +#: src/pages/applications/ApplicationViewPage.ts:134 +#: src/pages/flows/FlowViewPage.ts:101 +msgid "Policy / Group / User Bindings" +msgstr "Policy / Group / User Bindings" + +#: src/pages/policies/BoundPoliciesList.ts:40 msgid "Policy / User / Group" msgstr "Policy / User / Group" -#: src/pages/applications/ApplicationViewPage.ts:134 -#: src/pages/flows/FlowViewPage.ts:101 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:143 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:144 #: src/pages/sources/saml/SAMLSourceViewPage.ts:150 msgid "Policy Bindings" msgstr "Policy Bindings" -#: src/pages/policies/BoundPoliciesList.ts:138 +#: src/pages/policies/BoundPoliciesList.ts:142 msgid "Policy binding" msgstr "Policy binding" @@ -2292,7 +2295,7 @@ msgstr "Policy binding" msgid "Policy engine mode" msgstr "Policy engine mode" -#: src/pages/policies/BoundPoliciesList.ts:46 +#: src/pages/policies/BoundPoliciesList.ts:50 msgid "Policy {0}" msgstr "Policy {0}" @@ -2318,7 +2321,7 @@ msgstr "Post binding" msgid "Post binding (auto-submit)" msgstr "Post binding (auto-submit)" -#: src/flows/FlowExecutor.ts:252 +#: src/flows/FlowExecutor.ts:255 msgid "Powered by authentik" msgstr "Powered by authentik" @@ -2399,7 +2402,7 @@ msgid "Provider" msgstr "Provider" #: src/pages/applications/ApplicationListPage.ts:61 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:71 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:72 msgid "Provider Type" msgstr "Provider Type" @@ -2408,13 +2411,16 @@ msgid "Provider type" msgstr "Provider type" #: src/interfaces/AdminInterface.ts:20 -#: src/pages/admin-overview/AdminOverviewPage.ts:46 #: src/pages/outposts/OutpostForm.ts:82 #: src/pages/outposts/OutpostListPage.ts:51 #: src/pages/providers/ProviderListPage.ts:34 msgid "Providers" msgstr "Providers" +#: src/pages/admin-overview/AdminOverviewPage.ts:46 +msgid "Providers without application" +msgstr "Providers without application" + #: src/pages/outposts/OutpostForm.ts:57 msgid "Proxy" msgstr "Proxy" @@ -2435,7 +2441,7 @@ msgstr "Public key, acquired from https://www.google.com/recaptcha/intro/v3.html msgid "Publisher" msgstr "Publisher" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:146 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:147 msgid "RS256 (Asymmetric Encryption)" msgstr "RS256 (Asymmetric Encryption)" @@ -2507,7 +2513,7 @@ msgstr "Refresh Code" msgid "Register device" msgstr "Register device" -#: src/pages/providers/proxy/ProxyProviderForm.ts:151 +#: src/pages/providers/proxy/ProxyProviderForm.ts:153 msgid "Regular expressions for which authentication is not required. Each new line is interpreted as a new Regular Expression." msgstr "Regular expressions for which authentication is not required. Each new line is interpreted as a new Regular Expression." @@ -2556,7 +2562,7 @@ msgid "Resources" msgstr "Resources" #: src/pages/events/EventInfo.ts:171 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:34 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:36 msgid "Result" msgstr "Result" @@ -2569,7 +2575,7 @@ msgstr "Retry Task" msgid "Retry authentication" msgstr "Retry authentication" -#: src/flows/FlowExecutor.ts:142 +#: src/flows/FlowExecutor.ts:145 msgid "Return" msgstr "Return" @@ -2632,7 +2638,7 @@ msgstr "SMTP Username" msgid "SSO URL" msgstr "SSO URL" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:238 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:237 msgid "Same identifier is used for all providers" msgstr "Same identifier is used for all providers" @@ -2646,7 +2652,7 @@ msgstr "Scope which the client can specify to access these properties." #: src/elements/oauth/UserCodeList.ts:31 #: src/elements/oauth/UserRefreshList.ts:31 -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:155 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:156 msgid "Scopes" msgstr "Scopes" @@ -2658,10 +2664,10 @@ msgstr "Search..." msgid "Secret:" msgstr "Secret:" -#: src/pages/policies/expression/ExpressionPolicyForm.ts:86 -#: src/pages/property-mappings/PropertyMappingLDAPForm.ts:72 -#: src/pages/property-mappings/PropertyMappingSAMLForm.ts:82 -#: src/pages/property-mappings/PropertyMappingScopeForm.ts:79 +#: src/pages/policies/expression/ExpressionPolicyForm.ts:87 +#: src/pages/property-mappings/PropertyMappingLDAPForm.ts:73 +#: src/pages/property-mappings/PropertyMappingSAMLForm.ts:83 +#: src/pages/property-mappings/PropertyMappingScopeForm.ts:80 msgid "See documentation for a list of all variables." msgstr "See documentation for a list of all variables." @@ -2750,19 +2756,19 @@ msgstr "Session not valid on or after current time + this value (Format: hours=1 msgid "Session valid not on or after" msgstr "Session valid not on or after" -#: src/pages/providers/proxy/ProxyProviderForm.ts:161 +#: src/pages/providers/proxy/ProxyProviderForm.ts:163 msgid "Set HTTP-Basic Authentication" msgstr "Set HTTP-Basic Authentication" -#: src/pages/providers/proxy/ProxyProviderForm.ts:164 +#: src/pages/providers/proxy/ProxyProviderForm.ts:166 msgid "Set a custom HTTP-Basic Authentication header based on values from authentik." msgstr "Set a custom HTTP-Basic Authentication header based on values from authentik." #: src/pages/groups/GroupForm.ts:139 #: src/pages/outposts/OutpostForm.ts:109 #: src/pages/outposts/ServiceConnectionKubernetesForm.ts:73 -#: src/pages/policies/PolicyTestForm.ts:78 -#: src/pages/users/UserForm.ts:81 +#: src/pages/policies/PolicyTestForm.ts:79 +#: src/pages/users/UserForm.ts:82 msgid "Set custom attributes using YAML or JSON." msgstr "Set custom attributes using YAML or JSON." @@ -2804,7 +2810,7 @@ msgstr "Signing keypair" msgid "Single Prompts that can be used for Prompt Stages." msgstr "Single Prompts that can be used for Prompt Stages." -#: src/pages/providers/proxy/ProxyProviderForm.ts:148 +#: src/pages/providers/proxy/ProxyProviderForm.ts:150 msgid "Skip path regex" msgstr "Skip path regex" @@ -2817,7 +2823,7 @@ msgstr "Skip path regex" msgid "Slug" msgstr "Slug" -#: src/flows/FlowExecutor.ts:135 +#: src/flows/FlowExecutor.ts:138 msgid "Something went wrong! Please try again later." msgstr "Something went wrong! Please try again later." @@ -2942,7 +2948,7 @@ msgstr "Stop impersonation" msgid "Subject" msgstr "Subject" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:199 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:198 msgid "Subject mode" msgstr "Subject mode" @@ -2971,7 +2977,7 @@ msgid "Successfully created application." msgstr "Successfully created application." #: src/pages/flows/StageBindingForm.ts:39 -#: src/pages/policies/PolicyBindingForm.ts:72 +#: src/pages/policies/PolicyBindingForm.ts:64 msgid "Successfully created binding." msgstr "Successfully created binding." @@ -3089,8 +3095,8 @@ msgstr "Successfully imported flow." msgid "Successfully imported provider." msgstr "Successfully imported provider." -#: src/pages/policies/PolicyTestForm.ts:29 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:29 +#: src/pages/policies/PolicyTestForm.ts:30 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:31 msgid "Successfully sent test-request." msgstr "Successfully sent test-request." @@ -3099,7 +3105,7 @@ msgid "Successfully updated application." msgstr "Successfully updated application." #: src/pages/flows/StageBindingForm.ts:36 -#: src/pages/policies/PolicyBindingForm.ts:69 +#: src/pages/policies/PolicyBindingForm.ts:61 msgid "Successfully updated binding." msgstr "Successfully updated binding." @@ -3301,35 +3307,43 @@ msgstr "Text: Simple Text input" msgid "The URL \"{0}\" was not found." msgstr "The URL \"{0}\" was not found." +#: src/pages/providers/proxy/ProxyProviderForm.ts:123 +msgid "The external URL you'll access the outpost at." +msgstr "The external URL you'll access the outpost at." + #: src/pages/policies/dummy/DummyPolicyForm.ts:90 msgid "The policy takes a random time to execute. This controls the minimum time it will take." msgstr "The policy takes a random time to execute. This controls the minimum time it will take." +#: src/pages/flows/BoundStagesList.ts:102 +msgid "These bindings control if this stage will be applied to the flow." +msgstr "These bindings control if this stage will be applied to the flow." + #: src/pages/events/RuleListPage.ts:109 msgid "" -"These policies control upon which events this rule triggers. Bindings to\n" +"These bindings control upon which events this rule triggers. Bindings to\n" "groups/users are checked against the user of the event." msgstr "" -"These policies control upon which events this rule triggers. Bindings to\n" +"These bindings control upon which events this rule triggers. Bindings to\n" "groups/users are checked against the user of the event." -#: src/pages/flows/BoundStagesList.ts:102 -msgid "These policies control when this stage will be applied to the flow." -msgstr "These policies control when this stage will be applied to the flow." +#: src/pages/flows/FlowViewPage.ts:103 +msgid "These bindings control which users can access this flow." +msgstr "These bindings control which users can access this flow." + +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:146 +#: src/pages/sources/saml/SAMLSourceViewPage.ts:152 +msgid "" +"These bindings control which users can access this source.\n" +"You can only use policies here as access is checked before the user is authenticated." +msgstr "" +"These bindings control which users can access this source.\n" +"You can only use policies here as access is checked before the user is authenticated." #: src/pages/applications/ApplicationViewPage.ts:136 msgid "These policies control which users can access this application." msgstr "These policies control which users can access this application." -#: src/pages/flows/FlowViewPage.ts:103 -msgid "These policies control which users can access this flow." -msgstr "These policies control which users can access this flow." - -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:145 -#: src/pages/sources/saml/SAMLSourceViewPage.ts:152 -msgid "These policies control which users can access this source." -msgstr "These policies control which users can access this source." - #: src/pages/stages/invitation/InvitationStageForm.ts:53 msgid "This stage can be included in enrollment flows to accept invitations." msgstr "This stage can be included in enrollment flows to accept invitations." @@ -3354,8 +3368,8 @@ msgstr "Time offset when temporary users should be deleted. This only applies if msgid "Time-based One-Time Passwords" msgstr "Time-based One-Time Passwords" -#: src/pages/policies/BoundPoliciesList.ts:39 -#: src/pages/policies/PolicyBindingForm.ts:209 +#: src/pages/policies/BoundPoliciesList.ts:43 +#: src/pages/policies/PolicyBindingForm.ts:210 #: src/pages/stages/email/EmailStageForm.ts:101 msgid "Timeout" msgstr "Timeout" @@ -3370,7 +3384,7 @@ msgid "Token" msgstr "Token" #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:174 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:103 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:104 msgid "Token URL" msgstr "Token URL" @@ -3382,7 +3396,7 @@ msgstr "Token count" msgid "Token expiry" msgstr "Token expiry" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:135 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:136 msgid "Token validity" msgstr "Token validity" @@ -3453,6 +3467,10 @@ msgstr "URL used by authentik to retrieve tokens." msgid "URL used to request the initial token. This URL is only required for OAuth 1." msgstr "URL used to request the initial token. This URL is only required for OAuth 1." +#: src/pages/admin-overview/AdminOverviewPage.ts:48 +msgid "Unbound policies" +msgstr "Unbound policies" + #: src/pages/flows/FlowForm.ts:73 msgid "Unenrollment" msgstr "Unenrollment" @@ -3477,13 +3495,13 @@ msgstr "Up-to-date!" #: src/pages/flows/BoundStagesList.ts:53 #: src/pages/flows/BoundStagesList.ts:71 #: src/pages/flows/FlowListPage.ts:66 -#: src/pages/groups/GroupListPage.ts:62 +#: src/pages/groups/GroupListPage.ts:61 #: src/pages/outposts/OutpostListPage.ts:67 #: src/pages/outposts/ServiceConnectionListPage.ts:76 -#: src/pages/policies/BoundPoliciesList.ts:64 -#: src/pages/policies/BoundPoliciesList.ts:84 -#: src/pages/policies/BoundPoliciesList.ts:99 -#: src/pages/policies/BoundPoliciesList.ts:125 +#: src/pages/policies/BoundPoliciesList.ts:68 +#: src/pages/policies/BoundPoliciesList.ts:88 +#: src/pages/policies/BoundPoliciesList.ts:103 +#: src/pages/policies/BoundPoliciesList.ts:129 #: src/pages/policies/PolicyListPage.ts:77 #: src/pages/property-mappings/PropertyMappingListPage.ts:66 #: src/pages/providers/ProviderListPage.ts:73 @@ -3492,7 +3510,7 @@ msgstr "Up-to-date!" #: src/pages/providers/saml/SAMLProviderViewPage.ts:111 #: src/pages/sources/SourcesListPage.ts:69 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:95 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:114 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:115 #: src/pages/sources/saml/SAMLSourceViewPage.ts:101 #: src/pages/stages/StageListPage.ts:85 #: src/pages/stages/prompt/PromptListPage.ts:67 @@ -3512,7 +3530,7 @@ msgstr "Update" msgid "Update Application" msgstr "Update Application" -#: src/pages/policies/BoundPoliciesList.ts:128 +#: src/pages/policies/BoundPoliciesList.ts:132 msgid "Update Binding" msgstr "Update Binding" @@ -3524,8 +3542,8 @@ msgstr "Update Certificate-Key Pair" msgid "Update Flow" msgstr "Update Flow" -#: src/pages/groups/GroupListPage.ts:65 -#: src/pages/policies/BoundPoliciesList.ts:87 +#: src/pages/groups/GroupListPage.ts:64 +#: src/pages/policies/BoundPoliciesList.ts:91 msgid "Update Group" msgstr "Update Group" @@ -3541,7 +3559,7 @@ msgstr "Update Notification Rule" msgid "Update Notification Transport" msgstr "Update Notification Transport" -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:117 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:118 msgid "Update OAuth Source" msgstr "Update OAuth Source" @@ -3577,7 +3595,7 @@ msgstr "Update Stage binding" msgid "Update Token" msgstr "Update Token" -#: src/pages/policies/BoundPoliciesList.ts:102 +#: src/pages/policies/BoundPoliciesList.ts:106 #: src/pages/users/UserListPage.ts:71 #: src/pages/users/UserViewPage.ts:142 msgid "Update User" @@ -3589,7 +3607,7 @@ msgstr "Update details" #: src/pages/flows/BoundStagesList.ts:56 #: src/pages/outposts/ServiceConnectionListPage.ts:79 -#: src/pages/policies/BoundPoliciesList.ts:67 +#: src/pages/policies/BoundPoliciesList.ts:71 #: src/pages/policies/PolicyListPage.ts:80 #: src/pages/property-mappings/PropertyMappingListPage.ts:69 #: src/pages/providers/ProviderListPage.ts:76 @@ -3599,6 +3617,10 @@ msgstr "Update details" msgid "Update {0}" msgstr "Update {0}" +#: src/pages/providers/proxy/ProxyProviderForm.ts:107 +msgid "Upstream host that the requests are forwarded to." +msgstr "Upstream host that the requests are forwarded to." + #: src/pages/stages/email/EmailStageForm.ts:96 msgid "Use SSL" msgstr "Use SSL" @@ -3623,10 +3645,10 @@ msgstr "Use global settings" #: src/elements/events/UserEvents.ts:36 #: src/pages/events/EventInfo.ts:83 #: src/pages/events/EventListPage.ts:44 -#: src/pages/policies/PolicyBindingForm.ts:140 -#: src/pages/policies/PolicyBindingForm.ts:176 -#: src/pages/policies/PolicyTestForm.ts:60 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:49 +#: src/pages/policies/PolicyBindingForm.ts:133 +#: src/pages/policies/PolicyBindingForm.ts:177 +#: src/pages/policies/PolicyTestForm.ts:61 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:51 #: src/pages/tokens/TokenListPage.ts:45 #: src/pages/user-settings/tokens/UserTokenList.ts:72 #: src/pages/users/UserListPage.ts:88 @@ -3667,7 +3689,7 @@ msgstr "User object filter" msgid "User password writeback" msgstr "User password writeback" -#: src/pages/policies/BoundPoliciesList.ts:52 +#: src/pages/policies/BoundPoliciesList.ts:56 #: src/pages/users/UserViewPage.ts:63 msgid "User {0}" msgstr "User {0}" @@ -3722,11 +3744,11 @@ msgstr "Using flow" msgid "Using source" msgstr "Using source" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:123 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:124 msgid "Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows." msgstr "Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows." -#: src/pages/providers/proxy/ProxyProviderForm.ts:115 +#: src/pages/providers/proxy/ProxyProviderForm.ts:116 msgid "Validate SSL Certificates of upstream servers." msgstr "Validate SSL Certificates of upstream servers." @@ -3841,7 +3863,7 @@ msgstr "When selected, incoming assertion's Signatures will be validated against msgid "When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged." msgstr "When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged." -#: src/flows/FlowExecutor.ts:131 +#: src/flows/FlowExecutor.ts:134 msgid "Whoops!" msgstr "Whoops!" @@ -3866,11 +3888,11 @@ msgid "X509 Subject" msgstr "X509 Subject" #: src/pages/crypto/CertificateKeyPairListPage.ts:61 -#: src/pages/groups/GroupListPage.ts:58 +#: src/pages/groups/GroupListPage.ts:57 #: src/pages/groups/MemberSelectModal.ts:57 #: src/pages/outposts/ServiceConnectionListPage.ts:64 -#: src/pages/policies/BoundPoliciesList.ts:118 -#: src/pages/policies/PolicyTestForm.ts:38 +#: src/pages/policies/BoundPoliciesList.ts:122 +#: src/pages/policies/PolicyTestForm.ts:39 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:105 #: src/pages/tokens/TokenListPage.ts:56 #: src/pages/user-settings/tokens/UserTokenList.ts:83 diff --git a/web/src/locales/pseudo-LOCALE.po b/web/src/locales/pseudo-LOCALE.po index 9b4f58a1d..a346554c3 100644 --- a/web/src/locales/pseudo-LOCALE.po +++ b/web/src/locales/pseudo-LOCALE.po @@ -13,7 +13,7 @@ msgstr "" "Language-Team: \n" "Plural-Forms: \n" -#: src/pages/policies/BoundPoliciesList.ts:55 +#: src/pages/policies/BoundPoliciesList.ts:59 msgid "-" msgstr "" @@ -64,7 +64,7 @@ msgstr "" msgid "API request failed" msgstr "" -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:87 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:88 msgid "Access Key" msgstr "" @@ -105,8 +105,8 @@ msgstr "" msgid "Additional user DN, prepended to the Base DN." msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:131 -#: src/pages/providers/proxy/ProxyProviderForm.ts:128 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:132 +#: src/pages/providers/proxy/ProxyProviderForm.ts:130 #: src/pages/providers/saml/SAMLProviderForm.ts:117 #: src/pages/sources/saml/SAMLSourceForm.ts:134 msgid "Advanced protocol settings" @@ -125,7 +125,7 @@ msgstr "" msgid "Alert" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:152 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:153 msgid "Algorithm used to sign the JWT Tokens." msgstr "" @@ -255,7 +255,7 @@ msgstr "" msgid "Attribute name used for SAML Assertions. Can be a URN OID, a schema reference, or a any other string. If this property mapping is used for NameID Property, this field is discarded." msgstr "" -#: src/pages/groups/GroupForm.ts:135 +#: src/pages/groups/GroupForm.ts:134 #: src/pages/stages/invitation/InvitationForm.ts:52 #: src/pages/users/UserForm.ts:77 msgid "Attributes" @@ -289,7 +289,7 @@ msgid "Authorization Code" msgstr "" #: src/pages/sources/oauth/OAuthSourceForm.ts:66 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:95 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:96 msgid "Authorization URL" msgstr "" @@ -338,19 +338,19 @@ msgstr "" msgid "Base DN" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:204 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:203 msgid "Based on the Hashed User ID" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:210 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:209 msgid "Based on the User's Email. This is recommended over the UPN method." msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:213 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:212 msgid "Based on the User's UPN, only works if user has a 'upn' attribute set. Use this method only if you have different UPN and Mail domains." msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:207 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:206 msgid "Based on the username" msgstr "" @@ -401,7 +401,7 @@ msgstr "" msgid "Cached Policies" msgstr "" -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:79 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:80 msgid "Callback URL" msgstr "" @@ -422,7 +422,7 @@ msgid "Case insensitive matching" msgstr "" #: src/pages/crypto/CertificateKeyPairForm.ts:51 -#: src/pages/providers/proxy/ProxyProviderForm.ts:132 +#: src/pages/providers/proxy/ProxyProviderForm.ts:134 msgid "Certificate" msgstr "" @@ -468,7 +468,7 @@ msgstr "" #: src/pages/providers/proxy/ProxyProviderViewPage.ts:135 #: src/pages/providers/saml/SAMLProviderViewPage.ts:129 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:113 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:132 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:133 #: src/pages/sources/saml/SAMLSourceViewPage.ts:119 #: src/pages/users/UserViewPage.ts:185 msgid "Changelog" @@ -590,7 +590,7 @@ msgstr "" msgid "Configure how the NameID value will be created. When left empty, the NameIDPolicy of the incoming request will be respected." msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:242 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:241 msgid "Configure how the issuer field of the ID Token should be filled." msgstr "" @@ -598,7 +598,7 @@ msgstr "" msgid "Configure settings relevant to your user profile." msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:217 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:216 msgid "Configure what data should be used as unique User Identifier. For most cases, the default should be fine." msgstr "" @@ -654,8 +654,8 @@ msgstr "" #: src/pages/events/EventInfo.ts:79 #: src/pages/events/EventInfo.ts:148 #: src/pages/events/EventInfo.ts:167 -#: src/pages/policies/PolicyTestForm.ts:74 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:63 +#: src/pages/policies/PolicyTestForm.ts:75 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:65 msgid "Context" msgstr "" @@ -702,15 +702,15 @@ msgstr "" #: src/pages/flows/BoundStagesList.ts:167 #: src/pages/flows/FlowListPage.ts:109 #: src/pages/flows/FlowListPage.ts:117 -#: src/pages/groups/GroupListPage.ts:91 -#: src/pages/groups/GroupListPage.ts:99 +#: src/pages/groups/GroupListPage.ts:90 +#: src/pages/groups/GroupListPage.ts:98 #: src/pages/outposts/OutpostListPage.ts:101 #: src/pages/outposts/OutpostListPage.ts:109 #: src/pages/outposts/ServiceConnectionListPage.ts:110 #: src/pages/outposts/ServiceConnectionListPage.ts:119 -#: src/pages/policies/BoundPoliciesList.ts:158 -#: src/pages/policies/BoundPoliciesList.ts:185 -#: src/pages/policies/BoundPoliciesList.ts:206 +#: src/pages/policies/BoundPoliciesList.ts:162 +#: src/pages/policies/BoundPoliciesList.ts:189 +#: src/pages/policies/BoundPoliciesList.ts:210 #: src/pages/policies/PolicyListPage.ts:124 #: src/pages/policies/PolicyListPage.ts:133 #: src/pages/property-mappings/PropertyMappingListPage.ts:113 @@ -741,10 +741,10 @@ msgstr "" msgid "Create Application" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:161 -#: src/pages/policies/BoundPoliciesList.ts:166 -#: src/pages/policies/BoundPoliciesList.ts:209 -#: src/pages/policies/BoundPoliciesList.ts:214 +#: src/pages/policies/BoundPoliciesList.ts:165 +#: src/pages/policies/BoundPoliciesList.ts:170 +#: src/pages/policies/BoundPoliciesList.ts:213 +#: src/pages/policies/BoundPoliciesList.ts:218 msgid "Create Binding" msgstr "" @@ -756,7 +756,7 @@ msgstr "" msgid "Create Flow" msgstr "" -#: src/pages/groups/GroupListPage.ts:94 +#: src/pages/groups/GroupListPage.ts:93 msgid "Create Group" msgstr "" @@ -780,7 +780,7 @@ msgstr "" msgid "Create Outpost" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:176 +#: src/pages/policies/BoundPoliciesList.ts:180 msgid "Create Policy" msgstr "" @@ -813,7 +813,7 @@ msgstr "" #: src/pages/applications/ApplicationForm.ts:123 #: src/pages/flows/BoundStagesList.ts:149 #: src/pages/outposts/ServiceConnectionListPage.ts:122 -#: src/pages/policies/BoundPoliciesList.ts:188 +#: src/pages/policies/BoundPoliciesList.ts:192 #: src/pages/policies/PolicyListPage.ts:136 #: src/pages/property-mappings/PropertyMappingListPage.ts:125 #: src/pages/providers/ProviderListPage.ts:119 @@ -867,7 +867,7 @@ msgstr "" #: src/pages/events/RuleListPage.ts:82 #: src/pages/events/TransportListPage.ts:86 #: src/pages/flows/FlowListPage.ts:86 -#: src/pages/groups/GroupListPage.ts:82 +#: src/pages/groups/GroupListPage.ts:81 #: src/pages/outposts/OutpostListPage.ts:87 #: src/pages/outposts/ServiceConnectionListPage.ts:101 #: src/pages/policies/PolicyListPage.ts:115 @@ -889,7 +889,7 @@ msgid "Delete Authorization Code" msgstr "" #: src/pages/flows/BoundStagesList.ts:91 -#: src/pages/policies/BoundPoliciesList.ts:145 +#: src/pages/policies/BoundPoliciesList.ts:149 msgid "Delete Binding" msgstr "" @@ -1002,7 +1002,7 @@ msgstr "" msgid "Dummy stage used for testing. Shows a simple continue button and always passes." msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:235 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:234 msgid "Each provider has a different issuer, based on the application slug." msgstr "" @@ -1013,7 +1013,7 @@ msgstr "" #: src/pages/events/RuleListPage.ts:70 #: src/pages/events/TransportListPage.ts:74 #: src/pages/flows/FlowListPage.ts:74 -#: src/pages/groups/GroupListPage.ts:70 +#: src/pages/groups/GroupListPage.ts:69 #: src/pages/outposts/OutpostListPage.ts:75 #: src/pages/outposts/ServiceConnectionListPage.ts:89 #: src/pages/policies/PolicyListPage.ts:90 @@ -1024,7 +1024,7 @@ msgstr "" #: src/pages/providers/saml/SAMLProviderViewPage.ts:121 #: src/pages/sources/SourcesListPage.ts:82 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:105 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:124 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:125 #: src/pages/sources/saml/SAMLSourceViewPage.ts:111 #: src/pages/stages/StageListPage.ts:98 #: src/pages/stages/prompt/PromptListPage.ts:75 @@ -1035,15 +1035,15 @@ msgid "Edit" msgstr "" #: src/pages/flows/BoundStagesList.ts:79 -#: src/pages/policies/BoundPoliciesList.ts:133 +#: src/pages/policies/BoundPoliciesList.ts:137 msgid "Edit Binding" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:92 +#: src/pages/policies/BoundPoliciesList.ts:96 msgid "Edit Group" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:77 +#: src/pages/policies/BoundPoliciesList.ts:81 msgid "Edit Policy" msgstr "" @@ -1051,7 +1051,7 @@ msgstr "" msgid "Edit Stage" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:107 +#: src/pages/policies/BoundPoliciesList.ts:111 msgid "Edit User" msgstr "" @@ -1096,8 +1096,8 @@ msgstr "" msgid "Enable TOTP" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:37 -#: src/pages/policies/PolicyBindingForm.ts:198 +#: src/pages/policies/BoundPoliciesList.ts:41 +#: src/pages/policies/PolicyBindingForm.ts:199 #: src/pages/sources/ldap/LDAPSourceForm.ts:69 #: src/pages/sources/oauth/OAuthSourceForm.ts:115 #: src/pages/sources/saml/SAMLSourceForm.ts:69 @@ -1239,10 +1239,10 @@ msgstr "" msgid "Expression" msgstr "" -#: src/pages/policies/expression/ExpressionPolicyForm.ts:84 -#: src/pages/property-mappings/PropertyMappingLDAPForm.ts:70 -#: src/pages/property-mappings/PropertyMappingSAMLForm.ts:80 -#: src/pages/property-mappings/PropertyMappingScopeForm.ts:77 +#: src/pages/policies/expression/ExpressionPolicyForm.ts:85 +#: src/pages/property-mappings/PropertyMappingLDAPForm.ts:71 +#: src/pages/property-mappings/PropertyMappingSAMLForm.ts:81 +#: src/pages/property-mappings/PropertyMappingScopeForm.ts:78 msgid "Expression using Python." msgstr "" @@ -1254,7 +1254,7 @@ msgstr "" msgid "External Host" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:118 +#: src/pages/providers/proxy/ProxyProviderForm.ts:119 msgid "External host" msgstr "" @@ -1412,9 +1412,9 @@ msgid "Go to previous page" msgstr "" #: src/pages/events/RuleForm.ts:65 -#: src/pages/groups/GroupListPage.ts:75 -#: src/pages/policies/PolicyBindingForm.ts:132 -#: src/pages/policies/PolicyBindingForm.ts:160 +#: src/pages/groups/GroupListPage.ts:74 +#: src/pages/policies/PolicyBindingForm.ts:125 +#: src/pages/policies/PolicyBindingForm.ts:161 msgid "Group" msgstr "" @@ -1434,7 +1434,7 @@ msgstr "" msgid "Group users together and give them permissions based on the membership." msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:49 +#: src/pages/policies/BoundPoliciesList.ts:53 msgid "Group {0}" msgstr "" @@ -1443,7 +1443,7 @@ msgstr "" msgid "Groups" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:149 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:150 msgid "HS256 (Symmetric Encryption)" msgstr "" @@ -1468,7 +1468,7 @@ msgid "Hide managed mappings" msgstr "" #: src/pages/events/RuleForm.ts:93 -#: src/pages/groups/GroupForm.ts:132 +#: src/pages/groups/GroupForm.ts:131 #: src/pages/outposts/OutpostForm.ts:98 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:178 #: src/pages/providers/saml/SAMLProviderForm.ts:177 @@ -1544,11 +1544,11 @@ msgstr "" msgid "In case you can't access any other method." msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:227 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:226 msgid "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint." msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:224 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:223 msgid "Include claims in id_token" msgstr "" @@ -1564,7 +1564,7 @@ msgstr "" msgid "Internal host" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:112 +#: src/pages/providers/proxy/ProxyProviderForm.ts:113 msgid "Internal host SSL Validation" msgstr "" @@ -1592,15 +1592,15 @@ msgstr "" msgid "Issuer" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:230 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:229 msgid "Issuer mode" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:141 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:142 msgid "JWT Algorithm" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:196 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:195 msgid "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256." msgstr "" @@ -1657,8 +1657,8 @@ msgid "Library" msgstr "" #: src/elements/table/Table.ts:120 -#: src/flows/FlowExecutor.ts:164 -#: src/flows/FlowExecutor.ts:210 +#: src/flows/FlowExecutor.ts:167 +#: src/flows/FlowExecutor.ts:213 #: src/flows/access_denied/FlowAccessDenied.ts:27 #: src/flows/stages/authenticator_static/AuthenticatorStaticStage.ts:43 #: src/flows/stages/authenticator_totp/AuthenticatorTOTPStage.ts:33 @@ -1686,23 +1686,23 @@ msgstr "" #: src/pages/flows/StageBindingForm.ts:89 #: src/pages/flows/StageBindingForm.ts:106 #: src/pages/groups/GroupForm.ts:77 -#: src/pages/groups/GroupForm.ts:128 +#: src/pages/groups/GroupForm.ts:127 #: src/pages/outposts/OutpostForm.ts:74 #: src/pages/outposts/OutpostForm.ts:96 #: src/pages/outposts/ServiceConnectionDockerForm.ts:87 #: src/pages/outposts/ServiceConnectionDockerForm.ts:104 -#: src/pages/policies/PolicyBindingForm.ts:156 -#: src/pages/policies/PolicyBindingForm.ts:172 -#: src/pages/policies/PolicyBindingForm.ts:188 -#: src/pages/policies/PolicyTestForm.ts:70 +#: src/pages/policies/PolicyBindingForm.ts:157 +#: src/pages/policies/PolicyBindingForm.ts:173 +#: src/pages/policies/PolicyBindingForm.ts:189 +#: src/pages/policies/PolicyTestForm.ts:71 #: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:88 #: src/pages/policies/event_matcher/EventMatcherPolicyForm.ts:108 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:59 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:61 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:74 #: src/pages/providers/oauth2/OAuth2ProviderForm.ts:175 -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:194 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:193 #: src/pages/providers/proxy/ProxyProviderForm.ts:92 -#: src/pages/providers/proxy/ProxyProviderForm.ts:143 +#: src/pages/providers/proxy/ProxyProviderForm.ts:145 #: src/pages/providers/saml/SAMLProviderForm.ts:71 #: src/pages/providers/saml/SAMLProviderForm.ts:133 #: src/pages/providers/saml/SAMLProviderForm.ts:149 @@ -1795,7 +1795,7 @@ msgid "Members" msgstr "" #: src/pages/events/EventInfo.ts:174 -#: src/pages/policies/PolicyTestForm.ts:43 +#: src/pages/policies/PolicyTestForm.ts:44 #: src/pages/system-tasks/SystemTaskListPage.ts:80 msgid "Messages" msgstr "" @@ -1881,7 +1881,7 @@ msgstr "" #: src/pages/sources/ldap/LDAPSourceForm.ts:54 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:64 #: src/pages/sources/oauth/OAuthSourceForm.ts:100 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:63 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:64 #: src/pages/sources/saml/SAMLSourceForm.ts:54 #: src/pages/sources/saml/SAMLSourceViewPage.ts:66 #: src/pages/stages/StageListPage.ts:65 @@ -1931,11 +1931,11 @@ msgid "New version available!" msgstr "" #: src/pages/crypto/CertificateKeyPairListPage.ts:61 -#: src/pages/groups/GroupListPage.ts:58 +#: src/pages/groups/GroupListPage.ts:57 #: src/pages/groups/MemberSelectModal.ts:57 #: src/pages/outposts/ServiceConnectionListPage.ts:64 -#: src/pages/policies/BoundPoliciesList.ts:118 -#: src/pages/policies/PolicyTestForm.ts:38 +#: src/pages/policies/BoundPoliciesList.ts:122 +#: src/pages/policies/PolicyTestForm.ts:39 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:108 #: src/pages/tokens/TokenListPage.ts:56 #: src/pages/user-settings/tokens/UserTokenList.ts:83 @@ -1952,7 +1952,7 @@ msgstr "" msgid "No Events found." msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:151 +#: src/pages/policies/BoundPoliciesList.ts:155 msgid "No Policies bound." msgstr "" @@ -1981,7 +1981,7 @@ msgstr "" msgid "No matching events could be found." msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:153 +#: src/pages/policies/BoundPoliciesList.ts:157 msgid "No policies are currently bound to this object." msgstr "" @@ -2153,8 +2153,8 @@ msgstr "" #: src/pages/flows/BoundStagesList.ts:38 #: src/pages/flows/StageBindingForm.ts:110 -#: src/pages/policies/BoundPoliciesList.ts:38 -#: src/pages/policies/PolicyBindingForm.ts:203 +#: src/pages/policies/BoundPoliciesList.ts:42 +#: src/pages/policies/PolicyBindingForm.ts:204 #: src/pages/stages/prompt/PromptForm.ts:119 #: src/pages/stages/prompt/PromptListPage.ts:49 msgid "Order" @@ -2191,7 +2191,7 @@ msgstr "" #: src/pages/providers/proxy/ProxyProviderViewPage.ts:56 #: src/pages/providers/saml/SAMLProviderViewPage.ts:58 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:56 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:55 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:56 #: src/pages/sources/saml/SAMLSourceViewPage.ts:58 #: src/pages/users/UserViewPage.ts:74 msgid "Overview" @@ -2211,7 +2211,7 @@ msgid "Pass policy?" msgstr "" #: src/pages/events/EventInfo.ts:173 -#: src/pages/policies/PolicyTestForm.ts:35 +#: src/pages/policies/PolicyTestForm.ts:36 msgid "Passing" msgstr "" @@ -2246,7 +2246,6 @@ msgid "Please enter your password" msgstr "" #: src/interfaces/AdminInterface.ts:26 -#: src/pages/admin-overview/AdminOverviewPage.ts:48 #: src/pages/flows/FlowListPage.ts:50 #: src/pages/policies/PolicyListPage.ts:38 msgid "Policies" @@ -2256,24 +2255,28 @@ msgstr "" msgid "Policies without binding exist." msgstr "" -#: src/pages/policies/PolicyBindingForm.ts:124 -#: src/pages/policies/PolicyBindingForm.ts:147 +#: src/pages/policies/PolicyBindingForm.ts:108 +#: src/pages/policies/PolicyBindingForm.ts:117 +#: src/pages/policies/PolicyBindingForm.ts:148 #: src/pages/policies/PolicyListPage.ts:108 msgid "Policy" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:36 +#: src/pages/applications/ApplicationViewPage.ts:134 +#: src/pages/flows/FlowViewPage.ts:101 +msgid "Policy / Group / User Bindings" +msgstr "" + +#: src/pages/policies/BoundPoliciesList.ts:40 msgid "Policy / User / Group" msgstr "" -#: src/pages/applications/ApplicationViewPage.ts:134 -#: src/pages/flows/FlowViewPage.ts:101 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:143 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:144 #: src/pages/sources/saml/SAMLSourceViewPage.ts:150 msgid "Policy Bindings" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:138 +#: src/pages/policies/BoundPoliciesList.ts:142 msgid "Policy binding" msgstr "" @@ -2284,7 +2287,7 @@ msgstr "" msgid "Policy engine mode" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:46 +#: src/pages/policies/BoundPoliciesList.ts:50 msgid "Policy {0}" msgstr "" @@ -2310,7 +2313,7 @@ msgstr "" msgid "Post binding (auto-submit)" msgstr "" -#: src/flows/FlowExecutor.ts:252 +#: src/flows/FlowExecutor.ts:255 msgid "Powered by authentik" msgstr "" @@ -2391,7 +2394,7 @@ msgid "Provider" msgstr "" #: src/pages/applications/ApplicationListPage.ts:61 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:71 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:72 msgid "Provider Type" msgstr "" @@ -2400,13 +2403,16 @@ msgid "Provider type" msgstr "" #: src/interfaces/AdminInterface.ts:20 -#: src/pages/admin-overview/AdminOverviewPage.ts:46 #: src/pages/outposts/OutpostForm.ts:82 #: src/pages/outposts/OutpostListPage.ts:51 #: src/pages/providers/ProviderListPage.ts:34 msgid "Providers" msgstr "" +#: src/pages/admin-overview/AdminOverviewPage.ts:46 +msgid "Providers without application" +msgstr "" + #: src/pages/outposts/OutpostForm.ts:57 msgid "Proxy" msgstr "" @@ -2427,7 +2433,7 @@ msgstr "" msgid "Publisher" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:146 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:147 msgid "RS256 (Asymmetric Encryption)" msgstr "" @@ -2499,7 +2505,7 @@ msgstr "" msgid "Register device" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:151 +#: src/pages/providers/proxy/ProxyProviderForm.ts:153 msgid "Regular expressions for which authentication is not required. Each new line is interpreted as a new Regular Expression." msgstr "" @@ -2548,7 +2554,7 @@ msgid "Resources" msgstr "" #: src/pages/events/EventInfo.ts:171 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:34 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:36 msgid "Result" msgstr "" @@ -2561,7 +2567,7 @@ msgstr "" msgid "Retry authentication" msgstr "" -#: src/flows/FlowExecutor.ts:142 +#: src/flows/FlowExecutor.ts:145 msgid "Return" msgstr "" @@ -2624,7 +2630,7 @@ msgstr "" msgid "SSO URL" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:238 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:237 msgid "Same identifier is used for all providers" msgstr "" @@ -2638,7 +2644,7 @@ msgstr "" #: src/elements/oauth/UserCodeList.ts:31 #: src/elements/oauth/UserRefreshList.ts:31 -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:155 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:156 msgid "Scopes" msgstr "" @@ -2650,10 +2656,10 @@ msgstr "" msgid "Secret:" msgstr "" -#: src/pages/policies/expression/ExpressionPolicyForm.ts:86 -#: src/pages/property-mappings/PropertyMappingLDAPForm.ts:72 -#: src/pages/property-mappings/PropertyMappingSAMLForm.ts:82 -#: src/pages/property-mappings/PropertyMappingScopeForm.ts:79 +#: src/pages/policies/expression/ExpressionPolicyForm.ts:87 +#: src/pages/property-mappings/PropertyMappingLDAPForm.ts:73 +#: src/pages/property-mappings/PropertyMappingSAMLForm.ts:83 +#: src/pages/property-mappings/PropertyMappingScopeForm.ts:80 msgid "See documentation for a list of all variables." msgstr "" @@ -2742,19 +2748,19 @@ msgstr "" msgid "Session valid not on or after" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:161 +#: src/pages/providers/proxy/ProxyProviderForm.ts:163 msgid "Set HTTP-Basic Authentication" msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:164 +#: src/pages/providers/proxy/ProxyProviderForm.ts:166 msgid "Set a custom HTTP-Basic Authentication header based on values from authentik." msgstr "" #: src/pages/groups/GroupForm.ts:139 #: src/pages/outposts/OutpostForm.ts:109 #: src/pages/outposts/ServiceConnectionKubernetesForm.ts:73 -#: src/pages/policies/PolicyTestForm.ts:78 -#: src/pages/users/UserForm.ts:81 +#: src/pages/policies/PolicyTestForm.ts:79 +#: src/pages/users/UserForm.ts:82 msgid "Set custom attributes using YAML or JSON." msgstr "" @@ -2796,7 +2802,7 @@ msgstr "" msgid "Single Prompts that can be used for Prompt Stages." msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:148 +#: src/pages/providers/proxy/ProxyProviderForm.ts:150 msgid "Skip path regex" msgstr "" @@ -2809,7 +2815,7 @@ msgstr "" msgid "Slug" msgstr "" -#: src/flows/FlowExecutor.ts:135 +#: src/flows/FlowExecutor.ts:138 msgid "Something went wrong! Please try again later." msgstr "" @@ -2934,7 +2940,7 @@ msgstr "" msgid "Subject" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:199 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:198 msgid "Subject mode" msgstr "" @@ -2963,7 +2969,7 @@ msgid "Successfully created application." msgstr "" #: src/pages/flows/StageBindingForm.ts:39 -#: src/pages/policies/PolicyBindingForm.ts:72 +#: src/pages/policies/PolicyBindingForm.ts:64 msgid "Successfully created binding." msgstr "" @@ -3081,8 +3087,8 @@ msgstr "" msgid "Successfully imported provider." msgstr "" -#: src/pages/policies/PolicyTestForm.ts:29 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:29 +#: src/pages/policies/PolicyTestForm.ts:30 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:31 msgid "Successfully sent test-request." msgstr "" @@ -3091,7 +3097,7 @@ msgid "Successfully updated application." msgstr "" #: src/pages/flows/StageBindingForm.ts:36 -#: src/pages/policies/PolicyBindingForm.ts:69 +#: src/pages/policies/PolicyBindingForm.ts:61 msgid "Successfully updated binding." msgstr "" @@ -3293,33 +3299,39 @@ msgstr "" msgid "The URL \"{0}\" was not found." msgstr "" +#: src/pages/providers/proxy/ProxyProviderForm.ts:123 +msgid "The external URL you'll access the outpost at." +msgstr "" + #: src/pages/policies/dummy/DummyPolicyForm.ts:90 msgid "The policy takes a random time to execute. This controls the minimum time it will take." msgstr "" +#: src/pages/flows/BoundStagesList.ts:102 +msgid "These bindings control if this stage will be applied to the flow." +msgstr "" + #: src/pages/events/RuleListPage.ts:109 msgid "" -"These policies control upon which events this rule triggers. Bindings to\n" +"These bindings control upon which events this rule triggers. Bindings to\n" "groups/users are checked against the user of the event." msgstr "" -#: src/pages/flows/BoundStagesList.ts:102 -msgid "These policies control when this stage will be applied to the flow." +#: src/pages/flows/FlowViewPage.ts:103 +msgid "These bindings control which users can access this flow." +msgstr "" + +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:146 +#: src/pages/sources/saml/SAMLSourceViewPage.ts:152 +msgid "" +"These bindings control which users can access this source.\n" +"You can only use policies here as access is checked before the user is authenticated." msgstr "" #: src/pages/applications/ApplicationViewPage.ts:136 msgid "These policies control which users can access this application." msgstr "" -#: src/pages/flows/FlowViewPage.ts:103 -msgid "These policies control which users can access this flow." -msgstr "" - -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:145 -#: src/pages/sources/saml/SAMLSourceViewPage.ts:152 -msgid "These policies control which users can access this source." -msgstr "" - #: src/pages/stages/invitation/InvitationStageForm.ts:53 msgid "This stage can be included in enrollment flows to accept invitations." msgstr "" @@ -3344,8 +3356,8 @@ msgstr "" msgid "Time-based One-Time Passwords" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:39 -#: src/pages/policies/PolicyBindingForm.ts:209 +#: src/pages/policies/BoundPoliciesList.ts:43 +#: src/pages/policies/PolicyBindingForm.ts:210 #: src/pages/stages/email/EmailStageForm.ts:101 msgid "Timeout" msgstr "" @@ -3360,7 +3372,7 @@ msgid "Token" msgstr "" #: src/pages/providers/oauth2/OAuth2ProviderViewPage.ts:174 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:103 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:104 msgid "Token URL" msgstr "" @@ -3372,7 +3384,7 @@ msgstr "" msgid "Token expiry" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:135 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:136 msgid "Token validity" msgstr "" @@ -3443,6 +3455,10 @@ msgstr "" msgid "URL used to request the initial token. This URL is only required for OAuth 1." msgstr "" +#: src/pages/admin-overview/AdminOverviewPage.ts:48 +msgid "Unbound policies" +msgstr "" + #: src/pages/flows/FlowForm.ts:73 msgid "Unenrollment" msgstr "" @@ -3467,13 +3483,13 @@ msgstr "" #: src/pages/flows/BoundStagesList.ts:53 #: src/pages/flows/BoundStagesList.ts:71 #: src/pages/flows/FlowListPage.ts:66 -#: src/pages/groups/GroupListPage.ts:62 +#: src/pages/groups/GroupListPage.ts:61 #: src/pages/outposts/OutpostListPage.ts:67 #: src/pages/outposts/ServiceConnectionListPage.ts:76 -#: src/pages/policies/BoundPoliciesList.ts:64 -#: src/pages/policies/BoundPoliciesList.ts:84 -#: src/pages/policies/BoundPoliciesList.ts:99 -#: src/pages/policies/BoundPoliciesList.ts:125 +#: src/pages/policies/BoundPoliciesList.ts:68 +#: src/pages/policies/BoundPoliciesList.ts:88 +#: src/pages/policies/BoundPoliciesList.ts:103 +#: src/pages/policies/BoundPoliciesList.ts:129 #: src/pages/policies/PolicyListPage.ts:77 #: src/pages/property-mappings/PropertyMappingListPage.ts:66 #: src/pages/providers/ProviderListPage.ts:73 @@ -3482,7 +3498,7 @@ msgstr "" #: src/pages/providers/saml/SAMLProviderViewPage.ts:111 #: src/pages/sources/SourcesListPage.ts:69 #: src/pages/sources/ldap/LDAPSourceViewPage.ts:95 -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:114 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:115 #: src/pages/sources/saml/SAMLSourceViewPage.ts:101 #: src/pages/stages/StageListPage.ts:85 #: src/pages/stages/prompt/PromptListPage.ts:67 @@ -3502,7 +3518,7 @@ msgstr "" msgid "Update Application" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:128 +#: src/pages/policies/BoundPoliciesList.ts:132 msgid "Update Binding" msgstr "" @@ -3514,8 +3530,8 @@ msgstr "" msgid "Update Flow" msgstr "" -#: src/pages/groups/GroupListPage.ts:65 -#: src/pages/policies/BoundPoliciesList.ts:87 +#: src/pages/groups/GroupListPage.ts:64 +#: src/pages/policies/BoundPoliciesList.ts:91 msgid "Update Group" msgstr "" @@ -3531,7 +3547,7 @@ msgstr "" msgid "Update Notification Transport" msgstr "" -#: src/pages/sources/oauth/OAuthSourceViewPage.ts:117 +#: src/pages/sources/oauth/OAuthSourceViewPage.ts:118 msgid "Update OAuth Source" msgstr "" @@ -3567,7 +3583,7 @@ msgstr "" msgid "Update Token" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:102 +#: src/pages/policies/BoundPoliciesList.ts:106 #: src/pages/users/UserListPage.ts:71 #: src/pages/users/UserViewPage.ts:142 msgid "Update User" @@ -3579,7 +3595,7 @@ msgstr "" #: src/pages/flows/BoundStagesList.ts:56 #: src/pages/outposts/ServiceConnectionListPage.ts:79 -#: src/pages/policies/BoundPoliciesList.ts:67 +#: src/pages/policies/BoundPoliciesList.ts:71 #: src/pages/policies/PolicyListPage.ts:80 #: src/pages/property-mappings/PropertyMappingListPage.ts:69 #: src/pages/providers/ProviderListPage.ts:76 @@ -3589,6 +3605,10 @@ msgstr "" msgid "Update {0}" msgstr "" +#: src/pages/providers/proxy/ProxyProviderForm.ts:107 +msgid "Upstream host that the requests are forwarded to." +msgstr "" + #: src/pages/stages/email/EmailStageForm.ts:96 msgid "Use SSL" msgstr "" @@ -3613,10 +3633,10 @@ msgstr "" #: src/elements/events/UserEvents.ts:36 #: src/pages/events/EventInfo.ts:83 #: src/pages/events/EventListPage.ts:44 -#: src/pages/policies/PolicyBindingForm.ts:140 -#: src/pages/policies/PolicyBindingForm.ts:176 -#: src/pages/policies/PolicyTestForm.ts:60 -#: src/pages/property-mappings/PropertyMappingTestForm.ts:49 +#: src/pages/policies/PolicyBindingForm.ts:133 +#: src/pages/policies/PolicyBindingForm.ts:177 +#: src/pages/policies/PolicyTestForm.ts:61 +#: src/pages/property-mappings/PropertyMappingTestForm.ts:51 #: src/pages/tokens/TokenListPage.ts:45 #: src/pages/user-settings/tokens/UserTokenList.ts:72 #: src/pages/users/UserListPage.ts:88 @@ -3657,7 +3677,7 @@ msgstr "" msgid "User password writeback" msgstr "" -#: src/pages/policies/BoundPoliciesList.ts:52 +#: src/pages/policies/BoundPoliciesList.ts:56 #: src/pages/users/UserViewPage.ts:63 msgid "User {0}" msgstr "" @@ -3712,11 +3732,11 @@ msgstr "" msgid "Using source" msgstr "" -#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:123 +#: src/pages/providers/oauth2/OAuth2ProviderForm.ts:124 msgid "Valid redirect URLs after a successful authorization flow. Also specify any origins here for Implicit flows." msgstr "" -#: src/pages/providers/proxy/ProxyProviderForm.ts:115 +#: src/pages/providers/proxy/ProxyProviderForm.ts:116 msgid "Validate SSL Certificates of upstream servers." msgstr "" @@ -3831,7 +3851,7 @@ msgstr "" msgid "When this option is enabled, all executions of this policy will be logged. By default, only execution errors are logged." msgstr "" -#: src/flows/FlowExecutor.ts:131 +#: src/flows/FlowExecutor.ts:134 msgid "Whoops!" msgstr "" @@ -3854,11 +3874,11 @@ msgid "X509 Subject" msgstr "" #: src/pages/crypto/CertificateKeyPairListPage.ts:61 -#: src/pages/groups/GroupListPage.ts:58 +#: src/pages/groups/GroupListPage.ts:57 #: src/pages/groups/MemberSelectModal.ts:57 #: src/pages/outposts/ServiceConnectionListPage.ts:64 -#: src/pages/policies/BoundPoliciesList.ts:118 -#: src/pages/policies/PolicyTestForm.ts:38 +#: src/pages/policies/BoundPoliciesList.ts:122 +#: src/pages/policies/PolicyTestForm.ts:39 #: src/pages/providers/proxy/ProxyProviderViewPage.ts:105 #: src/pages/tokens/TokenListPage.ts:56 #: src/pages/user-settings/tokens/UserTokenList.ts:83 diff --git a/web/src/pages/admin-overview/AdminOverviewPage.ts b/web/src/pages/admin-overview/AdminOverviewPage.ts index e05535309..a2c59efb7 100644 --- a/web/src/pages/admin-overview/AdminOverviewPage.ts +++ b/web/src/pages/admin-overview/AdminOverviewPage.ts @@ -44,13 +44,13 @@ export class AdminOverviewPage extends LitElement { - + - + - + diff --git a/web/src/pages/applications/ApplicationViewPage.ts b/web/src/pages/applications/ApplicationViewPage.ts index 796ae9ca4..898a9b5f2 100644 --- a/web/src/pages/applications/ApplicationViewPage.ts +++ b/web/src/pages/applications/ApplicationViewPage.ts @@ -134,7 +134,7 @@ export class ApplicationViewPage extends LitElement { -
+
${t`These policies control which users can access this application.`}
diff --git a/web/src/pages/events/EventInfo.ts b/web/src/pages/events/EventInfo.ts index 7203a801b..420e9f4d1 100644 --- a/web/src/pages/events/EventInfo.ts +++ b/web/src/pages/events/EventInfo.ts @@ -190,7 +190,7 @@ export class EventInfo extends LitElement { ${this.defaultResponse()}`; case "update_available": return html`

${t`New version available!`}

- ${this.event.context.new_version} + ${this.event.context.new_version} `; // Action types which typically don't record any extra context. // If context is not empty, we fall to the default response. diff --git a/web/src/pages/events/RuleListPage.ts b/web/src/pages/events/RuleListPage.ts index 4a2741de8..1d7fb74e2 100644 --- a/web/src/pages/events/RuleListPage.ts +++ b/web/src/pages/events/RuleListPage.ts @@ -108,7 +108,7 @@ export class RuleListPage extends TablePage { return html`
-

${t`These policies control upon which events this rule triggers. Bindings to +

${t`These bindings control upon which events this rule triggers. Bindings to groups/users are checked against the user of the event.`}

diff --git a/web/src/pages/flows/BoundStagesList.ts b/web/src/pages/flows/BoundStagesList.ts index 798802027..f54a8b9c0 100644 --- a/web/src/pages/flows/BoundStagesList.ts +++ b/web/src/pages/flows/BoundStagesList.ts @@ -100,7 +100,7 @@ export class BoundStagesList extends Table {
-

${t`These policies control when this stage will be applied to the flow.`}

+

${t`These bindings control if this stage will be applied to the flow.`}

diff --git a/web/src/pages/flows/FlowViewPage.ts b/web/src/pages/flows/FlowViewPage.ts index 0736ba981..af1e12a28 100644 --- a/web/src/pages/flows/FlowViewPage.ts +++ b/web/src/pages/flows/FlowViewPage.ts @@ -104,9 +104,9 @@ export class FlowViewPage extends LitElement {
-
+
-
${t`These policies control which users can access this flow.`}
+
${t`These bindings control which users can access this flow.`}
diff --git a/web/src/pages/groups/GroupForm.ts b/web/src/pages/groups/GroupForm.ts index fdc25c285..f4d5edc4e 100644 --- a/web/src/pages/groups/GroupForm.ts +++ b/web/src/pages/groups/GroupForm.ts @@ -73,7 +73,6 @@ export class GroupForm extends Form {
{ diff --git a/web/src/pages/groups/GroupListPage.ts b/web/src/pages/groups/GroupListPage.ts index e41c9d0b1..2caa7e7d0 100644 --- a/web/src/pages/groups/GroupListPage.ts +++ b/web/src/pages/groups/GroupListPage.ts @@ -53,7 +53,7 @@ export class GroupListPage extends TablePage { return [ html`${item.name}`, html`${item.parent || "-"}`, - html`${item.users?.keys.length}`, + html`${Array.from(item.users || []).length}`, html`${item.isSuperuser ? t`Yes` : t`No`}`, html` diff --git a/web/src/pages/policies/BoundPoliciesList.ts b/web/src/pages/policies/BoundPoliciesList.ts index 27f499d3f..bf93ec5b5 100644 --- a/web/src/pages/policies/BoundPoliciesList.ts +++ b/web/src/pages/policies/BoundPoliciesList.ts @@ -25,6 +25,9 @@ export class BoundPoliciesList extends Table { @property() target?: string; + @property({type: Boolean}) + policyOnly = false; + apiEndpoint(page: number): Promise> { return new PoliciesApi(DEFAULT_CONFIG).policiesBindingsList({ target: this.target || "", @@ -125,7 +128,7 @@ export class BoundPoliciesList extends Table { ${t`Update Binding`} - + +
`; + } + return html` +
+ +
+ +
+ +
+ +
+ +
`; + } + renderForm(): TemplateResult { return html`
-
- -
- -
- -
- -
- -
+ ${this.renderModeSelector()}