Compare commits
	
		
			91 Commits
		
	
	
		
			version/20
			...
			version/20
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 49dfb4756e | |||
| 814758e2aa | |||
| 5c42dac5e2 | |||
| 88603fa4f7 | |||
| 0232c4e162 | |||
| 11753c1fe1 | |||
| f5cc6c67ec | |||
| 8b8ed3527a | |||
| 1aa0274e7c | |||
| ecd33ca0c1 | |||
| e93be0de9a | |||
| a5adc4f8ed | |||
| a6baed9753 | |||
| ceaf832e63 | |||
| a6b0b14685 | |||
| f679250edd | |||
| acc4de2235 | |||
| 56a8276dbf | |||
| 6dfe6edbef | |||
| 6af4bd0d9a | |||
| 7ee7f6bd6a | |||
| f8b8334010 | |||
| d4b65dc4b4 | |||
| e4bbd3b1c0 | |||
| 87de5e625d | |||
| efbe51673e | |||
| a95bea53ea | |||
| 6021fc0f52 | |||
| 1415b68ff4 | |||
| be6853ac52 | |||
| 7fd6be5abb | |||
| 91d6f572a5 | |||
| 016a9ce34e | |||
| 8adb95af7f | |||
| 1dc54775d8 | |||
| 370ef716b5 | |||
| 16e56ad9ca | |||
| b5b5a9eed3 | |||
| 8b22e7bcc3 | |||
| d48b5b9511 | |||
| 0eccaa3f1e | |||
| 67d550a80d | |||
| ebb5711c32 | |||
| 79ec872232 | |||
| 4284e14ff7 | |||
| 92a09779d0 | |||
| 14c621631d | |||
| c55f503b9b | |||
| a908cad976 | |||
| c2586557d8 | |||
| 01c80a82e2 | |||
| 0d47654651 | |||
| 1183095833 | |||
| c281b11bdc | |||
| 61fe45a58c | |||
| d43aab479c | |||
| 7f8383427a | |||
| a06d6cf33d | |||
| 5b7cb205c9 | |||
| 293a932d20 | |||
| fff901ff03 | |||
| f47c936295 | |||
| 88d5aec618 | |||
| 96ae68cf09 | |||
| 63b3434b6f | |||
| 947ecec02b | |||
| 1c2b452406 | |||
| 47777529ac | |||
| 949095c376 | |||
| 4b112c2799 | |||
| 291a2516b1 | |||
| 4dcfd021e2 | |||
| ca50848db3 | |||
| 0bb3e3c558 | |||
| e4b25809ab | |||
| 7bf932f8e2 | |||
| 99d04528b0 | |||
| e48d172036 | |||
| c2388137a8 | |||
| 650e2cbc38 | |||
| b32800ea71 | |||
| e1c0c0b20c | |||
| fe39e39dcd | |||
| 883f213b03 | |||
| 538996f617 | |||
| 2f4c92deb9 | |||
| ef335ec083 | |||
| 07b09df3fe | |||
| e70e031a1f | |||
| c7ba183dc0 | |||
| 3ed23a37ea | 
| @ -1,5 +1,5 @@ | ||||
| [bumpversion] | ||||
| current_version = 2022.1.2 | ||||
| current_version = 2022.1.4 | ||||
| tag = True | ||||
| commit = True | ||||
| parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)\-?(?P<release>.*) | ||||
|  | ||||
							
								
								
									
										16
									
								
								.github/workflows/ci-outpost.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								.github/workflows/ci-outpost.yml
									
									
									
									
										vendored
									
									
								
							| @ -30,9 +30,25 @@ jobs: | ||||
|             -w /app \ | ||||
|             golangci/golangci-lint:v1.43 \ | ||||
|             golangci-lint run -v --timeout 200s | ||||
|   test-unittest: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v2 | ||||
|       - uses: actions/setup-go@v2 | ||||
|         with: | ||||
|           go-version: "^1.17" | ||||
|       - name: Get dependencies | ||||
|         run: | | ||||
|           go get github.com/axw/gocov/gocov | ||||
|           go get github.com/AlekSi/gocov-xml | ||||
|           go get github.com/jstemmer/go-junit-report | ||||
|       - name: Go unittests | ||||
|         run: | | ||||
|           go test -timeout 0 -v -race -coverprofile=coverage.out -covermode=atomic -cover ./... | go-junit-report > junit.xml | ||||
|   ci-outpost-mark: | ||||
|     needs: | ||||
|       - lint-golint | ||||
|       - test-unittest | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - run: echo mark | ||||
|  | ||||
							
								
								
									
										14
									
								
								.github/workflows/release-publish.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/release-publish.yml
									
									
									
									
										vendored
									
									
								
							| @ -30,14 +30,14 @@ jobs: | ||||
|         with: | ||||
|           push: ${{ github.event_name == 'release' }} | ||||
|           tags: | | ||||
|             beryju/authentik:2022.1.2, | ||||
|             beryju/authentik:2022.1.4, | ||||
|             beryju/authentik:latest, | ||||
|             ghcr.io/goauthentik/server:2022.1.2, | ||||
|             ghcr.io/goauthentik/server:2022.1.4, | ||||
|             ghcr.io/goauthentik/server:latest | ||||
|           platforms: linux/amd64,linux/arm64 | ||||
|           context: . | ||||
|       - name: Building Docker Image (stable) | ||||
|         if: ${{ github.event_name == 'release' && !contains('2022.1.2', 'rc') }} | ||||
|         if: ${{ github.event_name == 'release' && !contains('2022.1.4', 'rc') }} | ||||
|         run: | | ||||
|           docker pull beryju/authentik:latest | ||||
|           docker tag beryju/authentik:latest beryju/authentik:stable | ||||
| @ -78,14 +78,14 @@ jobs: | ||||
|         with: | ||||
|           push: ${{ github.event_name == 'release' }} | ||||
|           tags: | | ||||
|             beryju/authentik-${{ matrix.type }}:2022.1.2, | ||||
|             beryju/authentik-${{ matrix.type }}:2022.1.4, | ||||
|             beryju/authentik-${{ matrix.type }}:latest, | ||||
|             ghcr.io/goauthentik/${{ matrix.type }}:2022.1.2, | ||||
|             ghcr.io/goauthentik/${{ matrix.type }}:2022.1.4, | ||||
|             ghcr.io/goauthentik/${{ matrix.type }}:latest | ||||
|           file: ${{ matrix.type }}.Dockerfile | ||||
|           platforms: linux/amd64,linux/arm64 | ||||
|       - name: Building Docker Image (stable) | ||||
|         if: ${{ github.event_name == 'release' && !contains('2022.1.2', 'rc') }} | ||||
|         if: ${{ github.event_name == 'release' && !contains('2022.1.4', 'rc') }} | ||||
|         run: | | ||||
|           docker pull beryju/authentik-${{ matrix.type }}:latest | ||||
|           docker tag beryju/authentik-${{ matrix.type }}:latest beryju/authentik-${{ matrix.type }}:stable | ||||
| @ -170,7 +170,7 @@ jobs: | ||||
|           SENTRY_PROJECT: authentik | ||||
|           SENTRY_URL: https://sentry.beryju.org | ||||
|         with: | ||||
|           version: authentik@2022.1.2 | ||||
|           version: authentik@2022.1.4 | ||||
|           environment: beryjuorg-prod | ||||
|           sourcemaps: './web/dist' | ||||
|           url_prefix: '~/static/dist' | ||||
|  | ||||
							
								
								
									
										3
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								Makefile
									
									
									
									
									
								
							| @ -15,6 +15,9 @@ test-e2e-provider: | ||||
| test-e2e-rest: | ||||
| 	coverage run manage.py test tests/e2e/test_flows* tests/e2e/test_source* | ||||
|  | ||||
| test-go: | ||||
| 	go test -timeout 0 -v -race -cover ./... | ||||
|  | ||||
| test: | ||||
| 	coverage run manage.py test authentik | ||||
| 	coverage html | ||||
|  | ||||
| @ -57,4 +57,4 @@ DigitalOcean provides development and testing resources for authentik. | ||||
|     </a> | ||||
| </p> | ||||
|  | ||||
| Netlify hosts the [goauthentik.io](goauthentik.io) site. | ||||
| Netlify hosts the [goauthentik.io](https://goauthentik.io) site. | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| from os import environ | ||||
| from typing import Optional | ||||
|  | ||||
| __version__ = "2022.1.2" | ||||
| __version__ = "2022.1.4" | ||||
| ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -3,7 +3,7 @@ from typing import Any | ||||
|  | ||||
| from django_filters.rest_framework import DjangoFilterBackend | ||||
| from drf_spectacular.utils import OpenApiResponse, extend_schema | ||||
| from guardian.shortcuts import get_anonymous_user | ||||
| from guardian.shortcuts import assign_perm, get_anonymous_user | ||||
| from rest_framework.decorators import action | ||||
| from rest_framework.exceptions import ValidationError | ||||
| from rest_framework.fields import CharField | ||||
| @ -95,10 +95,12 @@ class TokenViewSet(UsedByMixin, ModelViewSet): | ||||
|  | ||||
|     def perform_create(self, serializer: TokenSerializer): | ||||
|         if not self.request.user.is_superuser: | ||||
|             return serializer.save( | ||||
|             instance = serializer.save( | ||||
|                 user=self.request.user, | ||||
|                 expiring=self.request.user.attributes.get(USER_ATTRIBUTE_TOKEN_EXPIRING, True), | ||||
|             ) | ||||
|             assign_perm("authentik_core.view_token_key", self.request.user, instance) | ||||
|             return instance | ||||
|         return super().perform_create(serializer) | ||||
|  | ||||
|     @permission_required("authentik_core.view_token_key") | ||||
|  | ||||
| @ -30,6 +30,7 @@ class TestTokenAPI(APITestCase): | ||||
|         self.assertEqual(token.user, self.user) | ||||
|         self.assertEqual(token.intent, TokenIntents.INTENT_API) | ||||
|         self.assertEqual(token.expiring, True) | ||||
|         self.assertTrue(self.user.has_perm("authentik_core.view_token_key", token)) | ||||
|  | ||||
|     def test_token_create_invalid(self): | ||||
|         """Test token creation endpoint (invalid data)""" | ||||
|  | ||||
| @ -32,6 +32,7 @@ class BaseEvaluator: | ||||
|         self._globals = { | ||||
|             "regex_match": BaseEvaluator.expr_regex_match, | ||||
|             "regex_replace": BaseEvaluator.expr_regex_replace, | ||||
|             "list_flatten": BaseEvaluator.expr_flatten, | ||||
|             "ak_is_group_member": BaseEvaluator.expr_is_group_member, | ||||
|             "ak_user_by": BaseEvaluator.expr_user_by, | ||||
|             "ak_logger": get_logger(), | ||||
| @ -40,6 +41,15 @@ class BaseEvaluator: | ||||
|         self._context = {} | ||||
|         self._filename = "BaseEvalautor" | ||||
|  | ||||
|     @staticmethod | ||||
|     def expr_flatten(value: list[Any] | Any) -> Optional[Any]: | ||||
|         """Flatten `value` if its a list""" | ||||
|         if isinstance(value, list): | ||||
|             if len(value) < 1: | ||||
|                 return None | ||||
|             return value[0] | ||||
|         return value | ||||
|  | ||||
|     @staticmethod | ||||
|     def expr_regex_match(value: Any, regex: str) -> bool: | ||||
|         """Expression Filter to run re.search""" | ||||
|  | ||||
| @ -23,12 +23,12 @@ class ProxyDockerController(DockerController): | ||||
|             proxy_provider: ProxyProvider | ||||
|             external_host_name = urlparse(proxy_provider.external_host) | ||||
|             hosts.append(f"`{external_host_name.netloc}`") | ||||
|         traefik_name = f"ak-outpost-{self.outpost.pk.hex}" | ||||
|         traefik_name = self.name | ||||
|         labels = super()._get_labels() | ||||
|         labels["traefik.enable"] = "true" | ||||
|         labels[ | ||||
|             f"traefik.http.routers.{traefik_name}-router.rule" | ||||
|         ] = f"Host({','.join(hosts)}) && PathPrefix('/akprox')" | ||||
|         ] = f"Host({','.join(hosts)}) && PathPrefix(`/akprox`)" | ||||
|         labels[f"traefik.http.routers.{traefik_name}-router.tls"] = "true" | ||||
|         labels[f"traefik.http.routers.{traefik_name}-router.service"] = f"{traefik_name}-service" | ||||
|         labels[ | ||||
|  | ||||
| @ -1,14 +1,4 @@ | ||||
| """ | ||||
| Django settings for authentik project. | ||||
|  | ||||
| Generated by 'django-admin startproject' using Django 2.1.3. | ||||
|  | ||||
| For more information on this file, see | ||||
| https://docs.djangoproject.com/en/2.1/topics/settings/ | ||||
|  | ||||
| For the full list of settings and their values, see | ||||
| https://docs.djangoproject.com/en/2.1/ref/settings/ | ||||
| """ | ||||
| """root settings for authentik""" | ||||
|  | ||||
| import importlib | ||||
| import logging | ||||
| @ -18,24 +8,22 @@ from hashlib import sha512 | ||||
| from json import dumps | ||||
| from tempfile import gettempdir | ||||
| from time import time | ||||
| from urllib.parse import quote | ||||
| from urllib.parse import quote_plus | ||||
|  | ||||
| import structlog | ||||
| from celery.schedules import crontab | ||||
| from sentry_sdk import init as sentry_init | ||||
| from sentry_sdk.api import set_tag | ||||
| from sentry_sdk.integrations.boto3 import Boto3Integration | ||||
| from sentry_sdk.integrations.celery import CeleryIntegration | ||||
| from sentry_sdk.integrations.django import DjangoIntegration | ||||
| from sentry_sdk.integrations.redis import RedisIntegration | ||||
| from sentry_sdk.integrations.threading import ThreadingIntegration | ||||
|  | ||||
| from authentik import ENV_GIT_HASH_KEY, __version__, get_build_hash, get_full_version | ||||
| from authentik import ENV_GIT_HASH_KEY, __version__, get_build_hash | ||||
| from authentik.core.middleware import structlog_add_request_id | ||||
| from authentik.lib.config import CONFIG | ||||
| from authentik.lib.logging import add_process_id | ||||
| from authentik.lib.sentry import before_send | ||||
| from authentik.lib.utils.http import get_http_session | ||||
| from authentik.lib.utils.reflection import get_env | ||||
| from authentik.stages.password import BACKEND_APP_PASSWORD, BACKEND_INBUILT, BACKEND_LDAP | ||||
|  | ||||
| @ -220,7 +208,7 @@ if CONFIG.y_bool("redis.tls", False): | ||||
|     REDIS_CELERY_TLS_REQUIREMENTS = f"?ssl_cert_reqs={CONFIG.y('redis.tls_reqs')}" | ||||
| _redis_url = ( | ||||
|     f"{REDIS_PROTOCOL_PREFIX}:" | ||||
|     f"{quote(CONFIG.y('redis.password'))}@{quote(CONFIG.y('redis.host'))}:" | ||||
|     f"{quote_plus(CONFIG.y('redis.password'))}@{quote_plus(CONFIG.y('redis.host'))}:" | ||||
|     f"{int(CONFIG.y('redis.port'))}" | ||||
| ) | ||||
|  | ||||
| @ -347,6 +335,7 @@ LOCALE_PATHS = ["./locale"] | ||||
| # Celery settings | ||||
| # Add a 10 minute timeout to all Celery tasks. | ||||
| CELERY_TASK_SOFT_TIME_LIMIT = 600 | ||||
| CELERY_WORKER_MAX_TASKS_PER_CHILD = 50 | ||||
| CELERY_BEAT_SCHEDULE = { | ||||
|     "clean_expired_models": { | ||||
|         "task": "authentik.core.tasks.clean_expired_models", | ||||
| @ -407,7 +396,6 @@ if _ERROR_REPORTING: | ||||
|             DjangoIntegration(transaction_style="function_name"), | ||||
|             CeleryIntegration(), | ||||
|             RedisIntegration(), | ||||
|             Boto3Integration(), | ||||
|             ThreadingIntegration(propagate_hub=True), | ||||
|         ], | ||||
|         before_send=before_send, | ||||
| @ -424,29 +412,6 @@ if _ERROR_REPORTING: | ||||
|         "Error reporting is enabled", | ||||
|         env=CONFIG.y("error_reporting.environment", "customer"), | ||||
|     ) | ||||
| if not CONFIG.y_bool("disable_startup_analytics", False): | ||||
|     should_send = env not in ["dev", "ci"] | ||||
|     if should_send: | ||||
|         try: | ||||
|             get_http_session().post( | ||||
|                 "https://goauthentik.io/api/event", | ||||
|                 json={ | ||||
|                     "domain": "authentik", | ||||
|                     "name": "pageview", | ||||
|                     "referrer": get_full_version(), | ||||
|                     "url": ( | ||||
|                         f"http://localhost/{env}?utm_source={get_full_version()}&utm_medium={env}" | ||||
|                     ), | ||||
|                 }, | ||||
|                 headers={ | ||||
|                     "User-Agent": sha512(str(SECRET_KEY).encode("ascii")).hexdigest()[:16], | ||||
|                     "Content-Type": "application/json", | ||||
|                 }, | ||||
|                 timeout=5, | ||||
|             ) | ||||
|         # pylint: disable=bare-except | ||||
|         except:  # nosec | ||||
|             pass | ||||
|  | ||||
| # Static files (CSS, JavaScript, Images) | ||||
| # https://docs.djangoproject.com/en/2.1/howto/static-files/ | ||||
|  | ||||
| @ -35,21 +35,21 @@ class LDAPProviderManager(ObjectManager): | ||||
|                 "goauthentik.io/sources/ldap/ms-userprincipalname", | ||||
|                 name="authentik default Active Directory Mapping: userPrincipalName", | ||||
|                 object_field="attributes.upn", | ||||
|                 expression="return ldap.get('userPrincipalName')", | ||||
|                 expression="return list_flatten(ldap.get('userPrincipalName'))", | ||||
|             ), | ||||
|             EnsureExists( | ||||
|                 LDAPPropertyMapping, | ||||
|                 "goauthentik.io/sources/ldap/ms-givenName", | ||||
|                 name="authentik default Active Directory Mapping: givenName", | ||||
|                 object_field="attributes.givenName", | ||||
|                 expression="return ldap.get('givenName')", | ||||
|                 expression="return list_flatten(ldap.get('givenName'))", | ||||
|             ), | ||||
|             EnsureExists( | ||||
|                 LDAPPropertyMapping, | ||||
|                 "goauthentik.io/sources/ldap/ms-sn", | ||||
|                 name="authentik default Active Directory Mapping: sn", | ||||
|                 object_field="attributes.sn", | ||||
|                 expression="return ldap.get('sn')", | ||||
|                 expression="return list_flatten(ldap.get('sn'))", | ||||
|             ), | ||||
|             # OpenLDAP specific mappings | ||||
|             EnsureExists( | ||||
|  | ||||
| @ -8,6 +8,7 @@ import ( | ||||
| 	log "github.com/sirupsen/logrus" | ||||
|  | ||||
| 	"goauthentik.io/internal/common" | ||||
| 	"goauthentik.io/internal/debug" | ||||
| 	"goauthentik.io/internal/outpost/ak" | ||||
| 	"goauthentik.io/internal/outpost/ldap" | ||||
| ) | ||||
| @ -27,6 +28,7 @@ func main() { | ||||
| 			log.FieldKeyTime: "timestamp", | ||||
| 		}, | ||||
| 	}) | ||||
| 	go debug.EnableDebugServer() | ||||
| 	akURL, found := os.LookupEnv("AUTHENTIK_HOST") | ||||
| 	if !found { | ||||
| 		fmt.Println("env AUTHENTIK_HOST not set!") | ||||
|  | ||||
| @ -9,6 +9,7 @@ import ( | ||||
| 	log "github.com/sirupsen/logrus" | ||||
|  | ||||
| 	"goauthentik.io/internal/common" | ||||
| 	"goauthentik.io/internal/debug" | ||||
| 	"goauthentik.io/internal/outpost/ak" | ||||
| 	"goauthentik.io/internal/outpost/proxyv2" | ||||
| ) | ||||
| @ -32,6 +33,7 @@ func main() { | ||||
| 			log.FieldKeyTime: "timestamp", | ||||
| 		}, | ||||
| 	}) | ||||
| 	go debug.EnableDebugServer() | ||||
| 	akURL, found := os.LookupEnv("AUTHENTIK_HOST") | ||||
| 	if !found { | ||||
| 		fmt.Println("env AUTHENTIK_HOST not set!") | ||||
|  | ||||
| @ -11,6 +11,7 @@ import ( | ||||
| 	"goauthentik.io/internal/common" | ||||
| 	"goauthentik.io/internal/config" | ||||
| 	"goauthentik.io/internal/constants" | ||||
| 	"goauthentik.io/internal/debug" | ||||
| 	"goauthentik.io/internal/gounicorn" | ||||
| 	"goauthentik.io/internal/outpost/ak" | ||||
| 	"goauthentik.io/internal/outpost/proxyv2" | ||||
| @ -28,6 +29,7 @@ func main() { | ||||
| 			log.FieldKeyTime: "timestamp", | ||||
| 		}, | ||||
| 	}) | ||||
| 	go debug.EnableDebugServer() | ||||
| 	l := log.WithField("logger", "authentik.root") | ||||
| 	config.DefaultConfig() | ||||
| 	err := config.LoadConfig("./authentik/lib/default.yml") | ||||
|  | ||||
| @ -17,7 +17,7 @@ services: | ||||
|     image: redis:alpine | ||||
|     restart: unless-stopped | ||||
|   server: | ||||
|     image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.1.2} | ||||
|     image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.1.4} | ||||
|     restart: unless-stopped | ||||
|     command: server | ||||
|     environment: | ||||
| @ -38,7 +38,7 @@ services: | ||||
|       - "0.0.0.0:${AUTHENTIK_PORT_HTTP:-9000}:9000" | ||||
|       - "0.0.0.0:${AUTHENTIK_PORT_HTTPS:-9443}:9443" | ||||
|   worker: | ||||
|     image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.1.2} | ||||
|     image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2022.1.4} | ||||
|     restart: unless-stopped | ||||
|     command: worker | ||||
|     environment: | ||||
|  | ||||
							
								
								
									
										6
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.mod
									
									
									
									
									
								
							| @ -9,7 +9,7 @@ require ( | ||||
| 	github.com/garyburd/redigo v1.6.2 // indirect | ||||
| 	github.com/getsentry/sentry-go v0.12.0 | ||||
| 	github.com/go-ldap/ldap/v3 v3.4.1 | ||||
| 	github.com/go-openapi/runtime v0.21.1 | ||||
| 	github.com/go-openapi/runtime v0.22.0 | ||||
| 	github.com/go-openapi/strfmt v0.21.1 | ||||
| 	github.com/golang-jwt/jwt v3.2.2+incompatible | ||||
| 	github.com/google/uuid v1.3.0 | ||||
| @ -25,8 +25,10 @@ require ( | ||||
| 	github.com/pires/go-proxyproto v0.6.1 | ||||
| 	github.com/pkg/errors v0.9.1 | ||||
| 	github.com/pquerna/cachecontrol v0.0.0-20201205024021-ac21108117ac // indirect | ||||
| 	github.com/prometheus/client_golang v1.12.0 | ||||
| 	github.com/prometheus/client_golang v1.12.1 | ||||
| 	github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b | ||||
| 	github.com/sirupsen/logrus v1.8.1 | ||||
| 	github.com/stretchr/testify v1.7.0 | ||||
| 	goauthentik.io/api v0.2021125.1 | ||||
| 	golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c | ||||
| 	golang.org/x/sync v0.0.0-20210220032951-036812b2e83c | ||||
|  | ||||
							
								
								
									
										10
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								go.sum
									
									
									
									
									
								
							| @ -183,8 +183,8 @@ github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g | ||||
| github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= | ||||
| github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= | ||||
| github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= | ||||
| github.com/go-openapi/runtime v0.21.1 h1:/KIG00BzA2x2HRStX2tnhbqbQdPcFlkgsYCiNY20FZs= | ||||
| github.com/go-openapi/runtime v0.21.1/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs= | ||||
| github.com/go-openapi/runtime v0.22.0 h1:vY2D0u807kkcwidaj0YJuq4zyAWQnjLNDpJcVBrUFNs= | ||||
| github.com/go-openapi/runtime v0.22.0/go.mod h1:aQg+kaIQEn+A2CRSY1TxbM8+sT9g2V3aLc1FbIAnbbs= | ||||
| github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= | ||||
| github.com/go-openapi/spec v0.18.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= | ||||
| github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= | ||||
| @ -471,8 +471,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP | ||||
| github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= | ||||
| github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= | ||||
| github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= | ||||
| github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= | ||||
| github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= | ||||
| github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= | ||||
| github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= | ||||
| github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= | ||||
| github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||
| github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= | ||||
| @ -489,6 +489,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O | ||||
| github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= | ||||
| github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= | ||||
| github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= | ||||
| github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b h1:aUNXCGgukb4gtY99imuIeoh8Vr0GSwAlYxPAhqZrpFc= | ||||
| github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b/go.mod h1:wTPjTepVu7uJBYgZ0SdWHQlIas582j6cn2jgk4DDdlg= | ||||
| github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
|  | ||||
| @ -25,4 +25,4 @@ func OutpostUserAgent() string { | ||||
| 	return fmt.Sprintf("authentik-outpost@%s", FullVersion()) | ||||
| } | ||||
|  | ||||
| const VERSION = "2022.1.2" | ||||
| const VERSION = "2022.1.4" | ||||
|  | ||||
							
								
								
									
										24
									
								
								internal/debug/debug.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								internal/debug/debug.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| package debug | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/http/pprof" | ||||
| 	"os" | ||||
| 	"strings" | ||||
|  | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| ) | ||||
|  | ||||
| func EnableDebugServer() { | ||||
| 	l := log.WithField("logger", "authentik.go_debugger") | ||||
| 	if deb := os.Getenv("AUTHENTIK_DEBUG"); strings.ToLower(deb) != "true" { | ||||
| 		l.Info("not enabling debug server, set `AUTHENTIK_DEBUG` to `true` to enable it.") | ||||
| 	} | ||||
| 	h := http.NewServeMux() | ||||
| 	h.HandleFunc("/debug/pprof/", pprof.Index) | ||||
| 	h.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline) | ||||
| 	h.HandleFunc("/debug/pprof/profile", pprof.Profile) | ||||
| 	h.HandleFunc("/debug/pprof/symbol", pprof.Symbol) | ||||
| 	h.HandleFunc("/debug/pprof/trace", pprof.Trace) | ||||
| 	l.Println(http.ListenAndServe("0.0.0.0:9900", nil)) | ||||
| } | ||||
							
								
								
									
										66
									
								
								internal/outpost/ak/test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								internal/outpost/ak/test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,66 @@ | ||||
| package ak | ||||
|  | ||||
| import ( | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
| 	"math/rand" | ||||
| 	"net/http" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/google/uuid" | ||||
| 	"github.com/gorilla/securecookie" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| 	"goauthentik.io/api" | ||||
| ) | ||||
|  | ||||
| func TestSecret() string { | ||||
| 	return base64.RawURLEncoding.EncodeToString(securecookie.GenerateRandomKey(32)) | ||||
| } | ||||
|  | ||||
| func MockConfig() api.Config { | ||||
| 	return *api.NewConfig( | ||||
| 		*api.NewErrorReportingConfig(false, "test", false, 0.0), | ||||
| 		[]api.CapabilitiesEnum{}, | ||||
| 		100, | ||||
| 		100, | ||||
| 		100, | ||||
| 		100, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| func MockAK(outpost api.Outpost, globalConfig api.Config) *APIController { | ||||
| 	config := api.NewConfiguration() | ||||
| 	config.HTTPClient = &http.Client{ | ||||
| 		Transport: GetTLSTransport(), | ||||
| 	} | ||||
| 	token := TestSecret() | ||||
| 	config.AddDefaultHeader("Authorization", fmt.Sprintf("Bearer %s", token)) | ||||
|  | ||||
| 	// create the API client, with the transport | ||||
| 	apiClient := api.NewAPIClient(config) | ||||
|  | ||||
| 	log := log.WithField("logger", "authentik.outpost.ak-api-controller") | ||||
|  | ||||
| 	log.WithField("name", outpost.Name).Debug("Fetched outpost configuration") | ||||
|  | ||||
| 	log.Debug("Fetched global configuration") | ||||
|  | ||||
| 	// doGlobalSetup is called by the OnRefresh handler, which ticks on start | ||||
| 	// doGlobalSetup(outpost, akConfig) | ||||
|  | ||||
| 	ac := &APIController{ | ||||
| 		Client:       apiClient, | ||||
| 		GlobalConfig: globalConfig, | ||||
|  | ||||
| 		token:  token, | ||||
| 		logger: log, | ||||
|  | ||||
| 		reloadOffset:        time.Duration(rand.Intn(10)) * time.Second, | ||||
| 		instanceUUID:        uuid.New(), | ||||
| 		Outpost:             outpost, | ||||
| 		wsBackoffMultiplier: 1, | ||||
| 		refreshHandlers:     make([]func(), 0), | ||||
| 	} | ||||
| 	ac.logger.WithField("offset", ac.reloadOffset.String()).Debug("HA Reload offset") | ||||
| 	return ac | ||||
| } | ||||
| @ -16,6 +16,7 @@ import ( | ||||
| 	"goauthentik.io/internal/outpost/ldap/flags" | ||||
| 	"goauthentik.io/internal/outpost/ldap/metrics" | ||||
| 	"goauthentik.io/internal/outpost/ldap/server" | ||||
| 	"goauthentik.io/internal/outpost/ldap/utils" | ||||
| ) | ||||
|  | ||||
| const ContextUserKey = "ak_user" | ||||
| @ -35,7 +36,7 @@ func NewDirectBinder(si server.LDAPServerInstance) *DirectBinder { | ||||
| } | ||||
|  | ||||
| func (db *DirectBinder) GetUsername(dn string) (string, error) { | ||||
| 	if !strings.HasSuffix(strings.ToLower(dn), strings.ToLower(db.si.GetBaseDN())) { | ||||
| 	if !utils.HasSuffixNoCase(dn, db.si.GetBaseDN()) { | ||||
| 		return "", errors.New("invalid base DN") | ||||
| 	} | ||||
| 	dns, err := goldap.ParseDN(dn) | ||||
|  | ||||
| @ -140,26 +140,26 @@ func (pi *ProviderInstance) GetNeededObjects(scope int, baseDN string, filterOC | ||||
| 	// If our requested base DN doesn't match any of the container DNs, then | ||||
| 	// we're probably loading a user or group. If it does, then make sure our | ||||
| 	// scope will eventually take us to users or groups. | ||||
| 	if (baseDN == pi.BaseDN || strings.HasSuffix(baseDN, pi.UserDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetUserOCs()) { | ||||
| 	if (strings.EqualFold(baseDN, pi.BaseDN) || utils.HasSuffixNoCase(baseDN, pi.UserDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetUserOCs()) { | ||||
| 		if baseDN != pi.UserDN && baseDN != pi.BaseDN || | ||||
| 			baseDN == pi.BaseDN && scope > 1 || | ||||
| 			baseDN == pi.UserDN && scope > 0 { | ||||
| 			strings.EqualFold(baseDN, pi.BaseDN) && scope > 1 || | ||||
| 			strings.EqualFold(baseDN, pi.UserDN) && scope > 0 { | ||||
| 			needUsers = true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (baseDN == pi.BaseDN || strings.HasSuffix(baseDN, pi.GroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetGroupOCs()) { | ||||
| 	if (strings.EqualFold(baseDN, pi.BaseDN) || utils.HasSuffixNoCase(baseDN, pi.GroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetGroupOCs()) { | ||||
| 		if baseDN != pi.GroupDN && baseDN != pi.BaseDN || | ||||
| 			baseDN == pi.BaseDN && scope > 1 || | ||||
| 			baseDN == pi.GroupDN && scope > 0 { | ||||
| 			strings.EqualFold(baseDN, pi.BaseDN) && scope > 1 || | ||||
| 			strings.EqualFold(baseDN, pi.GroupDN) && scope > 0 { | ||||
| 			needGroups = true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (baseDN == pi.BaseDN || strings.HasSuffix(baseDN, pi.VirtualGroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetVirtualGroupOCs()) { | ||||
| 	if (strings.EqualFold(baseDN, pi.BaseDN) || utils.HasSuffixNoCase(baseDN, pi.VirtualGroupDN)) && utils.IncludeObjectClass(filterOC, ldapConstants.GetVirtualGroupOCs()) { | ||||
| 		if baseDN != pi.VirtualGroupDN && baseDN != pi.BaseDN || | ||||
| 			baseDN == pi.BaseDN && scope > 1 || | ||||
| 			baseDN == pi.VirtualGroupDN && scope > 0 { | ||||
| 			strings.EqualFold(baseDN, pi.BaseDN) && scope > 1 || | ||||
| 			strings.EqualFold(baseDN, pi.VirtualGroupDN) && scope > 0 { | ||||
| 			needUsers = true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -36,7 +36,7 @@ func NewDirectSearcher(si server.LDAPServerInstance) *DirectSearcher { | ||||
|  | ||||
| func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, error) { | ||||
| 	accsp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.check_access") | ||||
| 	baseDN := strings.ToLower(ds.si.GetBaseDN()) | ||||
| 	baseDN := ds.si.GetBaseDN() | ||||
|  | ||||
| 	filterOC, err := ldap.GetFilterObjectClass(req.Filter) | ||||
| 	if err != nil { | ||||
| @ -59,7 +59,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		}).Inc() | ||||
| 		return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultInsufficientAccessRights}, fmt.Errorf("Search Error: Anonymous BindDN not allowed %s", req.BindDN) | ||||
| 	} | ||||
| 	if !strings.HasSuffix(req.BindDN, ","+baseDN) { | ||||
| 	if !utils.HasSuffixNoCase(req.BindDN, ","+baseDN) { | ||||
| 		metrics.RequestsRejected.With(prometheus.Labels{ | ||||
| 			"outpost_name": ds.si.GetOutpostName(), | ||||
| 			"type":         "search", | ||||
| @ -105,7 +105,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 	scope := req.SearchRequest.Scope | ||||
| 	needUsers, needGroups := ds.si.GetNeededObjects(scope, req.BaseDN, filterOC) | ||||
|  | ||||
| 	if scope >= 0 && req.BaseDN == baseDN { | ||||
| 	if scope >= 0 && strings.EqualFold(req.BaseDN, baseDN) { | ||||
| 		if utils.IncludeObjectClass(filterOC, constants.GetDomainOCs()) { | ||||
| 			entries = append(entries, ds.si.GetBaseEntry()) | ||||
| 		} | ||||
| @ -209,8 +209,8 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, err | ||||
| 	} | ||||
|  | ||||
| 	if scope >= 0 && (req.BaseDN == ds.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ds.si.GetBaseUserDN())) { | ||||
| 		singleu := strings.HasSuffix(req.BaseDN, ","+ds.si.GetBaseUserDN()) | ||||
| 	if scope >= 0 && (strings.EqualFold(req.BaseDN, ds.si.GetBaseDN()) || utils.HasSuffixNoCase(req.BaseDN, ds.si.GetBaseUserDN())) { | ||||
| 		singleu := utils.HasSuffixNoCase(req.BaseDN, ","+ds.si.GetBaseUserDN()) | ||||
|  | ||||
| 		if !singleu && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { | ||||
| 			entries = append(entries, utils.GetContainerEntry(filterOC, ds.si.GetBaseUserDN(), constants.OUUsers)) | ||||
| @ -220,7 +220,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		if scope >= 0 && users != nil && utils.IncludeObjectClass(filterOC, constants.GetUserOCs()) { | ||||
| 			for _, u := range *users { | ||||
| 				entry := ds.si.UserEntry(u) | ||||
| 				if req.BaseDN == entry.DN || !singleu { | ||||
| 				if strings.EqualFold(req.BaseDN, entry.DN) || !singleu { | ||||
| 					entries = append(entries, entry) | ||||
| 				} | ||||
| 			} | ||||
| @ -229,8 +229,8 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		scope += 1 // Return the scope to what it was before we descended | ||||
| 	} | ||||
|  | ||||
| 	if scope >= 0 && (req.BaseDN == ds.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ds.si.GetBaseGroupDN())) { | ||||
| 		singleg := strings.HasSuffix(req.BaseDN, ","+ds.si.GetBaseGroupDN()) | ||||
| 	if scope >= 0 && (strings.EqualFold(req.BaseDN, ds.si.GetBaseDN()) || utils.HasSuffixNoCase(req.BaseDN, ds.si.GetBaseGroupDN())) { | ||||
| 		singleg := utils.HasSuffixNoCase(req.BaseDN, ","+ds.si.GetBaseGroupDN()) | ||||
|  | ||||
| 		if !singleg && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { | ||||
| 			entries = append(entries, utils.GetContainerEntry(filterOC, ds.si.GetBaseGroupDN(), constants.OUGroups)) | ||||
| @ -240,7 +240,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		if scope >= 0 && groups != nil && utils.IncludeObjectClass(filterOC, constants.GetGroupOCs()) { | ||||
| 			for _, g := range *groups { | ||||
| 				entry := group.FromAPIGroup(g, ds.si).Entry() | ||||
| 				if req.BaseDN == entry.DN || !singleg { | ||||
| 				if strings.EqualFold(req.BaseDN, entry.DN) || !singleg { | ||||
| 					entries = append(entries, entry) | ||||
| 				} | ||||
| 			} | ||||
| @ -249,8 +249,8 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		scope += 1 // Return the scope to what it was before we descended | ||||
| 	} | ||||
|  | ||||
| 	if scope >= 0 && (req.BaseDN == ds.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ds.si.GetBaseVirtualGroupDN())) { | ||||
| 		singlevg := strings.HasSuffix(req.BaseDN, ","+ds.si.GetBaseVirtualGroupDN()) | ||||
| 	if scope >= 0 && (strings.EqualFold(req.BaseDN, ds.si.GetBaseDN()) || utils.HasSuffixNoCase(req.BaseDN, ds.si.GetBaseVirtualGroupDN())) { | ||||
| 		singlevg := utils.HasSuffixNoCase(req.BaseDN, ","+ds.si.GetBaseVirtualGroupDN()) | ||||
|  | ||||
| 		if !singlevg || utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { | ||||
| 			entries = append(entries, utils.GetContainerEntry(filterOC, ds.si.GetBaseVirtualGroupDN(), constants.OUVirtualGroups)) | ||||
| @ -260,7 +260,7 @@ func (ds *DirectSearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		if scope >= 0 && users != nil && utils.IncludeObjectClass(filterOC, constants.GetVirtualGroupOCs()) { | ||||
| 			for _, u := range *users { | ||||
| 				entry := group.FromAPIUser(u, ds.si).Entry() | ||||
| 				if req.BaseDN == entry.DN || !singlevg { | ||||
| 				if strings.EqualFold(req.BaseDN, entry.DN) || !singlevg { | ||||
| 					entries = append(entries, entry) | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @ -39,7 +39,7 @@ func NewMemorySearcher(si server.LDAPServerInstance) *MemorySearcher { | ||||
|  | ||||
| func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, error) { | ||||
| 	accsp := sentry.StartSpan(req.Context(), "authentik.providers.ldap.search.check_access") | ||||
| 	baseDN := strings.ToLower(ms.si.GetBaseDN()) | ||||
| 	baseDN := ms.si.GetBaseDN() | ||||
|  | ||||
| 	filterOC, err := ldap.GetFilterObjectClass(req.Filter) | ||||
| 	if err != nil { | ||||
| @ -62,7 +62,7 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		}).Inc() | ||||
| 		return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultInsufficientAccessRights}, fmt.Errorf("Search Error: Anonymous BindDN not allowed %s", req.BindDN) | ||||
| 	} | ||||
| 	if !strings.HasSuffix(req.BindDN, ","+baseDN) { | ||||
| 	if !utils.HasSuffixNoCase(req.BindDN, ","+baseDN) { | ||||
| 		metrics.RequestsRejected.With(prometheus.Labels{ | ||||
| 			"outpost_name": ms.si.GetOutpostName(), | ||||
| 			"type":         "search", | ||||
| @ -92,7 +92,7 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 	scope := req.SearchRequest.Scope | ||||
| 	needUsers, needGroups := ms.si.GetNeededObjects(scope, req.BaseDN, filterOC) | ||||
|  | ||||
| 	if scope >= 0 && req.BaseDN == baseDN { | ||||
| 	if scope >= 0 && strings.EqualFold(req.BaseDN, baseDN) { | ||||
| 		if utils.IncludeObjectClass(filterOC, constants.GetDomainOCs()) { | ||||
| 			entries = append(entries, ms.si.GetBaseEntry()) | ||||
| 		} | ||||
| @ -155,8 +155,8 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		return ldap.ServerSearchResult{ResultCode: ldap.LDAPResultOperationsError}, err | ||||
| 	} | ||||
|  | ||||
| 	if scope >= 0 && (req.BaseDN == ms.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ms.si.GetBaseUserDN())) { | ||||
| 		singleu := strings.HasSuffix(req.BaseDN, ","+ms.si.GetBaseUserDN()) | ||||
| 	if scope >= 0 && (strings.EqualFold(req.BaseDN, ms.si.GetBaseDN()) || utils.HasSuffixNoCase(req.BaseDN, ms.si.GetBaseUserDN())) { | ||||
| 		singleu := utils.HasSuffixNoCase(req.BaseDN, ","+ms.si.GetBaseUserDN()) | ||||
|  | ||||
| 		if !singleu && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { | ||||
| 			entries = append(entries, utils.GetContainerEntry(filterOC, ms.si.GetBaseUserDN(), constants.OUUsers)) | ||||
| @ -166,7 +166,7 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		if scope >= 0 && users != nil && utils.IncludeObjectClass(filterOC, constants.GetUserOCs()) { | ||||
| 			for _, u := range *users { | ||||
| 				entry := ms.si.UserEntry(u) | ||||
| 				if req.BaseDN == entry.DN || !singleu { | ||||
| 				if strings.EqualFold(req.BaseDN, entry.DN) || !singleu { | ||||
| 					entries = append(entries, entry) | ||||
| 				} | ||||
| 			} | ||||
| @ -175,8 +175,8 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		scope += 1 // Return the scope to what it was before we descended | ||||
| 	} | ||||
|  | ||||
| 	if scope >= 0 && (req.BaseDN == ms.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ms.si.GetBaseGroupDN())) { | ||||
| 		singleg := strings.HasSuffix(req.BaseDN, ","+ms.si.GetBaseGroupDN()) | ||||
| 	if scope >= 0 && (strings.EqualFold(req.BaseDN, ms.si.GetBaseDN()) || utils.HasSuffixNoCase(req.BaseDN, ms.si.GetBaseGroupDN())) { | ||||
| 		singleg := utils.HasSuffixNoCase(req.BaseDN, ","+ms.si.GetBaseGroupDN()) | ||||
|  | ||||
| 		if !singleg && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { | ||||
| 			entries = append(entries, utils.GetContainerEntry(filterOC, ms.si.GetBaseGroupDN(), constants.OUGroups)) | ||||
| @ -185,7 +185,7 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
|  | ||||
| 		if scope >= 0 && groups != nil && utils.IncludeObjectClass(filterOC, constants.GetGroupOCs()) { | ||||
| 			for _, g := range groups { | ||||
| 				if req.BaseDN == g.DN || !singleg { | ||||
| 				if strings.EqualFold(req.BaseDN, g.DN) || !singleg { | ||||
| 					entries = append(entries, g.Entry()) | ||||
| 				} | ||||
| 			} | ||||
| @ -194,8 +194,8 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		scope += 1 // Return the scope to what it was before we descended | ||||
| 	} | ||||
|  | ||||
| 	if scope >= 0 && (req.BaseDN == ms.si.GetBaseDN() || strings.HasSuffix(req.BaseDN, ms.si.GetBaseVirtualGroupDN())) { | ||||
| 		singlevg := strings.HasSuffix(req.BaseDN, ","+ms.si.GetBaseVirtualGroupDN()) | ||||
| 	if scope >= 0 && (strings.EqualFold(req.BaseDN, ms.si.GetBaseDN()) || utils.HasSuffixNoCase(req.BaseDN, ms.si.GetBaseVirtualGroupDN())) { | ||||
| 		singlevg := utils.HasSuffixNoCase(req.BaseDN, ","+ms.si.GetBaseVirtualGroupDN()) | ||||
|  | ||||
| 		if !singlevg && utils.IncludeObjectClass(filterOC, constants.GetContainerOCs()) { | ||||
| 			entries = append(entries, utils.GetContainerEntry(filterOC, ms.si.GetBaseVirtualGroupDN(), constants.OUVirtualGroups)) | ||||
| @ -205,7 +205,7 @@ func (ms *MemorySearcher) Search(req *search.Request) (ldap.ServerSearchResult, | ||||
| 		if scope >= 0 && users != nil && utils.IncludeObjectClass(filterOC, constants.GetVirtualGroupOCs()) { | ||||
| 			for _, u := range *users { | ||||
| 				entry := group.FromAPIUser(u, ms.si).Entry() | ||||
| 				if req.BaseDN == entry.DN || !singlevg { | ||||
| 				if strings.EqualFold(req.BaseDN, entry.DN) || !singlevg { | ||||
| 					entries = append(entries, entry) | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @ -26,7 +26,6 @@ type Request struct { | ||||
| func NewRequest(bindDN string, searchReq ldap.SearchRequest, conn net.Conn) (*Request, *sentry.Span) { | ||||
| 	rid := uuid.New().String() | ||||
| 	bindDN = strings.ToLower(bindDN) | ||||
| 	searchReq.BaseDN = strings.ToLower(searchReq.BaseDN) | ||||
| 	span := sentry.StartSpan(context.TODO(), "authentik.providers.ldap.search", sentry.TransactionName("authentik.providers.ldap.search")) | ||||
| 	span.Description = fmt.Sprintf("%s (%s)", searchReq.BaseDN, ldap.ScopeMap[searchReq.Scope]) | ||||
| 	span.SetTag("request_uid", rid) | ||||
|  | ||||
| @ -2,6 +2,7 @@ package utils | ||||
|  | ||||
| import ( | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/nmcclain/ldap" | ||||
| 	log "github.com/sirupsen/logrus" | ||||
| @ -117,3 +118,7 @@ func GetContainerEntry(filterOC string, dn string, ou string) *ldap.Entry { | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func HasSuffixNoCase(s1 string, s2 string) bool { | ||||
| 	return strings.HasSuffix(strings.ToLower(s1), strings.ToLower(s2)) | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,8 @@ | ||||
| package utils | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	goldap "github.com/go-ldap/ldap/v3" | ||||
| 	ber "github.com/nmcclain/asn1-ber" | ||||
| 	"github.com/nmcclain/ldap" | ||||
| @ -41,7 +43,7 @@ func parseFilterForGroupSingle(req api.ApiCoreGroupsListRequest, f *ber.Packet) | ||||
| 	// Switch on type of the value, then check the key | ||||
| 	switch vv := v.(type) { | ||||
| 	case string: | ||||
| 		switch k { | ||||
| 		switch strings.ToLower(k.(string)) { | ||||
| 		case "cn": | ||||
| 			return req.Name(vv), false | ||||
| 		case "member": | ||||
| @ -54,7 +56,7 @@ func parseFilterForGroupSingle(req api.ApiCoreGroupsListRequest, f *ber.Packet) | ||||
| 			username := userDN.RDNs[0].Attributes[0].Value | ||||
| 			// If the DN's first ou is virtual-groups, ignore this filter | ||||
| 			if len(userDN.RDNs) > 1 { | ||||
| 				if userDN.RDNs[1].Attributes[0].Value == constants.OUVirtualGroups || userDN.RDNs[1].Attributes[0].Value == constants.OUGroups { | ||||
| 				if strings.EqualFold(userDN.RDNs[1].Attributes[0].Value, constants.OUVirtualGroups) || strings.EqualFold(userDN.RDNs[1].Attributes[0].Value, constants.OUGroups) { | ||||
| 					// Since we know we're not filtering anything, skip this request | ||||
| 					return req, true | ||||
| 				} | ||||
|  | ||||
| @ -46,6 +46,7 @@ type Application struct { | ||||
|  | ||||
| 	log *log.Entry | ||||
| 	mux *mux.Router | ||||
| 	ak  *ak.APIController | ||||
|  | ||||
| 	errorTemplates *template.Template | ||||
| } | ||||
| @ -93,6 +94,7 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore | ||||
| 		httpClient:     c, | ||||
| 		mux:            mux, | ||||
| 		errorTemplates: templates.GetTemplates(), | ||||
| 		ak:             ak, | ||||
| 	} | ||||
| 	a.sessions = a.getStore(p) | ||||
| 	mux.Use(web.NewLoggingHandler(muxLogger, func(l *log.Entry, r *http.Request) *log.Entry { | ||||
|  | ||||
| @ -1,7 +1,8 @@ | ||||
| package application | ||||
|  | ||||
| type ProxyClaims struct { | ||||
| 	UserAttributes map[string]interface{} `json:"user_attributes"` | ||||
| 	UserAttributes  map[string]interface{} `json:"user_attributes"` | ||||
| 	BackendOverride string                 `json:"backend_override"` | ||||
| } | ||||
|  | ||||
| type Claims struct { | ||||
|  | ||||
| @ -1,7 +1,9 @@ | ||||
| package application | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| @ -57,7 +59,8 @@ func (a *Application) addHeaders(headers http.Header, c *Claims) { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (a *Application) getTraefikForwardUrl(r *http.Request) *url.URL { | ||||
| // getTraefikForwardUrl See https://doc.traefik.io/traefik/middlewares/forwardauth/ | ||||
| func (a *Application) getTraefikForwardUrl(r *http.Request) (*url.URL, error) { | ||||
| 	u, err := url.Parse(fmt.Sprintf( | ||||
| 		"%s://%s%s", | ||||
| 		r.Header.Get("X-Forwarded-Proto"), | ||||
| @ -65,33 +68,63 @@ func (a *Application) getTraefikForwardUrl(r *http.Request) *url.URL { | ||||
| 		r.Header.Get("X-Forwarded-Uri"), | ||||
| 	)) | ||||
| 	if err != nil { | ||||
| 		a.log.WithError(err).Warning("Failed to parse URL from traefik") | ||||
| 		return r.URL | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	a.log.WithField("url", u.String()).Trace("traefik forwarded url") | ||||
| 	return u | ||||
| 	return u, nil | ||||
| } | ||||
|  | ||||
| func (a *Application) IsAllowlisted(r *http.Request) bool { | ||||
| 	url := r.URL | ||||
| 	// In Forward auth mode, we can't directly match against the requested URL | ||||
| 	// Since that would be /akprox/auth/... | ||||
| 	if a.Mode() == api.PROXYMODE_FORWARD_SINGLE || a.Mode() == api.PROXYMODE_FORWARD_DOMAIN { | ||||
| 		// For traefik, we can get the Upstream URL from headers | ||||
| 		// For nginx we can attempt to as well, but it's not guaranteed to work. | ||||
| 		if strings.HasPrefix(r.URL.Path, "/akprox/auth") { | ||||
| 			url = a.getTraefikForwardUrl(r) | ||||
| // getNginxForwardUrl See https://github.com/kubernetes/ingress-nginx/blob/main/rootfs/etc/nginx/template/nginx.tmpl | ||||
| func (a *Application) getNginxForwardUrl(r *http.Request) (*url.URL, error) { | ||||
| 	ou := r.Header.Get("X-Original-URI") | ||||
| 	if ou != "" { | ||||
| 		// Turn this full URL into a relative URL | ||||
| 		u := &url.URL{ | ||||
| 			Host:   "", | ||||
| 			Scheme: "", | ||||
| 			Path:   ou, | ||||
| 		} | ||||
| 		a.log.WithField("url", u.String()).Info("building forward URL from X-Original-URI") | ||||
| 		return u, nil | ||||
| 	} | ||||
| 	for _, u := range a.UnauthenticatedRegex { | ||||
| 	h := r.Header.Get("X-Original-URL") | ||||
| 	if len(h) < 1 { | ||||
| 		return nil, errors.New("no forward URL found") | ||||
| 	} | ||||
| 	u, err := url.Parse(h) | ||||
| 	if err != nil { | ||||
| 		a.log.WithError(err).Warning("failed to parse URL from nginx") | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	a.log.WithField("url", u.String()).Trace("nginx forwarded url") | ||||
| 	return u, nil | ||||
| } | ||||
|  | ||||
| func (a *Application) ReportMisconfiguration(r *http.Request, msg string, fields map[string]interface{}) { | ||||
| 	fields["message"] = msg | ||||
| 	a.log.WithFields(fields).Error("Reporting configuration error") | ||||
| 	req := api.EventRequest{ | ||||
| 		Action:   api.EVENTACTIONS_CONFIGURATION_ERROR, | ||||
| 		App:      "authentik.providers.proxy", // must match python apps.py name | ||||
| 		ClientIp: *api.NewNullableString(api.PtrString(r.RemoteAddr)), | ||||
| 		Context:  &fields, | ||||
| 	} | ||||
| 	_, _, err := a.ak.Client.EventsApi.EventsEventsCreate(context.Background()).EventRequest(req).Execute() | ||||
| 	if err != nil { | ||||
| 		a.log.WithError(err).Warning("failed to report configuration error") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (a *Application) IsAllowlisted(u *url.URL) bool { | ||||
| 	for _, ur := range a.UnauthenticatedRegex { | ||||
| 		var testString string | ||||
| 		if a.Mode() == api.PROXYMODE_PROXY || a.Mode() == api.PROXYMODE_FORWARD_SINGLE { | ||||
| 			testString = url.Path | ||||
| 			testString = u.Path | ||||
| 		} else { | ||||
| 			testString = url.String() | ||||
| 			testString = u.String() | ||||
| 		} | ||||
| 		a.log.WithField("regex", u.String()).WithField("url", testString).Trace("Matching URL against allow list") | ||||
| 		if u.MatchString(testString) { | ||||
| 		if ur.MatchString(testString) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @ -25,13 +25,27 @@ func (a *Application) configureForward() error { | ||||
| } | ||||
|  | ||||
| func (a *Application) forwardHandleTraefik(rw http.ResponseWriter, r *http.Request) { | ||||
| 	a.log.WithField("header", r.Header).Trace("tracing headers for debug") | ||||
| 	// First check if we've got everything we need | ||||
| 	fwd, err := a.getTraefikForwardUrl(r) | ||||
| 	if err != nil { | ||||
| 		a.ReportMisconfiguration(r, fmt.Sprintf("Outpost %s (Provider %s) failed to detect a forward URL from Traefik", a.outpostName, a.proxyConfig.Name), map[string]interface{}{ | ||||
| 			"provider": a.proxyConfig.Name, | ||||
| 			"outpost":  a.outpostName, | ||||
| 			"url":      r.URL.String(), | ||||
| 			"headers":  cleanseHeaders(r.Header), | ||||
| 		}) | ||||
| 		http.Error(rw, "configuration error", http.StatusInternalServerError) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	claims, err := a.getClaims(r) | ||||
| 	if claims != nil && err == nil { | ||||
| 		a.addHeaders(rw.Header(), claims) | ||||
| 		rw.Header().Set("User-Agent", r.Header.Get("User-Agent")) | ||||
| 		a.log.WithField("headers", rw.Header()).Trace("headers written to forward_auth") | ||||
| 		return | ||||
| 	} else if claims == nil && a.IsAllowlisted(r) { | ||||
| 	} else if claims == nil && a.IsAllowlisted(fwd) { | ||||
| 		a.log.Trace("path can be accessed without authentication") | ||||
| 		return | ||||
| 	} | ||||
| @ -45,15 +59,18 @@ func (a *Application) forwardHandleTraefik(rw http.ResponseWriter, r *http.Reque | ||||
| 	if *a.proxyConfig.Mode == api.PROXYMODE_FORWARD_SINGLE { | ||||
| 		host = web.GetHost(r) | ||||
| 	} else if *a.proxyConfig.Mode == api.PROXYMODE_FORWARD_DOMAIN { | ||||
| 		eh, _ := url.Parse(a.proxyConfig.ExternalHost) | ||||
| 		host = eh.Host | ||||
| 		eh, err := url.Parse(a.proxyConfig.ExternalHost) | ||||
| 		if err != nil { | ||||
| 			a.log.WithField("host", a.proxyConfig.ExternalHost).WithError(err).Warning("invalid external_host") | ||||
| 		} else { | ||||
| 			host = eh.Host | ||||
| 		} | ||||
| 	} | ||||
| 	// set the redirect flag to the current URL we have, since we redirect | ||||
| 	// to a (possibly) different domain, but we want to be redirected back | ||||
| 	// to the application | ||||
| 	// see https://doc.traefik.io/traefik/middlewares/forwardauth/ | ||||
| 	// X-Forwarded-Uri is only the path, so we need to build the entire URL | ||||
| 	s.Values[constants.SessionRedirect] = a.getTraefikForwardUrl(r).String() | ||||
| 	s.Values[constants.SessionRedirect] = fwd.String() | ||||
| 	err = s.Save(r, rw) | ||||
| 	if err != nil { | ||||
| 		a.log.WithError(err).Warning("failed to save session before redirect") | ||||
| @ -69,6 +86,19 @@ func (a *Application) forwardHandleTraefik(rw http.ResponseWriter, r *http.Reque | ||||
| } | ||||
|  | ||||
| func (a *Application) forwardHandleNginx(rw http.ResponseWriter, r *http.Request) { | ||||
| 	a.log.WithField("header", r.Header).Trace("tracing headers for debug") | ||||
| 	fwd, err := a.getNginxForwardUrl(r) | ||||
| 	if err != nil { | ||||
| 		a.ReportMisconfiguration(r, fmt.Sprintf("Outpost %s (Provider %s) failed to detect a forward URL from nginx", a.outpostName, a.proxyConfig.Name), map[string]interface{}{ | ||||
| 			"provider": a.proxyConfig.Name, | ||||
| 			"outpost":  a.outpostName, | ||||
| 			"url":      r.URL.String(), | ||||
| 			"headers":  cleanseHeaders(r.Header), | ||||
| 		}) | ||||
| 		http.Error(rw, "configuration error", http.StatusInternalServerError) | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	claims, err := a.getClaims(r) | ||||
| 	if claims != nil && err == nil { | ||||
| 		a.addHeaders(rw.Header(), claims) | ||||
| @ -76,13 +106,20 @@ func (a *Application) forwardHandleNginx(rw http.ResponseWriter, r *http.Request | ||||
| 		rw.WriteHeader(200) | ||||
| 		a.log.WithField("headers", rw.Header()).Trace("headers written to forward_auth") | ||||
| 		return | ||||
| 	} else if claims == nil && a.IsAllowlisted(r) { | ||||
| 	} else if claims == nil && a.IsAllowlisted(fwd) { | ||||
| 		a.log.Trace("path can be accessed without authentication") | ||||
| 		return | ||||
| 	} | ||||
| 	fwu := a.getTraefikForwardUrl(r) | ||||
| 	if fwu.String() != r.URL.String() { | ||||
| 		if strings.HasPrefix(fwu.Path, "/akprox") { | ||||
|  | ||||
| 	s, _ := a.sessions.Get(r, constants.SeesionName) | ||||
| 	s.Values[constants.SessionRedirect] = fwd.String() | ||||
| 	err = s.Save(r, rw) | ||||
| 	if err != nil { | ||||
| 		a.log.WithError(err).Warning("failed to save session before redirect") | ||||
| 	} | ||||
|  | ||||
| 	if fwd.String() != r.URL.String() { | ||||
| 		if strings.HasPrefix(fwd.Path, "/akprox") { | ||||
| 			a.log.WithField("url", r.URL.String()).Trace("path begins with /akprox, allowing access") | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
							
								
								
									
										134
									
								
								internal/outpost/proxyv2/application/mode_forward_nginx_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								internal/outpost/proxyv2/application/mode_forward_nginx_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | ||||
| package application | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"goauthentik.io/api" | ||||
| 	"goauthentik.io/internal/outpost/proxyv2/constants" | ||||
| ) | ||||
|  | ||||
| func TestForwardHandleNginx_Single_Blank(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil) | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleNginx(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusInternalServerError, rr.Code) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleNginx_Single_Skip(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil) | ||||
| 	req.Header.Set("X-Original-URL", "http://test.goauthentik.io/skip") | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleNginx(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusOK, rr.Code) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleNginx_Single_Headers(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil) | ||||
| 	req.Header.Set("X-Original-URL", "http://test.goauthentik.io/app") | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleNginx(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, rr.Code, http.StatusUnauthorized) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect]) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleNginx_Single_URI(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	req, _ := http.NewRequest("GET", "https://foo.bar/akprox/auth/nginx", nil) | ||||
| 	req.Header.Set("X-Original-URI", "/app") | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleNginx(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, rr.Code, http.StatusUnauthorized) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	assert.Equal(t, "/app", s.Values[constants.SessionRedirect]) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleNginx_Single_Claims(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil) | ||||
| 	req.Header.Set("X-Original-URI", "/") | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleNginx(rr, req) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	s.Values[constants.SessionClaims] = Claims{ | ||||
| 		Sub: "foo", | ||||
| 		Proxy: ProxyClaims{ | ||||
| 			UserAttributes: map[string]interface{}{ | ||||
| 				"username": "foo", | ||||
| 				"password": "bar", | ||||
| 				"additionalHeaders": map[string]interface{}{ | ||||
| 					"foo": "bar", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	err := a.sessions.Save(req, rr, s) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
|  | ||||
| 	rr = httptest.NewRecorder() | ||||
| 	a.forwardHandleNginx(rr, req) | ||||
|  | ||||
| 	h := rr.Result().Header | ||||
|  | ||||
| 	assert.Equal(t, []string{"Basic Zm9vOmJhcg=="}, h["Authorization"]) | ||||
| 	assert.Equal(t, []string{"bar"}, h["Foo"]) | ||||
| 	assert.Equal(t, []string{""}, h["User-Agent"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Email"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Groups"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Jwt"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Meta-App"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Meta-Jwks"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Meta-Outpost"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Name"]) | ||||
| 	assert.Equal(t, []string{"foo"}, h["X-Authentik-Uid"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Username"]) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleNginx_Domain_Blank(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr() | ||||
| 	a.proxyConfig.CookieDomain = api.PtrString("foo") | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil) | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleNginx(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusInternalServerError, rr.Code) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleNginx_Domain_Header(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr() | ||||
| 	a.proxyConfig.CookieDomain = api.PtrString("foo") | ||||
| 	a.proxyConfig.ExternalHost = "http://auth.test.goauthentik.io" | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/nginx", nil) | ||||
| 	req.Header.Set("X-Original-URL", "http://test.goauthentik.io/app") | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleNginx(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusUnauthorized, rr.Code) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect]) | ||||
| } | ||||
| @ -0,0 +1,132 @@ | ||||
| package application | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"goauthentik.io/api" | ||||
| 	"goauthentik.io/internal/outpost/proxyv2/constants" | ||||
| ) | ||||
|  | ||||
| func TestForwardHandleTraefik_Single_Blank(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil) | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleTraefik(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusInternalServerError, rr.Code) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleTraefik_Single_Skip(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil) | ||||
| 	req.Header.Set("X-Forwarded-Proto", "http") | ||||
| 	req.Header.Set("X-Forwarded-Host", "test.goauthentik.io") | ||||
| 	req.Header.Set("X-Forwarded-Uri", "/skip") | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleTraefik(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusOK, rr.Code) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleTraefik_Single_Headers(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil) | ||||
| 	req.Header.Set("X-Forwarded-Proto", "http") | ||||
| 	req.Header.Set("X-Forwarded-Host", "test.goauthentik.io") | ||||
| 	req.Header.Set("X-Forwarded-Uri", "/app") | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleTraefik(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, rr.Code, http.StatusTemporaryRedirect) | ||||
| 	loc, _ := rr.Result().Location() | ||||
| 	assert.Equal(t, loc.String(), "http://test.goauthentik.io/akprox/start") | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect]) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleTraefik_Single_Claims(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil) | ||||
| 	req.Header.Set("X-Forwarded-Proto", "http") | ||||
| 	req.Header.Set("X-Forwarded-Host", "test.goauthentik.io") | ||||
| 	req.Header.Set("X-Forwarded-Uri", "/app") | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleTraefik(rr, req) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	s.Values[constants.SessionClaims] = Claims{ | ||||
| 		Sub: "foo", | ||||
| 		Proxy: ProxyClaims{ | ||||
| 			UserAttributes: map[string]interface{}{ | ||||
| 				"username": "foo", | ||||
| 				"password": "bar", | ||||
| 				"additionalHeaders": map[string]interface{}{ | ||||
| 					"foo": "bar", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	err := a.sessions.Save(req, rr, s) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
|  | ||||
| 	rr = httptest.NewRecorder() | ||||
| 	a.forwardHandleTraefik(rr, req) | ||||
|  | ||||
| 	h := rr.Result().Header | ||||
|  | ||||
| 	assert.Equal(t, []string{"Basic Zm9vOmJhcg=="}, h["Authorization"]) | ||||
| 	assert.Equal(t, []string{"bar"}, h["Foo"]) | ||||
| 	assert.Equal(t, []string{""}, h["User-Agent"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Email"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Groups"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Jwt"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Meta-App"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Meta-Jwks"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Meta-Outpost"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Name"]) | ||||
| 	assert.Equal(t, []string{"foo"}, h["X-Authentik-Uid"]) | ||||
| 	assert.Equal(t, []string{""}, h["X-Authentik-Username"]) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleTraefik_Domain_Blank(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr() | ||||
| 	a.proxyConfig.CookieDomain = api.PtrString("foo") | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil) | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleTraefik(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusInternalServerError, rr.Code) | ||||
| } | ||||
|  | ||||
| func TestForwardHandleTraefik_Domain_Header(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr() | ||||
| 	a.proxyConfig.CookieDomain = api.PtrString("foo") | ||||
| 	a.proxyConfig.ExternalHost = "http://auth.test.goauthentik.io" | ||||
| 	req, _ := http.NewRequest("GET", "/akprox/auth/traefik", nil) | ||||
| 	req.Header.Set("X-Forwarded-Proto", "http") | ||||
| 	req.Header.Set("X-Forwarded-Host", "test.goauthentik.io") | ||||
| 	req.Header.Set("X-Forwarded-Uri", "/app") | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.forwardHandleTraefik(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusTemporaryRedirect, rr.Code) | ||||
| 	loc, _ := rr.Result().Location() | ||||
| 	assert.Equal(t, "http://auth.test.goauthentik.io/akprox/start", loc.String()) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect]) | ||||
| } | ||||
| @ -35,7 +35,7 @@ func (a *Application) configureProxy() error { | ||||
| 	rp.ModifyResponse = a.proxyModifyResponse | ||||
| 	a.mux.PathPrefix("/").HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | ||||
| 		claims, err := a.getClaims(r) | ||||
| 		if claims == nil && a.IsAllowlisted(r) { | ||||
| 		if claims == nil && a.IsAllowlisted(r.URL) { | ||||
| 			a.log.Trace("path can be accessed without authentication") | ||||
| 		} else if claims == nil && err != nil { | ||||
| 			a.redirectToStart(rw, r) | ||||
| @ -60,7 +60,7 @@ func (a *Application) configureProxy() error { | ||||
| 		} | ||||
| 		metrics.UpstreamTiming.With(prometheus.Labels{ | ||||
| 			"outpost_name":  a.outpostName, | ||||
| 			"upstream_host": u.String(), | ||||
| 			"upstream_host": r.URL.Host, | ||||
| 			"scheme":        r.URL.Scheme, | ||||
| 			"method":        r.Method, | ||||
| 			"path":          r.URL.Path, | ||||
| @ -71,13 +71,24 @@ func (a *Application) configureProxy() error { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (a *Application) proxyModifyRequest(u *url.URL) func(req *http.Request) { | ||||
| 	return func(req *http.Request) { | ||||
| 		req.URL.Scheme = u.Scheme | ||||
| 		req.URL.Host = u.Host | ||||
| func (a *Application) proxyModifyRequest(ou *url.URL) func(req *http.Request) { | ||||
| 	return func(r *http.Request) { | ||||
| 		claims, _ := a.getClaims(r) | ||||
| 		if claims.Proxy.BackendOverride != "" { | ||||
| 			u, err := url.Parse(claims.Proxy.BackendOverride) | ||||
| 			if err != nil { | ||||
| 				a.log.WithField("backend_override", claims.Proxy.BackendOverride).WithError(err).Warning("failed parse user backend override") | ||||
| 			} | ||||
| 			r.URL.Scheme = u.Scheme | ||||
| 			r.URL.Host = u.Host | ||||
| 		} else { | ||||
| 			r.URL.Scheme = ou.Scheme | ||||
| 			r.URL.Host = ou.Host | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (a *Application) proxyModifyResponse(res *http.Response) error { | ||||
| 	res.Header.Set("X-Powered-By", "authentik_proxy2") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
							
								
								
									
										40
									
								
								internal/outpost/proxyv2/application/test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								internal/outpost/proxyv2/application/test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| package application | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
|  | ||||
| 	"github.com/quasoft/memstore" | ||||
| 	"goauthentik.io/api" | ||||
| 	"goauthentik.io/internal/outpost/ak" | ||||
| ) | ||||
|  | ||||
| func newTestApplication() *Application { | ||||
| 	a, _ := NewApplication( | ||||
| 		api.ProxyOutpostConfig{ | ||||
| 			Name:                       ak.TestSecret(), | ||||
| 			ClientId:                   api.PtrString(ak.TestSecret()), | ||||
| 			ClientSecret:               api.PtrString(ak.TestSecret()), | ||||
| 			CookieSecret:               api.PtrString(ak.TestSecret()), | ||||
| 			CookieDomain:               api.PtrString(""), | ||||
| 			Mode:                       api.PROXYMODE_FORWARD_SINGLE.Ptr(), | ||||
| 			SkipPathRegex:              api.PtrString("/skip.*"), | ||||
| 			BasicAuthEnabled:           api.PtrBool(true), | ||||
| 			BasicAuthUserAttribute:     api.PtrString("username"), | ||||
| 			BasicAuthPasswordAttribute: api.PtrString("password"), | ||||
| 		}, | ||||
| 		http.DefaultClient, | ||||
| 		nil, | ||||
| 		ak.MockAK( | ||||
| 			api.Outpost{ | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"authentik_host": ak.TestSecret(), | ||||
| 				}, | ||||
| 			}, | ||||
| 			ak.MockConfig(), | ||||
| 		), | ||||
| 	) | ||||
| 	a.sessions = memstore.NewMemStore( | ||||
| 		[]byte(ak.TestSecret()), | ||||
| 	) | ||||
| 	return a | ||||
| } | ||||
| @ -26,21 +26,14 @@ func (a *Application) redirectToStart(rw http.ResponseWriter, r *http.Request) { | ||||
| 	if err == nil { | ||||
| 		a.log.WithError(err).Warning("failed to decode session") | ||||
| 	} | ||||
| 	redirectUrl := r.URL.String() | ||||
| 	// simple way to copy the URL | ||||
| 	u, _ := url.Parse(redirectUrl) | ||||
| 	// In proxy and forward_single mode we only have one URL that we route on | ||||
| 	// if we somehow got here without that URL, make sure we're at least redirected back to it | ||||
| 	if a.Mode() == api.PROXYMODE_PROXY || a.Mode() == api.PROXYMODE_FORWARD_SINGLE { | ||||
| 		u.Host = a.proxyConfig.ExternalHost | ||||
| 	} | ||||
| 	redirectUrl := urlJoin(a.proxyConfig.ExternalHost, r.URL.Path) | ||||
| 	if a.Mode() == api.PROXYMODE_FORWARD_DOMAIN { | ||||
| 		dom := strings.TrimPrefix(*a.proxyConfig.CookieDomain, ".") | ||||
| 		// In forward_domain we only check that the current URL's host | ||||
| 		// ends with the cookie domain (remove the leading period if set) | ||||
| 		if !strings.HasSuffix(r.URL.Hostname(), dom) { | ||||
| 			a.log.WithField("url", r.URL.String()).WithField("cd", dom).Warning("Invalid redirect found") | ||||
| 			redirectUrl = "" | ||||
| 			redirectUrl = a.proxyConfig.ExternalHost | ||||
| 		} | ||||
| 	} | ||||
| 	s.Values[constants.SessionRedirect] = redirectUrl | ||||
| @ -94,3 +87,13 @@ func contains(s []string, e string) bool { | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func cleanseHeaders(headers http.Header) map[string]string { | ||||
| 	h := make(map[string]string) | ||||
| 	for hk, hv := range headers { | ||||
| 		if len(hv) > 0 { | ||||
| 			h[hk] = hv[0] | ||||
| 		} | ||||
| 	} | ||||
| 	return h | ||||
| } | ||||
|  | ||||
							
								
								
									
										81
									
								
								internal/outpost/proxyv2/application/utils_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								internal/outpost/proxyv2/application/utils_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,81 @@ | ||||
| package application | ||||
|  | ||||
| import ( | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"goauthentik.io/api" | ||||
| 	"goauthentik.io/internal/outpost/proxyv2/constants" | ||||
| ) | ||||
|  | ||||
| func TestRedirectToStart_Proxy(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	a.proxyConfig.Mode = api.PROXYMODE_PROXY.Ptr() | ||||
| 	a.proxyConfig.ExternalHost = "https://test.goauthentik.io" | ||||
| 	req, _ := http.NewRequest("GET", "/foo/bar/baz", nil) | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.redirectToStart(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusFound, rr.Code) | ||||
| 	loc, _ := rr.Result().Location() | ||||
| 	assert.Equal(t, "https://test.goauthentik.io/akprox/start", loc.String()) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	assert.Equal(t, "https://test.goauthentik.io/foo/bar/baz", s.Values[constants.SessionRedirect]) | ||||
| } | ||||
|  | ||||
| func TestRedirectToStart_Forward(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	a.proxyConfig.Mode = api.PROXYMODE_FORWARD_SINGLE.Ptr() | ||||
| 	a.proxyConfig.ExternalHost = "https://test.goauthentik.io" | ||||
| 	req, _ := http.NewRequest("GET", "/foo/bar/baz", nil) | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.redirectToStart(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusFound, rr.Code) | ||||
| 	loc, _ := rr.Result().Location() | ||||
| 	assert.Equal(t, "https://test.goauthentik.io/akprox/start", loc.String()) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	assert.Equal(t, "https://test.goauthentik.io/foo/bar/baz", s.Values[constants.SessionRedirect]) | ||||
| } | ||||
|  | ||||
| func TestRedirectToStart_Forward_Domain_Invalid(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	a.proxyConfig.CookieDomain = api.PtrString("foo") | ||||
| 	a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr() | ||||
| 	a.proxyConfig.ExternalHost = "https://test.goauthentik.io" | ||||
| 	req, _ := http.NewRequest("GET", "/foo/bar/baz", nil) | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.redirectToStart(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusFound, rr.Code) | ||||
| 	loc, _ := rr.Result().Location() | ||||
| 	assert.Equal(t, "https://test.goauthentik.io/akprox/start", loc.String()) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	assert.Equal(t, "https://test.goauthentik.io", s.Values[constants.SessionRedirect]) | ||||
| } | ||||
|  | ||||
| func TestRedirectToStart_Forward_Domain(t *testing.T) { | ||||
| 	a := newTestApplication() | ||||
| 	a.proxyConfig.CookieDomain = api.PtrString("goauthentik.io") | ||||
| 	a.proxyConfig.Mode = api.PROXYMODE_FORWARD_DOMAIN.Ptr() | ||||
| 	a.proxyConfig.ExternalHost = "https://test.goauthentik.io" | ||||
| 	req, _ := http.NewRequest("GET", "/foo/bar/baz", nil) | ||||
|  | ||||
| 	rr := httptest.NewRecorder() | ||||
| 	a.redirectToStart(rr, req) | ||||
|  | ||||
| 	assert.Equal(t, http.StatusFound, rr.Code) | ||||
| 	loc, _ := rr.Result().Location() | ||||
| 	assert.Equal(t, "https://test.goauthentik.io/akprox/start", loc.String()) | ||||
|  | ||||
| 	s, _ := a.sessions.Get(req, constants.SeesionName) | ||||
| 	assert.Equal(t, "https://test.goauthentik.io", s.Values[constants.SessionRedirect]) | ||||
| } | ||||
| @ -8,6 +8,7 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/prometheus/client_golang/prometheus" | ||||
| 	"goauthentik.io/api" | ||||
| 	"goauthentik.io/internal/outpost/proxyv2/application" | ||||
| 	"goauthentik.io/internal/outpost/proxyv2/metrics" | ||||
| 	"goauthentik.io/internal/utils/web" | ||||
| @ -58,6 +59,9 @@ func (ps *ProxyServer) lookupApp(r *http.Request) (*application.Application, str | ||||
| 	var longestMatch *application.Application | ||||
| 	longestMatchLength := 0 | ||||
| 	for _, app := range ps.apps { | ||||
| 		if app.Mode() != api.PROXYMODE_FORWARD_DOMAIN { | ||||
| 			continue | ||||
| 		} | ||||
| 		// Check if the cookie domain has a leading period for a wildcard | ||||
| 		// This will decrease the weight of a wildcard domain, but a request to example.com | ||||
| 		// with the cookie domain set to example.com will still be routed correctly. | ||||
| @ -70,6 +74,11 @@ func (ps *ProxyServer) lookupApp(r *http.Request) (*application.Application, str | ||||
| 		} | ||||
| 		longestMatch = app | ||||
| 		longestMatchLength = len(cd) | ||||
| 		// Also for forward_auth_domain, we need to respond on the external domain | ||||
| 		if app.ProxyConfig().ExternalHost == host { | ||||
| 			ps.log.WithField("host", host).WithField("app", app.ProxyConfig().Name).Debug("Found app based on external_host") | ||||
| 			return app, host | ||||
| 		} | ||||
| 	} | ||||
| 	// Check if our longes match is 0, in which case we didn't match, so we | ||||
| 	// manually return no app | ||||
|  | ||||
| @ -46,7 +46,7 @@ func NewProxyServer(ac *ak.APIController, portOffset int) *ProxyServer { | ||||
| 	rootMux.Use(func(h http.Handler) http.Handler { | ||||
| 		return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { | ||||
| 			h.ServeHTTP(rw, r) | ||||
| 			rw.Header().Set("Server", "authentik_proxy2") | ||||
| 			rw.Header().Set("X-Powered-By", "authentik_proxy2") | ||||
| 		}) | ||||
| 	}) | ||||
|  | ||||
| @ -91,7 +91,7 @@ func (ps *ProxyServer) TimerFlowCacheExpiry() {} | ||||
| func (ps *ProxyServer) GetCertificate(serverName string) *tls.Certificate { | ||||
| 	app, ok := ps.apps[serverName] | ||||
| 	if !ok { | ||||
| 		ps.log.WithField("server-name", serverName).Debug("app does not exist") | ||||
| 		ps.log.WithField("server-name", serverName).Debug("failed to get certificate for ServerName") | ||||
| 		return nil | ||||
| 	} | ||||
| 	if app.Cert == nil { | ||||
| @ -151,17 +151,14 @@ func (ps *ProxyServer) Start() error { | ||||
| 	wg.Add(3) | ||||
| 	go func() { | ||||
| 		defer wg.Done() | ||||
| 		ps.log.Debug("Starting HTTP Server...") | ||||
| 		ps.ServeHTTP() | ||||
| 	}() | ||||
| 	go func() { | ||||
| 		defer wg.Done() | ||||
| 		ps.log.Debug("Starting HTTPs Server...") | ||||
| 		ps.ServeHTTPS() | ||||
| 	}() | ||||
| 	go func() { | ||||
| 		defer wg.Done() | ||||
| 		ps.log.Debug("Starting Metrics Server...") | ||||
| 		metrics.RunServer() | ||||
| 	}() | ||||
| 	return nil | ||||
|  | ||||
| @ -99,14 +99,14 @@ func (h loggingHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) { | ||||
| 	h.handler.ServeHTTP(responseLogger, req) | ||||
| 	duration := float64(time.Since(t)) / float64(time.Millisecond) | ||||
| 	h.afterHandler(h.logger.WithFields(log.Fields{ | ||||
| 		"remote":            req.RemoteAddr, | ||||
| 		"host":              GetHost(req), | ||||
| 		"request_protocol":  req.Proto, | ||||
| 		"runtime":           fmt.Sprintf("%0.3f", duration), | ||||
| 		"method":            req.Method, | ||||
| 		"size":              responseLogger.Size(), | ||||
| 		"status":            responseLogger.Status(), | ||||
| 		"upstream":          responseLogger.upstream, | ||||
| 		"request_useragent": req.UserAgent(), | ||||
| 		"remote":     req.RemoteAddr, | ||||
| 		"host":       GetHost(req), | ||||
| 		"runtime":    fmt.Sprintf("%0.3f", duration), | ||||
| 		"method":     req.Method, | ||||
| 		"scheme":     req.URL.Scheme, | ||||
| 		"size":       responseLogger.Size(), | ||||
| 		"status":     responseLogger.Status(), | ||||
| 		"upstream":   responseLogger.upstream, | ||||
| 		"user_agent": req.UserAgent(), | ||||
| 	}), req).Info(url.RequestURI()) | ||||
| } | ||||
|  | ||||
| @ -74,6 +74,6 @@ func (ws *WebServer) proxyErrorHandler(rw http.ResponseWriter, req *http.Request | ||||
| } | ||||
|  | ||||
| func (ws *WebServer) proxyModifyResponse(r *http.Response) error { | ||||
| 	r.Header.Set("server", "authentik") | ||||
| 	r.Header.Set("X-Powered-By", "authentik") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @ -69,6 +69,7 @@ if [[ "$1" == "server" ]]; then | ||||
|     python -m lifecycle.migrate | ||||
|     /authentik-proxy | ||||
| elif [[ "$1" == "worker" ]]; then | ||||
|     wait_for_db | ||||
|     echo "worker" > $MODE_FILE | ||||
|     check_if_root "celery -A authentik.root.celery worker -Ofair --max-tasks-per-child=1 --autoscale 3,1 -E -B -s /tmp/celerybeat-schedule -Q authentik,authentik_scheduled,authentik_events" | ||||
| elif [[ "$1" == "flower" ]]; then | ||||
|  | ||||
| @ -1,13 +1,18 @@ | ||||
| """Gunicorn config""" | ||||
| import os | ||||
| import pwd | ||||
| from hashlib import sha512 | ||||
| from multiprocessing import cpu_count | ||||
|  | ||||
| import structlog | ||||
| from kubernetes.config.incluster_config import SERVICE_HOST_ENV_NAME | ||||
|  | ||||
| from authentik import get_full_version | ||||
| from authentik.lib.config import CONFIG | ||||
| from authentik.lib.utils.http import get_http_session | ||||
| from authentik.lib.utils.reflection import get_env | ||||
|  | ||||
| bind = "127.0.0.1:8000" | ||||
| reload = True | ||||
|  | ||||
| try: | ||||
|     pwd.getpwnam("authentik") | ||||
| @ -23,6 +28,9 @@ if os.path.exists("/dev/shm"):  # nosec | ||||
|  | ||||
| os.environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings") | ||||
|  | ||||
| max_requests = 1000 | ||||
| max_requests_jitter = 50 | ||||
|  | ||||
| logconfig_dict = { | ||||
|     "version": 1, | ||||
|     "disable_existing_loggers": False, | ||||
| @ -67,3 +75,31 @@ def worker_exit(server, worker): | ||||
|     from prometheus_client import multiprocess | ||||
|  | ||||
|     multiprocess.mark_process_dead(worker.pid) | ||||
|  | ||||
|  | ||||
| if not CONFIG.y_bool("disable_startup_analytics", False): | ||||
|     env = get_env() | ||||
|     should_send = env not in ["dev", "ci"] | ||||
|     if should_send: | ||||
|         try: | ||||
|             get_http_session().post( | ||||
|                 "https://goauthentik.io/api/event", | ||||
|                 json={ | ||||
|                     "domain": "authentik", | ||||
|                     "name": "pageview", | ||||
|                     "referrer": get_full_version(), | ||||
|                     "url": ( | ||||
|                         f"http://localhost/{env}?utm_source={get_full_version()}&utm_medium={env}" | ||||
|                     ), | ||||
|                 }, | ||||
|                 headers={ | ||||
|                     "User-Agent": sha512(str(CONFIG.y("secret_key")).encode("ascii")).hexdigest()[ | ||||
|                         :16 | ||||
|                     ], | ||||
|                     "Content-Type": "application/json", | ||||
|                 }, | ||||
|                 timeout=5, | ||||
|             ) | ||||
|         # pylint: disable=bare-except | ||||
|         except:  # nosec | ||||
|             pass | ||||
|  | ||||
| @ -26,9 +26,13 @@ def j_print(event: str, log_level: str = "info", **kwargs): | ||||
|     print(dumps(data), file=stderr) | ||||
|  | ||||
|  | ||||
| j_print("Starting authentik bootstrap") | ||||
|  | ||||
| # Sanity check, ensure SECRET_KEY is set before we even check for database connectivity | ||||
| if CONFIG.y("secret_key") is None or len(CONFIG.y("secret_key")) == 0: | ||||
|     j_print("----------------------------------------------------------------------") | ||||
|     j_print("Secret key missing, check https://goauthentik.io/docs/installation/.") | ||||
|     j_print("----------------------------------------------------------------------") | ||||
|     sysexit(1) | ||||
|  | ||||
|  | ||||
| @ -45,7 +49,9 @@ while True: | ||||
|         break | ||||
|     except OperationalError as exc: | ||||
|         sleep(1) | ||||
|         j_print(f"PostgreSQL Connection failed, retrying... ({exc})") | ||||
|         j_print(f"PostgreSQL connection failed, retrying... ({exc})") | ||||
|     finally: | ||||
|         j_print("PostgreSQL connection successful") | ||||
|  | ||||
| REDIS_PROTOCOL_PREFIX = "redis://" | ||||
| if CONFIG.y_bool("redis.tls", False): | ||||
| @ -63,3 +69,7 @@ while True: | ||||
|     except RedisError as exc: | ||||
|         sleep(1) | ||||
|         j_print(f"Redis Connection failed, retrying... ({exc})", redis_url=REDIS_URL) | ||||
|     finally: | ||||
|         j_print("Redis Connection successful") | ||||
|  | ||||
| j_print("Finished authentik bootstrap") | ||||
|  | ||||
							
								
								
									
										
											BIN
										
									
								
								locale/es/LC_MESSAGES/django.mo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								locale/es/LC_MESSAGES/django.mo
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										1831
									
								
								locale/es/LC_MESSAGES/django.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1831
									
								
								locale/es/LC_MESSAGES/django.po
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										252
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										252
									
								
								poetry.lock
									
									
									
										generated
									
									
									
								
							| @ -163,11 +163,11 @@ visualize = ["graphviz (>0.5.1)", "Twisted (>=16.1.1)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "bandit" | ||||
| version = "1.7.1" | ||||
| version = "1.7.2" | ||||
| description = "Security oriented static analyser for python code." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.5" | ||||
| python-versions = ">=3.7" | ||||
|  | ||||
| [package.dependencies] | ||||
| colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} | ||||
| @ -175,6 +175,11 @@ GitPython = ">=1.0.1" | ||||
| PyYAML = ">=5.3.1" | ||||
| stevedore = ">=1.20.0" | ||||
|  | ||||
| [package.extras] | ||||
| test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml"] | ||||
| toml = ["toml"] | ||||
| yaml = ["pyyaml"] | ||||
|  | ||||
| [[package]] | ||||
| name = "bcrypt" | ||||
| version = "3.2.0" | ||||
| @ -201,40 +206,35 @@ python-versions = "*" | ||||
|  | ||||
| [[package]] | ||||
| name = "black" | ||||
| version = "21.12b0" | ||||
| version = "22.1.0" | ||||
| description = "The uncompromising code formatter." | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6.2" | ||||
|  | ||||
| [package.dependencies] | ||||
| click = ">=7.1.2" | ||||
| click = ">=8.0.0" | ||||
| mypy-extensions = ">=0.4.3" | ||||
| pathspec = ">=0.9.0,<1" | ||||
| pathspec = ">=0.9.0" | ||||
| platformdirs = ">=2" | ||||
| tomli = ">=0.2.6,<2.0.0" | ||||
| typing-extensions = [ | ||||
|     {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}, | ||||
|     {version = "!=3.10.0.1", markers = "python_version >= \"3.10\""}, | ||||
| ] | ||||
| tomli = ">=1.1.0" | ||||
|  | ||||
| [package.extras] | ||||
| colorama = ["colorama (>=0.4.3)"] | ||||
| d = ["aiohttp (>=3.7.4)"] | ||||
| jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] | ||||
| python2 = ["typed-ast (>=1.4.3)"] | ||||
| uvloop = ["uvloop (>=0.15.2)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "boto3" | ||||
| version = "1.20.41" | ||||
| version = "1.20.46" | ||||
| description = "The AWS SDK for Python" | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = ">= 3.6" | ||||
|  | ||||
| [package.dependencies] | ||||
| botocore = ">=1.23.41,<1.24.0" | ||||
| botocore = ">=1.23.46,<1.24.0" | ||||
| jmespath = ">=0.7.1,<1.0.0" | ||||
| s3transfer = ">=0.5.0,<0.6.0" | ||||
|  | ||||
| @ -243,7 +243,7 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "botocore" | ||||
| version = "1.23.41" | ||||
| version = "1.23.46" | ||||
| description = "Low-level, data-driven core of boto 3." | ||||
| category = "main" | ||||
| optional = false | ||||
| @ -490,11 +490,11 @@ python-versions = "*" | ||||
|  | ||||
| [[package]] | ||||
| name = "coverage" | ||||
| version = "6.2" | ||||
| version = "6.3" | ||||
| description = "Code coverage measurement for Python" | ||||
| category = "dev" | ||||
| optional = false | ||||
| python-versions = ">=3.6" | ||||
| python-versions = ">=3.7" | ||||
|  | ||||
| [package.dependencies] | ||||
| tomli = {version = "*", optional = true, markers = "extra == \"toml\""} | ||||
| @ -580,7 +580,7 @@ dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "im | ||||
|  | ||||
| [[package]] | ||||
| name = "django" | ||||
| version = "4.0.1" | ||||
| version = "4.0.2" | ||||
| description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." | ||||
| category = "main" | ||||
| optional = false | ||||
| @ -1297,7 +1297,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" | ||||
|  | ||||
| [[package]] | ||||
| name = "pycryptodome" | ||||
| version = "3.13.0" | ||||
| version = "3.14.0" | ||||
| description = "Cryptographic library for Python" | ||||
| category = "main" | ||||
| optional = false | ||||
| @ -1555,7 +1555,7 @@ test = ["fixtures", "mock", "purl", "pytest", "sphinx", "testrepository (>=0.0.1 | ||||
|  | ||||
| [[package]] | ||||
| name = "requests-oauthlib" | ||||
| version = "1.3.0" | ||||
| version = "1.3.1" | ||||
| description = "OAuthlib authentication support for Requests." | ||||
| category = "main" | ||||
| optional = false | ||||
| @ -1608,7 +1608,7 @@ urllib3 = {version = ">=1.26,<2.0", extras = ["secure"]} | ||||
|  | ||||
| [[package]] | ||||
| name = "sentry-sdk" | ||||
| version = "1.5.3" | ||||
| version = "1.5.4" | ||||
| description = "Python client for Sentry (https://sentry.io)" | ||||
| category = "main" | ||||
| optional = false | ||||
| @ -1898,11 +1898,11 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] | ||||
|  | ||||
| [[package]] | ||||
| name = "uvicorn" | ||||
| version = "0.17.0" | ||||
| version = "0.17.1" | ||||
| description = "The lightning-fast ASGI server." | ||||
| category = "main" | ||||
| optional = false | ||||
| python-versions = "*" | ||||
| python-versions = ">=3.7" | ||||
|  | ||||
| [package.dependencies] | ||||
| asgiref = ">=3.4.0" | ||||
| @ -2188,14 +2188,17 @@ automat = [ | ||||
|     {file = "Automat-20.2.0.tar.gz", hash = "sha256:7979803c74610e11ef0c0d68a2942b152df52da55336e0c9d58daf1831cbdf33"}, | ||||
| ] | ||||
| bandit = [ | ||||
|     {file = "bandit-1.7.1-py3-none-any.whl", hash = "sha256:f5acd838e59c038a159b5c621cf0f8270b279e884eadd7b782d7491c02add0d4"}, | ||||
|     {file = "bandit-1.7.1.tar.gz", hash = "sha256:a81b00b5436e6880fa8ad6799bc830e02032047713cbb143a12939ac67eb756c"}, | ||||
|     {file = "bandit-1.7.2-py3-none-any.whl", hash = "sha256:e20402cadfd126d85b68ed4c8862959663c8c372dbbb1fca8f8e2c9f55a067ec"}, | ||||
|     {file = "bandit-1.7.2.tar.gz", hash = "sha256:6d11adea0214a43813887bfe71a377b5a9955e4c826c8ffd341b494e3ab25260"}, | ||||
| ] | ||||
| bcrypt = [ | ||||
|     {file = "bcrypt-3.2.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:b589229207630484aefe5899122fb938a5b017b0f4349f769b8c13e78d99a8fd"}, | ||||
|     {file = "bcrypt-3.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c95d4cbebffafcdd28bd28bb4e25b31c50f6da605c81ffd9ad8a3d1b2ab7b1b6"}, | ||||
|     {file = "bcrypt-3.2.0-cp36-abi3-manylinux1_x86_64.whl", hash = "sha256:63d4e3ff96188e5898779b6057878fecf3f11cfe6ec3b313ea09955d587ec7a7"}, | ||||
|     {file = "bcrypt-3.2.0-cp36-abi3-manylinux2010_x86_64.whl", hash = "sha256:cd1ea2ff3038509ea95f687256c46b79f5fc382ad0aa3664d200047546d511d1"}, | ||||
|     {file = "bcrypt-3.2.0-cp36-abi3-manylinux2014_aarch64.whl", hash = "sha256:cdcdcb3972027f83fe24a48b1e90ea4b584d35f1cc279d76de6fc4b13376239d"}, | ||||
|     {file = "bcrypt-3.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:a0584a92329210fcd75eb8a3250c5a941633f8bfaf2a18f81009b097732839b7"}, | ||||
|     {file = "bcrypt-3.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:56e5da069a76470679f312a7d3d23deb3ac4519991a0361abc11da837087b61d"}, | ||||
|     {file = "bcrypt-3.2.0-cp36-abi3-win32.whl", hash = "sha256:a67fb841b35c28a59cebed05fbd3e80eea26e6d75851f0574a9273c80f3e9b55"}, | ||||
|     {file = "bcrypt-3.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:81fec756feff5b6818ea7ab031205e1d323d8943d237303baca2c5f9c7846f34"}, | ||||
|     {file = "bcrypt-3.2.0.tar.gz", hash = "sha256:5b93c1726e50a93a033c36e5ca7fdcd29a5c7395af50a6892f5d9e7c6cfbfb29"}, | ||||
| @ -2205,16 +2208,37 @@ billiard = [ | ||||
|     {file = "billiard-3.6.4.0.tar.gz", hash = "sha256:299de5a8da28a783d51b197d496bef4f1595dd023a93a4f59dde1886ae905547"}, | ||||
| ] | ||||
| black = [ | ||||
|     {file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"}, | ||||
|     {file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"}, | ||||
|     {file = "black-22.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6"}, | ||||
|     {file = "black-22.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866"}, | ||||
|     {file = "black-22.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71"}, | ||||
|     {file = "black-22.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab"}, | ||||
|     {file = "black-22.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5"}, | ||||
|     {file = "black-22.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a"}, | ||||
|     {file = "black-22.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0"}, | ||||
|     {file = "black-22.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba"}, | ||||
|     {file = "black-22.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1"}, | ||||
|     {file = "black-22.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8"}, | ||||
|     {file = "black-22.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28"}, | ||||
|     {file = "black-22.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912"}, | ||||
|     {file = "black-22.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3"}, | ||||
|     {file = "black-22.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3"}, | ||||
|     {file = "black-22.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61"}, | ||||
|     {file = "black-22.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd"}, | ||||
|     {file = "black-22.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f"}, | ||||
|     {file = "black-22.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0"}, | ||||
|     {file = "black-22.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c"}, | ||||
|     {file = "black-22.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2"}, | ||||
|     {file = "black-22.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321"}, | ||||
|     {file = "black-22.1.0-py3-none-any.whl", hash = "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d"}, | ||||
|     {file = "black-22.1.0.tar.gz", hash = "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5"}, | ||||
| ] | ||||
| boto3 = [ | ||||
|     {file = "boto3-1.20.41-py3-none-any.whl", hash = "sha256:aaddf6cf93568b734ad62fd96991775bccc7f016e93ff4e98dc1aa4f7586440c"}, | ||||
|     {file = "boto3-1.20.41.tar.gz", hash = "sha256:fb02467a6e8109c7db994ba77fa2e8381ed129ce312988d8ef23edf6e3a3c7f1"}, | ||||
|     {file = "boto3-1.20.46-py3-none-any.whl", hash = "sha256:a2ffce001160d7e7c72a90c3084700d50eb64ea4a3aae8afe21566971d1fd611"}, | ||||
|     {file = "boto3-1.20.46.tar.gz", hash = "sha256:d7effba509d7298ef49316ba2da7a2ea115f2a7ff691f875f6354666663cf386"}, | ||||
| ] | ||||
| botocore = [ | ||||
|     {file = "botocore-1.23.41-py3-none-any.whl", hash = "sha256:41104e1c976c9c410387b3c7d265466b314f287a1c13fd4b543768135301058a"}, | ||||
|     {file = "botocore-1.23.41.tar.gz", hash = "sha256:9137c59c4eb1dee60ae3c710e94f56119a1b33b0b17ff3ad878fc2f4ce77843a"}, | ||||
|     {file = "botocore-1.23.46-py3-none-any.whl", hash = "sha256:354bce55e5adc8e2fe106acfd455ce448f9b920d7b697d06faa8cf200fd6566b"}, | ||||
|     {file = "botocore-1.23.46.tar.gz", hash = "sha256:38dd4564839f531725b667db360ba7df2125ceb3752b0ba12759c3e918015b95"}, | ||||
| ] | ||||
| bump2version = [ | ||||
|     {file = "bump2version-1.0.1-py2.py3-none-any.whl", hash = "sha256:37f927ea17cde7ae2d7baf832f8e80ce3777624554a653006c9144f8017fe410"}, | ||||
| @ -2344,53 +2368,50 @@ constantly = [ | ||||
|     {file = "constantly-15.1.0.tar.gz", hash = "sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"}, | ||||
| ] | ||||
| coverage = [ | ||||
|     {file = "coverage-6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b"}, | ||||
|     {file = "coverage-6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0"}, | ||||
|     {file = "coverage-6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da"}, | ||||
|     {file = "coverage-6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d"}, | ||||
|     {file = "coverage-6.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739"}, | ||||
|     {file = "coverage-6.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971"}, | ||||
|     {file = "coverage-6.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840"}, | ||||
|     {file = "coverage-6.2-cp310-cp310-win32.whl", hash = "sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c"}, | ||||
|     {file = "coverage-6.2-cp310-cp310-win_amd64.whl", hash = "sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f"}, | ||||
|     {file = "coverage-6.2-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76"}, | ||||
|     {file = "coverage-6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47"}, | ||||
|     {file = "coverage-6.2-cp311-cp311-win_amd64.whl", hash = "sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64"}, | ||||
|     {file = "coverage-6.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9"}, | ||||
|     {file = "coverage-6.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d"}, | ||||
|     {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48"}, | ||||
|     {file = "coverage-6.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e"}, | ||||
|     {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d"}, | ||||
|     {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17"}, | ||||
|     {file = "coverage-6.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781"}, | ||||
|     {file = "coverage-6.2-cp36-cp36m-win32.whl", hash = "sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a"}, | ||||
|     {file = "coverage-6.2-cp36-cp36m-win_amd64.whl", hash = "sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0"}, | ||||
|     {file = "coverage-6.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49"}, | ||||
|     {file = "coverage-6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521"}, | ||||
|     {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884"}, | ||||
|     {file = "coverage-6.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa"}, | ||||
|     {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64"}, | ||||
|     {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617"}, | ||||
|     {file = "coverage-6.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8"}, | ||||
|     {file = "coverage-6.2-cp37-cp37m-win32.whl", hash = "sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4"}, | ||||
|     {file = "coverage-6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74"}, | ||||
|     {file = "coverage-6.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e"}, | ||||
|     {file = "coverage-6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58"}, | ||||
|     {file = "coverage-6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc"}, | ||||
|     {file = "coverage-6.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd"}, | ||||
|     {file = "coverage-6.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953"}, | ||||
|     {file = "coverage-6.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475"}, | ||||
|     {file = "coverage-6.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57"}, | ||||
|     {file = "coverage-6.2-cp38-cp38-win32.whl", hash = "sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c"}, | ||||
|     {file = "coverage-6.2-cp38-cp38-win_amd64.whl", hash = "sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2"}, | ||||
|     {file = "coverage-6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd"}, | ||||
|     {file = "coverage-6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685"}, | ||||
|     {file = "coverage-6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c"}, | ||||
|     {file = "coverage-6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3"}, | ||||
|     {file = "coverage-6.2-cp39-cp39-win32.whl", hash = "sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282"}, | ||||
|     {file = "coverage-6.2-cp39-cp39-win_amd64.whl", hash = "sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644"}, | ||||
|     {file = "coverage-6.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de"}, | ||||
|     {file = "coverage-6.2.tar.gz", hash = "sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e8071e7d9ba9f457fc674afc3de054450be2c9b195c470147fbbc082468d8ff7"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:86c91c511853dfda81c2cf2360502cb72783f4b7cebabef27869f00cbe1db07d"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c4ce3b647bd1792d4394f5690d9df6dc035b00bcdbc5595099c01282a59ae01"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a491e159294d756e7fc8462f98175e2d2225e4dbe062cca7d3e0d5a75ba6260"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d008e0f67ac800b0ca04d7914b8501312c8c6c00ad8c7ba17754609fae1231a"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4578728c36de2801c1deb1c6b760d31883e62e33f33c7ba8f982e609dc95167d"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7ee317486593193e066fc5e98ac0ce712178c21529a85c07b7cb978171f25d53"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2bc85664b06ba42d14bb74d6ddf19d8bfc520cb660561d2d9ce5786ae72f71b5"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-win32.whl", hash = "sha256:27a94db5dc098c25048b0aca155f5fac674f2cf1b1736c5272ba28ead2fc267e"}, | ||||
|     {file = "coverage-6.3-cp310-cp310-win_amd64.whl", hash = "sha256:bde4aeabc0d1b2e52c4036c54440b1ad05beeca8113f47aceb4998bb7471e2c2"}, | ||||
|     {file = "coverage-6.3-cp311-cp311-macosx_10_14_x86_64.whl", hash = "sha256:509c68c3e2015022aeda03b003dd68fa19987cdcf64e9d4edc98db41cfc45d30"}, | ||||
|     {file = "coverage-6.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e4ff163602c5c77e7bb4ea81ba5d3b793b4419f8acd296aae149370902cf4e92"}, | ||||
|     {file = "coverage-6.3-cp311-cp311-win_amd64.whl", hash = "sha256:d1675db48490e5fa0b300f6329ecb8a9a37c29b9ab64fa9c964d34111788ca2d"}, | ||||
|     {file = "coverage-6.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7eed8459a2b81848cafb3280b39d7d49950d5f98e403677941c752e7e7ee47cb"}, | ||||
|     {file = "coverage-6.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b4285fde5286b946835a1a53bba3ad41ef74285ba9e8013e14b5ea93deaeafc"}, | ||||
|     {file = "coverage-6.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4748349734110fd32d46ff8897b561e6300d8989a494ad5a0a2e4f0ca974fc7"}, | ||||
|     {file = "coverage-6.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:823f9325283dc9565ba0aa2d240471a93ca8999861779b2b6c7aded45b58ee0f"}, | ||||
|     {file = "coverage-6.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:fff16a30fdf57b214778eff86391301c4509e327a65b877862f7c929f10a4253"}, | ||||
|     {file = "coverage-6.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:da1a428bdbe71f9a8c270c7baab29e9552ac9d0e0cba5e7e9a4c9ee6465d258d"}, | ||||
|     {file = "coverage-6.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7d82c610a2e10372e128023c5baf9ce3d270f3029fe7274ff5bc2897c68f1318"}, | ||||
|     {file = "coverage-6.3-cp37-cp37m-win32.whl", hash = "sha256:11e61c5548ecf74ea1f8b059730b049871f0e32b74f88bd0d670c20c819ad749"}, | ||||
|     {file = "coverage-6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:8e0c3525b1a182c8ffc9bca7e56b521e0c2b8b3e82f033c8e16d6d721f1b54d6"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a189036c50dcd56100746139a459f0d27540fef95b09aba03e786540b8feaa5f"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:32168001f33025fd756884d56d01adebb34e6c8c0b3395ca8584cdcee9c7c9d2"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5d79c9af3f410a2b5acad91258b4ae179ee9c83897eb9de69151b179b0227f5"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:85c5fc9029043cf8b07f73fbb0a7ab6d3b717510c3b5642b77058ea55d7cacde"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a7596aa2f2b8fa5604129cfc9a27ad9beec0a96f18078cb424d029fdd707468d"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ce443a3e6df90d692c38762f108fc4c88314bf477689f04de76b3f252e7a351c"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:012157499ec4f135fc36cd2177e3d1a1840af9b236cbe80e9a5ccfc83d912a69"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0a34d313105cdd0d3644c56df2d743fe467270d6ab93b5d4a347eb9fec8924d6"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-win32.whl", hash = "sha256:6e78b1e25e5c5695dea012be473e442f7094d066925604be20b30713dbd47f89"}, | ||||
|     {file = "coverage-6.3-cp38-cp38-win_amd64.whl", hash = "sha256:433b99f7b0613bdcdc0b00cc3d39ed6d756797e3b078d2c43f8a38288520aec6"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9ed3244b415725f08ca3bdf02ed681089fd95e9465099a21c8e2d9c5d6ca2606"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab4fc4b866b279740e0d917402f0e9a08683e002f43fa408e9655818ed392196"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8582e9280f8d0f38114fe95a92ae8d0790b56b099d728cc4f8a2e14b1c4a18c"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c72bb4679283c6737f452eeb9b2a0e570acaef2197ad255fb20162adc80bea76"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca29c352389ea27a24c79acd117abdd8a865c6eb01576b6f0990cd9a4e9c9f48"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:152cc2624381df4e4e604e21bd8e95eb8059535f7b768c1fb8b8ae0b26f47ab0"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:51372e24b1f7143ee2df6b45cff6a721f3abe93b1e506196f3ffa4155c2497f7"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:72d9d186508325a456475dd05b1756f9a204c7086b07fffb227ef8cee03b1dc2"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-win32.whl", hash = "sha256:649df3641eb351cdfd0d5533c92fc9df507b6b2bf48a7ef8c71ab63cbc7b5c3c"}, | ||||
|     {file = "coverage-6.3-cp39-cp39-win_amd64.whl", hash = "sha256:e67ccd53da5958ea1ec833a160b96357f90859c220a00150de011b787c27b98d"}, | ||||
|     {file = "coverage-6.3-pp36.pp37.pp38-none-any.whl", hash = "sha256:27ac7cb84538e278e07569ceaaa6f807a029dc194b1c819a9820b9bb5dbf63ab"}, | ||||
|     {file = "coverage-6.3.tar.gz", hash = "sha256:987a84ff98a309994ca77ed3cc4b92424f824278e48e4bf7d1bb79a63cfe2099"}, | ||||
| ] | ||||
| cryptography = [ | ||||
|     {file = "cryptography-36.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:73bc2d3f2444bcfeac67dd130ff2ea598ea5f20b40e36d19821b4df8c9c5037b"}, | ||||
| @ -2435,8 +2456,8 @@ deprecated = [ | ||||
|     {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, | ||||
| ] | ||||
| django = [ | ||||
|     {file = "Django-4.0.1-py3-none-any.whl", hash = "sha256:7cd8e8a3ed2bc0dfda05ce1e53a9c81b30eefd7aa350e538a18884475e4d4ce2"}, | ||||
|     {file = "Django-4.0.1.tar.gz", hash = "sha256:2485eea3cc4c3bae13080dee866ebf90ba9f98d1afe8fda89bfb0eb2e218ef86"}, | ||||
|     {file = "Django-4.0.2-py3-none-any.whl", hash = "sha256:996495c58bff749232426c88726d8cd38d24c94d7c1d80835aafffa9bc52985a"}, | ||||
|     {file = "Django-4.0.2.tar.gz", hash = "sha256:110fb58fb12eca59e072ad59fc42d771cd642dd7a2f2416582aa9da7a8ef954a"}, | ||||
| ] | ||||
| django-dbbackup = [ | ||||
|     {file = "django-dbbackup-4.0.0b0.tar.gz", hash = "sha256:aca81265dab91b3a73c3a730cf168d946621c28002f1321d4c33910ba7c63634"}, | ||||
| @ -3053,36 +3074,36 @@ pycparser = [ | ||||
|     {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, | ||||
| ] | ||||
| pycryptodome = [ | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e468724173df02f9d83f3fea830bf0d04aa291b5add22b4a78e01c97aab04873"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1fb7a6f222072412f320b9e48d3ce981920efbfce37b06d028ec9bd94093b37f"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:4f1b594d0cf35bd12ec4244df1155a7f565bf6e6245976ac36174c1564688c90"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:9ea70f6c3f6566159e3798e4593a4a8016994a0080ac29a45200615b45091a1b"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:f7aad304575d075faf2806977b726b67da7ba294adc97d878f92a062e357a56a"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:702446a012fd9337b9327d168bb0c7dc714eb93ad361f6f61af9ca8305a301f1"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27m-win32.whl", hash = "sha256:681ac47c538c64305d710eaed2bb49532f62b3f4c93aa7c423c520df981392e5"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27m-win_amd64.whl", hash = "sha256:7b3478a187d897f003b2aa1793bcc59463e8d57a42e2aafbcbbe9cd47ec46863"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:eec02d9199af4b1ccfe1f9c587691a07a1fa39d949d2c1dc69d079ab9af8212f"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:9c8e0e6c5e982699801b20fa74f43c19aa080d2b53a39f3c132d35958e153bd4"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f5457e44d3f26d9946091e92b28f3e970a56538b96c87b4b155a84e32a40b7b5"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:88d6d54e83cf9bbd665ce1e7b9079983ee2d97a05f42e0569ff00a70f1dd8b1e"}, | ||||
|     {file = "pycryptodome-3.13.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:72de8c4d71e6b11d54528bb924447fa4fdabcbb3d76cc0e7f61d3b6075def6b3"}, | ||||
|     {file = "pycryptodome-3.13.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:008ef2c631f112cd5a58736e0b29f4a28b4bb853e68878689f8b476fd56e0691"}, | ||||
|     {file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:51ebe9624ad0a0b4da1aaaa2d43aabadf8537737fd494cee0ffa37cd6326de02"}, | ||||
|     {file = "pycryptodome-3.13.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:deede160bdf87ddb71f0a1314ad5a267b1a960be314ea7dc6b7ad86da6da89a3"}, | ||||
|     {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:857c16bffd938254e3a834cd6b2a755ed24e1a953b1a86e33da136d3e4c16a6f"}, | ||||
|     {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:ca6db61335d07220de0b665bfee7b8e9615b2dfc67a54016db4826dac34c2dd2"}, | ||||
|     {file = "pycryptodome-3.13.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:073dedf0f9c490ae22ca081b86357646ac9b76f3e2bd89119d137fc697a9e3b6"}, | ||||
|     {file = "pycryptodome-3.13.0-cp35-abi3-win32.whl", hash = "sha256:e3affa03c49cce7b0a9501cc7f608d4f8e61fb2522b276d599ac049b5955576d"}, | ||||
|     {file = "pycryptodome-3.13.0-cp35-abi3-win_amd64.whl", hash = "sha256:e5d72be02b17e6bd7919555811264403468d1d052fa67c946e402257c3c29a27"}, | ||||
|     {file = "pycryptodome-3.13.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:0896d5d15ffe584d46cb9b69a75cf14a2bc8f6daf635b7bf16c1b041342a44b1"}, | ||||
|     {file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:e420cdfca73f80fe15f79bb34756959945231a052440813e5fce531e6e96331a"}, | ||||
|     {file = "pycryptodome-3.13.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:720fafdf3e5c5de93039d8308f765cc60b8e9e7e852ad7135aa65dd89238191f"}, | ||||
|     {file = "pycryptodome-3.13.0-pp27-pypy_73-win32.whl", hash = "sha256:7a8b0e526ff239b4f4c61dd6898e2474d609843ffc437267f3a27ddff626e6f6"}, | ||||
|     {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d92a5eddffb0ad39f582f07c1de26e9daf6880e3e782a94bb7ebaf939567f8bf"}, | ||||
|     {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:cb9453c981554984c6f5c5ce7682d7286e65e2173d7416114c3593a977a01bf5"}, | ||||
|     {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:765b8b16bc1fd699e183dde642c7f2653b8f3c9c1a50051139908e9683f97732"}, | ||||
|     {file = "pycryptodome-3.13.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:b3af53dddf848afb38b3ac2bae7159ddad1feb9bac14aa3acec6ef1797b82f8d"}, | ||||
|     {file = "pycryptodome-3.13.0.tar.gz", hash = "sha256:95bacf9ff7d1b90bba537d3f5f6c834efe6bfbb1a0195cb3573f29e6716ef08d"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bd800856e6dea6924504795ae4ec0d822e912e0a9a215e73b77b585c4d15a0f7"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:625f78ad69aa3c45e19b85b9e9cae3a30aa4a1de6b908981a63426b88e860489"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:a1c116dd7a00aac631f67920912fd8ef7a5ad3402cd4d497c6f5cc6b8115747b"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:0d0b6cca6b707b2c7cd4177c2d3cd950efa959ed8f01c30e676f102c68156f00"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9d939a257117cc8c6840ad69f149b3ca5e07268cfe0429bd9feec0f91da2343d"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:41dbb8c2129d43f34ed555cbd365d5e8f023ef0f9238fd9cd0302086b15a38b3"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27m-win32.whl", hash = "sha256:9b454af09914807cef1222d100a8c523737a160347cb8d699facc4bdfb9fe725"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27m-win_amd64.whl", hash = "sha256:95bac6e55411650933f3b615e57bf0966bf08f3ce07c01f07482ced95f18cbec"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:0ffbca43c1788243421a8583d85acb59f4cd0b82b001c485fdc3fbfd8fd0804f"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:69b85d78f7db628370d2cc87f1c41a449f6460896ba95f412173618f75027c2c"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:bba348d2823315ab8ebe44f0b2fc2ff8dfac8de881713a08def3dadcfc8e92bb"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:7d667daa851b1f9a20f2b5cad3cff13fba5204bc2f857d12f27c25b178d8629b"}, | ||||
|     {file = "pycryptodome-3.14.0-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:74918d5de06b12fef2255135bede41307a5f7b929b145ad867111525aea075dc"}, | ||||
|     {file = "pycryptodome-3.14.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c2b6faabd09d2876f9050f8af5d78046d81fe856f99e801c2ddab85b59602007"}, | ||||
|     {file = "pycryptodome-3.14.0-cp35-abi3-manylinux1_i686.whl", hash = "sha256:22a8629315c76d2bec57bc4fd67eb7e01664c3e3b9579df40f530ee5821db1de"}, | ||||
|     {file = "pycryptodome-3.14.0-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:7e3851e4fbbab72d9b30f98a504f450cc61e497e8e4b0be8205dc198703eee4d"}, | ||||
|     {file = "pycryptodome-3.14.0-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:9006f17944efaacc3be364c01c2253c00a00f0b5fa5a1a85a1191efd861e764d"}, | ||||
|     {file = "pycryptodome-3.14.0-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:8f0da308fca149b4c4da78e1388f82d8dd167e0ce12992a44f81b506cede3109"}, | ||||
|     {file = "pycryptodome-3.14.0-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:d186e34747985fbd94df7ed4d621f8377165053a06872314c2a594af34741655"}, | ||||
|     {file = "pycryptodome-3.14.0-cp35-abi3-win32.whl", hash = "sha256:2ed4da8f8afe44895c1f49ae1141a55b15d81dc745b5baa7b7a7265d7b40b81e"}, | ||||
|     {file = "pycryptodome-3.14.0-cp35-abi3-win_amd64.whl", hash = "sha256:11167a1f892283e5320feb5e81589fd041a1822b94c047820f00bc03eb98a9f7"}, | ||||
|     {file = "pycryptodome-3.14.0-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:1714ea5f83bcff25e8ae4640e22359d7a0815157a29d9f4eebc2b9e975a3cda0"}, | ||||
|     {file = "pycryptodome-3.14.0-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:3a011b9fe674bd21056613e88a3e660c56f1b47263138ebf420aa3ee4b8b0107"}, | ||||
|     {file = "pycryptodome-3.14.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:3fd50e3682ac3a684ace5b90ba1aef8090a78eeadf38c1ec385aad3a599cfd68"}, | ||||
|     {file = "pycryptodome-3.14.0-pp27-pypy_73-win32.whl", hash = "sha256:08be50d4195edd595df580077bbeec5599d0e5aa0cc468083178ae870e0b29f4"}, | ||||
|     {file = "pycryptodome-3.14.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:16c171dd969c9046b7b304c6ba0c643624dcf18093a66bd30b8b091703f177a2"}, | ||||
|     {file = "pycryptodome-3.14.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:89bb56cfd1fb74663842710bc41a6be26dafceb60eb8d432536891aea08a3740"}, | ||||
|     {file = "pycryptodome-3.14.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:c30a98c8718ae93d44680a7038adb484a520319860747ba43b6cd0a20f6b5984"}, | ||||
|     {file = "pycryptodome-3.14.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:e972f566ef7b821c8b958dab64174afa072f8271b779e32444ad7c127b0a84b2"}, | ||||
|     {file = "pycryptodome-3.14.0.tar.gz", hash = "sha256:ceea92a4b8ba6c50d8d70f2efbb4ea14b002dac4160ce4dda33f1b7442f8158a"}, | ||||
| ] | ||||
| pyjwt = [ | ||||
|     {file = "PyJWT-2.3.0-py3-none-any.whl", hash = "sha256:e0c4bb8d9f0af0c7f5b1ec4c5036309617d03d56932877f2f7a0beeb5318322f"}, | ||||
| @ -3229,9 +3250,8 @@ requests-mock = [ | ||||
|     {file = "requests_mock-1.9.3-py2.py3-none-any.whl", hash = "sha256:0a2d38a117c08bb78939ec163522976ad59a6b7fdd82b709e23bb98004a44970"}, | ||||
| ] | ||||
| requests-oauthlib = [ | ||||
|     {file = "requests-oauthlib-1.3.0.tar.gz", hash = "sha256:b4261601a71fd721a8bd6d7aa1cc1d6a8a93b4a9f5e96626f8e4d91e8beeaa6a"}, | ||||
|     {file = "requests_oauthlib-1.3.0-py2.py3-none-any.whl", hash = "sha256:7f71572defaecd16372f9006f33c2ec8c077c3cfa6f5911a9a90202beb513f3d"}, | ||||
|     {file = "requests_oauthlib-1.3.0-py3.7.egg", hash = "sha256:fa6c47b933f01060936d87ae9327fead68768b69c6c9ea2109c48be30f2d4dbc"}, | ||||
|     {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, | ||||
|     {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, | ||||
| ] | ||||
| rsa = [ | ||||
|     {file = "rsa-4.8-py3-none-any.whl", hash = "sha256:95c5d300c4e879ee69708c428ba566c59478fd653cc3a22243eeb8ed846950bb"}, | ||||
| @ -3245,8 +3265,8 @@ selenium = [ | ||||
|     {file = "selenium-4.1.0-py3-none-any.whl", hash = "sha256:27e7b64df961d609f3d57237caa0df123abbbe22d038f2ec9e332fb90ec1a939"}, | ||||
| ] | ||||
| sentry-sdk = [ | ||||
|     {file = "sentry-sdk-1.5.3.tar.gz", hash = "sha256:141da032f0fa4c56f9af6b361fda57360af1789576285bd1944561f9c274f9c0"}, | ||||
|     {file = "sentry_sdk-1.5.3-py2.py3-none-any.whl", hash = "sha256:9aeff2a47f4038460296b920bf4d269284e8454e1c67547ee002ccafd9c2442b"}, | ||||
|     {file = "sentry-sdk-1.5.4.tar.gz", hash = "sha256:f7e54567937ebcbe938c4df1075ec891587faeb7c74184b88cf2894e47c86116"}, | ||||
|     {file = "sentry_sdk-1.5.4-py2.py3-none-any.whl", hash = "sha256:4fc7960a82c95d906a0514cf4d9aacba1743eb9863a5b7c2a01c525a7d9b21e6"}, | ||||
| ] | ||||
| service-identity = [ | ||||
|     {file = "service-identity-21.1.0.tar.gz", hash = "sha256:6e6c6086ca271dc11b033d17c3a8bea9f24ebff920c587da090afc9519419d34"}, | ||||
| @ -3386,8 +3406,8 @@ urllib3 = [ | ||||
|     {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, | ||||
| ] | ||||
| uvicorn = [ | ||||
|     {file = "uvicorn-0.17.0-py3-none-any.whl", hash = "sha256:0b89c91bb8fe84c4bded9996af13c4b8c0de799d29bffeaa0c8ad298f2be0934"}, | ||||
|     {file = "uvicorn-0.17.0.tar.gz", hash = "sha256:192c2422b056a3beb512c6c260bf77a7a884204a4ae41856719c1913ead63bbb"}, | ||||
|     {file = "uvicorn-0.17.1-py3-none-any.whl", hash = "sha256:8b16d9ecb76500f7804184f182835fe8a2b54716d3b0b6bb2da0b2b192f62c73"}, | ||||
|     {file = "uvicorn-0.17.1.tar.gz", hash = "sha256:dffbacb8cc25d924d68d231d2c478c4fe6727c36537d8de21e5de591b37afc41"}, | ||||
| ] | ||||
| uvloop = [ | ||||
|     {file = "uvloop-0.16.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d"}, | ||||
|  | ||||
| @ -14,7 +14,7 @@ pythonPlatform = "Linux" | ||||
|  | ||||
| [tool.black] | ||||
| line-length = 100 | ||||
| target-version = ['py39'] | ||||
| target-version = ['py310'] | ||||
| exclude = 'node_modules' | ||||
|  | ||||
| [tool.isort] | ||||
| @ -92,7 +92,7 @@ addopts = "-p no:celery --junitxml=unittest.xml" | ||||
|  | ||||
| [tool.poetry] | ||||
| name = "authentik" | ||||
| version = "2022.1.2" | ||||
| version = "2022.1.4" | ||||
| description = "" | ||||
| authors = ["Jens Langhammer <jens.langhammer@beryju.org>"] | ||||
|  | ||||
|  | ||||
| @ -1,7 +1,7 @@ | ||||
| openapi: 3.0.3 | ||||
| info: | ||||
|   title: authentik | ||||
|   version: 2022.1.2 | ||||
|   version: 2022.1.4 | ||||
|   description: Making authentication simple. | ||||
|   contact: | ||||
|     email: hello@beryju.org | ||||
|  | ||||
| @ -3,7 +3,11 @@ from authentik.lib.generators import generate_id | ||||
| from yaml import safe_dump | ||||
|  | ||||
| with open("local.env.yml", "w") as _config: | ||||
|     safe_dump({ | ||||
|         "log_level": "debug", | ||||
|         "secret_key": generate_id(), | ||||
|     }, _config, default_flow_style=False) | ||||
|     safe_dump( | ||||
|         { | ||||
|             "log_level": "debug", | ||||
|             "secret_key": generate_id(), | ||||
|         }, | ||||
|         _config, | ||||
|         default_flow_style=False, | ||||
|     ) | ||||
|  | ||||
| @ -13,7 +13,10 @@ if os.environ.get(env_pr_branch, "") != "": | ||||
| should_build = str(os.environ.get("DOCKER_USERNAME", "") != "").lower() | ||||
|  | ||||
| print("##[set-output name=branchName]%s" % branch_name) | ||||
| print("##[set-output name=branchNameContainer]%s" % branch_name.replace("refs/heads/", "").replace("/", "-")) | ||||
| print( | ||||
|     "##[set-output name=branchNameContainer]%s" | ||||
|     % branch_name.replace("refs/heads/", "").replace("/", "-") | ||||
| ) | ||||
| print("##[set-output name=timestamp]%s" % int(time())) | ||||
| print("##[set-output name=sha]%s" % os.environ[sha]) | ||||
| print("##[set-output name=shouldBuild]%s" % should_build) | ||||
|  | ||||
| @ -2,20 +2,15 @@ | ||||
| from json import loads, dumps | ||||
|  | ||||
| TSCONFIG_ESM = { | ||||
|   "compilerOptions": { | ||||
|     "declaration": True, | ||||
|     "target": "es6", | ||||
|     "module": "esnext", | ||||
|     "moduleResolution": "node", | ||||
|     "outDir": "./dist/esm", | ||||
|     "typeRoots": [ | ||||
|       "node_modules/@types" | ||||
|     ] | ||||
|   }, | ||||
|   "exclude": [ | ||||
|     "dist", | ||||
|     "node_modules" | ||||
|   ] | ||||
|     "compilerOptions": { | ||||
|         "declaration": True, | ||||
|         "target": "es6", | ||||
|         "module": "esnext", | ||||
|         "moduleResolution": "node", | ||||
|         "outDir": "./dist/esm", | ||||
|         "typeRoots": ["node_modules/@types"], | ||||
|     }, | ||||
|     "exclude": ["dist", "node_modules"], | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -24,7 +19,7 @@ with open("web-api/package.json", encoding="utf-8") as _package: | ||||
|     package["license"] = "GPL-3.0-only" | ||||
|     package["module"] = "./dist/esm/index.js" | ||||
|     package["sideEffects"] = False | ||||
|     package["scripts"]["build"] =  "tsc && tsc --project tsconfig.esm.json" | ||||
|     package["scripts"]["build"] = "tsc && tsc --project tsconfig.esm.json" | ||||
|  | ||||
| open("web-api/package.json", "w+", encoding="utf-8").write(dumps(package)) | ||||
| open("web-api/tsconfig.esm.json", "w+", encoding="utf-8").write(dumps(TSCONFIG_ESM)) | ||||
|  | ||||
							
								
								
									
										559
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										559
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -14,15 +14,15 @@ | ||||
|                 "@babel/plugin-transform-runtime": "^7.16.10", | ||||
|                 "@babel/preset-env": "^7.16.11", | ||||
|                 "@babel/preset-typescript": "^7.16.7", | ||||
|                 "@formatjs/intl-listformat": "^6.5.0", | ||||
|                 "@formatjs/intl-listformat": "^6.5.1", | ||||
|                 "@fortawesome/fontawesome-free": "^5.15.4", | ||||
|                 "@goauthentik/api": "^2022.1.1-1642874681", | ||||
|                 "@goauthentik/api": "^2022.1.3-1643236150", | ||||
|                 "@jackfranklin/rollup-plugin-markdown": "^0.3.0", | ||||
|                 "@lingui/cli": "^3.13.1", | ||||
|                 "@lingui/core": "^3.13.1", | ||||
|                 "@lingui/detect-locale": "^3.13.1", | ||||
|                 "@lingui/macro": "^3.13.1", | ||||
|                 "@patternfly/patternfly": "^4.164.2", | ||||
|                 "@lingui/cli": "^3.13.2", | ||||
|                 "@lingui/core": "^3.13.2", | ||||
|                 "@lingui/detect-locale": "^3.13.2", | ||||
|                 "@lingui/macro": "^3.13.2", | ||||
|                 "@patternfly/patternfly": "^4.171.1", | ||||
|                 "@polymer/iron-form": "^3.0.1", | ||||
|                 "@polymer/paper-input": "^3.2.1", | ||||
|                 "@rollup/plugin-babel": "^5.3.0", | ||||
| @ -30,34 +30,34 @@ | ||||
|                 "@rollup/plugin-node-resolve": "^13.1.3", | ||||
|                 "@rollup/plugin-replace": "^3.0.1", | ||||
|                 "@rollup/plugin-typescript": "^8.3.0", | ||||
|                 "@sentry/browser": "^6.16.1", | ||||
|                 "@sentry/tracing": "^6.16.1", | ||||
|                 "@sentry/browser": "^6.17.3", | ||||
|                 "@sentry/tracing": "^6.17.3", | ||||
|                 "@squoosh/cli": "^0.7.2", | ||||
|                 "@trivago/prettier-plugin-sort-imports": "^3.1.1", | ||||
|                 "@types/chart.js": "^2.9.35", | ||||
|                 "@types/codemirror": "5.60.5", | ||||
|                 "@types/grecaptcha": "^3.0.3", | ||||
|                 "@typescript-eslint/eslint-plugin": "^5.10.0", | ||||
|                 "@typescript-eslint/parser": "^5.10.0", | ||||
|                 "@typescript-eslint/eslint-plugin": "^5.10.2", | ||||
|                 "@typescript-eslint/parser": "^5.10.2", | ||||
|                 "@webcomponents/webcomponentsjs": "^2.6.0", | ||||
|                 "babel-plugin-macros": "^3.1.0", | ||||
|                 "base64-js": "^1.5.1", | ||||
|                 "chart.js": "^3.7.0", | ||||
|                 "chartjs-adapter-moment": "^1.0.0", | ||||
|                 "codemirror": "^5.65.1", | ||||
|                 "construct-style-sheets-polyfill": "^3.0.5", | ||||
|                 "country-flag-icons": "^1.4.19", | ||||
|                 "eslint": "^8.7.0", | ||||
|                 "construct-style-sheets-polyfill": "^3.1.0", | ||||
|                 "country-flag-icons": "^1.4.20", | ||||
|                 "eslint": "^8.8.0", | ||||
|                 "eslint-config-google": "^0.14.0", | ||||
|                 "eslint-plugin-custom-elements": "0.0.4", | ||||
|                 "eslint-plugin-lit": "^1.6.1", | ||||
|                 "flowchart.js": "^1.17.0", | ||||
|                 "fuse.js": "^6.5.3", | ||||
|                 "lit": "^2.1.1", | ||||
|                 "lit": "^2.1.2", | ||||
|                 "moment": "^2.29.1", | ||||
|                 "prettier": "^2.5.1", | ||||
|                 "rapidoc": "^9.1.4", | ||||
|                 "rollup": "^2.66.0", | ||||
|                 "rollup": "^2.66.1", | ||||
|                 "rollup-plugin-copy": "^3.4.0", | ||||
|                 "rollup-plugin-cssimport": "^1.0.2", | ||||
|                 "rollup-plugin-minify-html-literals": "^1.2.6", | ||||
| @ -1717,28 +1717,28 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@formatjs/ecma402-abstract": { | ||||
|             "version": "1.11.1", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.1.tgz", | ||||
|             "integrity": "sha512-tgtNODZUGuUI6PAcnvaLZpGrZLVkXnnAvgzOiueYMzFdOdcOw4iH1WKhCe3+r6VR8rHKToJ2HksUGNCB+zt/bg==", | ||||
|             "version": "1.11.2", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.2.tgz", | ||||
|             "integrity": "sha512-qDgOL0vtfJ51cc0pRbFB/oXc4qDbamG22Z6h/QWy6FBxaQgppiy8JF0iYbmNO35cC8r88bQGsgfd/eM6/eTEQQ==", | ||||
|             "dependencies": { | ||||
|                 "@formatjs/intl-localematcher": "0.2.22", | ||||
|                 "@formatjs/intl-localematcher": "0.2.23", | ||||
|                 "tslib": "^2.1.0" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@formatjs/intl-listformat": { | ||||
|             "version": "6.5.0", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.5.0.tgz", | ||||
|             "integrity": "sha512-gVyAV5QWWtq84MK4cAyJITW+Wb74c2+FT+wa8jhSPxXUky9B5z/k/Ff7or4Vb3KV0YYZuVBQ/vMIoD8Gr182ww==", | ||||
|             "version": "6.5.1", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.5.1.tgz", | ||||
|             "integrity": "sha512-ijsOM7J7aNnGx+1JYUGWgMAcisnK0CxdlPx7KJpUXKj9Mf2Ph28H2WMTL1h1xv9T7SSvH0Nd6asI0Qw4ffw17w==", | ||||
|             "dependencies": { | ||||
|                 "@formatjs/ecma402-abstract": "1.11.1", | ||||
|                 "@formatjs/intl-localematcher": "0.2.22", | ||||
|                 "@formatjs/ecma402-abstract": "1.11.2", | ||||
|                 "@formatjs/intl-localematcher": "0.2.23", | ||||
|                 "tslib": "^2.1.0" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@formatjs/intl-localematcher": { | ||||
|             "version": "0.2.22", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.22.tgz", | ||||
|             "integrity": "sha512-z+TvbHW8Q/g2l7/PnfUl0mV9gWxV4d0HT6GQyzkO5QI6QjCvCZGiztnmLX7zoyS16uSMvZ2PoMDfSK9xvZkRRA==", | ||||
|             "version": "0.2.23", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.23.tgz", | ||||
|             "integrity": "sha512-oCe2TOciTtB1bEbJ85EvYrXQxD0epusmVJfJ7AduO0tlbXP42CmDIYIH2CZ+kP2GE+PTLQD1Hbt9kpOpl939MQ==", | ||||
|             "dependencies": { | ||||
|                 "tslib": "^2.1.0" | ||||
|             } | ||||
| @ -1753,9 +1753,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@goauthentik/api": { | ||||
|             "version": "2022.1.1-1642874681", | ||||
|             "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2022.1.1-1642874681.tgz", | ||||
|             "integrity": "sha512-MOFu1g/5dvQu+BTj8qqc2IMT9fpBICqzERkC949JiDxDSqHg0kuqmxe23vPnFceryQM5zktTBJ+VxXjzR9lX3g==" | ||||
|             "version": "2022.1.3-1643236150", | ||||
|             "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2022.1.3-1643236150.tgz", | ||||
|             "integrity": "sha512-eteq3Y/4eME6bffuQy8cB6ZrV3DB7rk1IKdvzfUbr9I1hSRzXEBtlzmXp+lhY6RxlEy9hhcJHZO8/OCKFI5l9A==" | ||||
|         }, | ||||
|         "node_modules/@humanwhocodes/config-array": { | ||||
|             "version": "0.9.2", | ||||
| @ -1865,13 +1865,13 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@lingui/babel-plugin-extract-messages": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.13.1.tgz", | ||||
|             "integrity": "sha512-K0ekhQI49ZTE90bVxvndqdxO80X1ZjacVdznWn4RJq6EEN9ElppMKkWUmAe/vfHGJRCH/2aUIp73xvaXPJPbGg==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.13.2.tgz", | ||||
|             "integrity": "sha512-SyvwfrPqkyj9XM2CB/YK25o0Zi+B8ikoCENwqNSk7201n80YfOJoksc6lQ3X/QODqvy+iuOsiQrVT3qzKblOmg==", | ||||
|             "dependencies": { | ||||
|                 "@babel/generator": "^7.11.6", | ||||
|                 "@babel/runtime": "^7.11.2", | ||||
|                 "@lingui/conf": "^3.13.1", | ||||
|                 "@lingui/conf": "^3.13.2", | ||||
|                 "mkdirp": "^1.0.4" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -1879,17 +1879,17 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@lingui/cli": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.13.1.tgz", | ||||
|             "integrity": "sha512-JGfbdAn1qxHBjuhnLeERMhCLe7UXSFafqq9S//g3+VNHKHfVHfa0CKFUmISMDKMLFdKmbdJCZpYU3DRZNrUGyQ==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.13.2.tgz", | ||||
|             "integrity": "sha512-wPYlsKI7hx1hyntc6enUVUdKVwBM8XW+DnwHslWWw4ShMNvh98gLgAOW1ajXtUym7x0WTjhR+/s436hdxfZ/Og==", | ||||
|             "dependencies": { | ||||
|                 "@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.13.1", | ||||
|                 "@lingui/conf": "^3.13.1", | ||||
|                 "@lingui/babel-plugin-extract-messages": "^3.13.2", | ||||
|                 "@lingui/conf": "^3.13.2", | ||||
|                 "babel-plugin-macros": "^3.0.1", | ||||
|                 "bcp-47": "^1.0.7", | ||||
|                 "chalk": "^4.1.0", | ||||
| @ -1992,9 +1992,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@lingui/conf": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.13.1.tgz", | ||||
|             "integrity": "sha512-xWJVdgNiGqYzkYIxHg4c6KqSNleN5/96M2ly+GzBOmA5H75r4hz27DfQpxuC4FuBUAPC+Mk1HTBO9/aFO0BCZg==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.13.2.tgz", | ||||
|             "integrity": "sha512-JhiIBxnh2X4QmLP0/+dnTBc7xnZ6qk5MRsQtJqkEOWGFl09CTrha5uPVqjr5MgkmBOQ6Q8+cRYWG+qtJsuUH5A==", | ||||
|             "dependencies": { | ||||
|                 "@babel/runtime": "^7.11.2", | ||||
|                 "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", | ||||
| @ -2072,9 +2072,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@lingui/core": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.13.1.tgz", | ||||
|             "integrity": "sha512-spzRJ/fca9Ddpns27Xmz2f9lgiesrvTZjcpOO2wKJq9QozF1qtv7n1bViQ1Erh2uFaO0kaEzUjkAYU3LtlP4PQ==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.13.2.tgz", | ||||
|             "integrity": "sha512-ic1uC+bS7hpfM4oVugHKel8UhlLAwykSv2TYw3oyeEQhvCS232nSzh+PFbP0BXK1hZ0UdHve7mODpgADuwHIQA==", | ||||
|             "dependencies": { | ||||
|                 "@babel/runtime": "^7.11.2", | ||||
|                 "make-plural": "^6.2.2", | ||||
| @ -2085,20 +2085,20 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@lingui/detect-locale": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.13.1.tgz", | ||||
|             "integrity": "sha512-ZY/jo3whJ5+QlkpUjZgXzzmON6vA9s0qbXgsKue6xIEOGZ7/z5p05tnHb8RYa6jhpRSYN+CJARx2H82QZMrtwA==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.13.2.tgz", | ||||
|             "integrity": "sha512-1fouly1ecq1wCKUGtYgFn0Hdsjuz4bBYxh/oIjrqEeb4+bKdjaHbCT2ypsX7rRxs88yOfOWGUYuuzG0EoJXiSw==", | ||||
|             "engines": { | ||||
|                 "node": ">=10.0.0" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@lingui/macro": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.13.1.tgz", | ||||
|             "integrity": "sha512-iXdAbREJpIUs3s78Erbg+7ZRuJsD0S0nyGCeEo9Ml/NDO/MtVYo7XCHecwtCdNxDe/h0NItB3m/7uPZ/BvOLOA==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.13.2.tgz", | ||||
|             "integrity": "sha512-0BdybZkBq8bl4NrT8txX7k8BodyJ/4uQbMIK0ucPJvQ/6Lhj824CodBq5KuMWpcXoMSxUWjQIkIGr1Fi1ckLGg==", | ||||
|             "dependencies": { | ||||
|                 "@babel/runtime": "^7.11.2", | ||||
|                 "@lingui/conf": "^3.13.1", | ||||
|                 "@lingui/conf": "^3.13.2", | ||||
|                 "ramda": "^0.27.1" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -2176,9 +2176,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@patternfly/patternfly": { | ||||
|             "version": "4.164.2", | ||||
|             "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.164.2.tgz", | ||||
|             "integrity": "sha512-gezQi83JKd6tW0z1J6Q5VvMCW/a58+ys4TWcTuXUMqcV3APQdNxVP+ZV6FIv5353oIPi9HuWAaApVwcCxYZYYg==" | ||||
|             "version": "4.171.1", | ||||
|             "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.171.1.tgz", | ||||
|             "integrity": "sha512-e5Ykg+QOo8TsyOyG6SqytAs52MJXwaP020z3twb8z9G3ZNra92uNsrxGgZEqPJoWbjU4K7LGDxy2DOM1FeRoFw==" | ||||
|         }, | ||||
|         "node_modules/@polymer/font-roboto": { | ||||
|             "version": "3.0.2", | ||||
| @ -2433,13 +2433,13 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@sentry/browser": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.16.1.tgz", | ||||
|             "integrity": "sha512-F2I5RL7RTLQF9CccMrqt73GRdK3FdqaChED3RulGQX5lH6U3exHGFxwyZxSrY4x6FedfBFYlfXWWCJXpLnFkow==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.17.3.tgz", | ||||
|             "integrity": "sha512-UElPk6/Q/78eL8tHGHy080uHVQAuieWXlSMSzrJMVNa+vwXPwEeyL+WbPtKkND2jGwdODjg+pSj960RqhIv+ig==", | ||||
|             "dependencies": { | ||||
|                 "@sentry/core": "6.16.1", | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/utils": "6.16.1", | ||||
|                 "@sentry/core": "6.17.3", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "@sentry/utils": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -2452,14 +2452,14 @@ | ||||
|             "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" | ||||
|         }, | ||||
|         "node_modules/@sentry/core": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.16.1.tgz", | ||||
|             "integrity": "sha512-UFI0264CPUc5cR1zJH+S2UPOANpm6dLJOnsvnIGTjsrwzR0h8Hdl6rC2R/GPq+WNbnipo9hkiIwDlqbqvIU5vw==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.17.3.tgz", | ||||
|             "integrity": "sha512-h7WgrNL0RVlr8Dceh97ZiXNdmEumDutpoqFijjiX4x72IiC6zSaVD4IsqrdGln+v8iJ3l3lX44HHqzubDub1OQ==", | ||||
|             "dependencies": { | ||||
|                 "@sentry/hub": "6.16.1", | ||||
|                 "@sentry/minimal": "6.16.1", | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/utils": "6.16.1", | ||||
|                 "@sentry/hub": "6.17.3", | ||||
|                 "@sentry/minimal": "6.17.3", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "@sentry/utils": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -2472,12 +2472,12 @@ | ||||
|             "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" | ||||
|         }, | ||||
|         "node_modules/@sentry/hub": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.16.1.tgz", | ||||
|             "integrity": "sha512-4PGtg6AfpqMkreTpL7ymDeQ/U1uXv03bKUuFdtsSTn/FRf9TLS4JB0KuTZCxfp1IRgAA+iFg6B784dDkT8R9eg==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.17.3.tgz", | ||||
|             "integrity": "sha512-TDxv8nRvk45xvfQg6zs8GYzQzgo0EMhI3wjQZLiNfW2rzybKmIwVp2x3O4PAc3WPzwg4bYNgSAkYKVlHmYjRCg==", | ||||
|             "dependencies": { | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/utils": "6.16.1", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "@sentry/utils": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -2490,12 +2490,12 @@ | ||||
|             "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" | ||||
|         }, | ||||
|         "node_modules/@sentry/minimal": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.16.1.tgz", | ||||
|             "integrity": "sha512-dq+mI1EQIvUM+zJtGCVgH3/B3Sbx4hKlGf2Usovm9KoqWYA+QpfVBholYDe/H2RXgO7LFEefDLvOdHDkqeJoyA==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.17.3.tgz", | ||||
|             "integrity": "sha512-zvGGfHNNA92Lqx6P8ZwOUkmRmAiQl0AQFRXl9So1Ayq9bJRnFLJZv4YFVnp2wE4HXYIlfBYb51+GlGB5LIuPmw==", | ||||
|             "dependencies": { | ||||
|                 "@sentry/hub": "6.16.1", | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/hub": "6.17.3", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -2508,14 +2508,14 @@ | ||||
|             "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" | ||||
|         }, | ||||
|         "node_modules/@sentry/tracing": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.16.1.tgz", | ||||
|             "integrity": "sha512-MPSbqXX59P+OEeST+U2V/8Hu/8QjpTUxTNeNyTHWIbbchdcMMjDbXTS3etCgajZR6Ro+DHElOz5cdSxH6IBGlA==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.17.3.tgz", | ||||
|             "integrity": "sha512-GnHugxw5qkWwYmeQbbrswuWpb0bpYqyJr/dO25QQOCwp+cckQrvBYTMC8zGJG10u94O4el0lQaQnNFz9WF3r6g==", | ||||
|             "dependencies": { | ||||
|                 "@sentry/hub": "6.16.1", | ||||
|                 "@sentry/minimal": "6.16.1", | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/utils": "6.16.1", | ||||
|                 "@sentry/hub": "6.17.3", | ||||
|                 "@sentry/minimal": "6.17.3", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "@sentry/utils": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -2528,19 +2528,19 @@ | ||||
|             "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" | ||||
|         }, | ||||
|         "node_modules/@sentry/types": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.16.1.tgz", | ||||
|             "integrity": "sha512-Wh354g30UsJ5kYJbercektGX4ZMc9MHU++1NjeN2bTMnbofEcpUDWIiKeulZEY65IC1iU+1zRQQgtYO+/hgCUQ==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.17.3.tgz", | ||||
|             "integrity": "sha512-0AXCjYcfl8Vx26GfyLY4rBQ78Lyt1oND3UozTTMaVXlcKYIjzV+f7TOo5IZx+Kbr6EGUNDLdpA4xfbkWdW/1NA==", | ||||
|             "engines": { | ||||
|                 "node": ">=6" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@sentry/utils": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.16.1.tgz", | ||||
|             "integrity": "sha512-7ngq/i4R8JZitJo9Sl8PDnjSbDehOxgr1vsoMmerIsyRZ651C/8B+jVkMhaAPgSdyJ0AlE3O7DKKTP1FXFw9qw==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.17.3.tgz", | ||||
|             "integrity": "sha512-6/2awDIeHSj0JgiC7DDdV1lxvLmf+/BisWhw09dKvmhVQB3ADvQZbohjUgM+Qam5zE0xmZAfQhvuDwC41W8Wnw==", | ||||
|             "dependencies": { | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -2844,13 +2844,13 @@ | ||||
|             "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/eslint-plugin": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.0.tgz", | ||||
|             "integrity": "sha512-XXVKnMsq2fuu9K2KsIxPUGqb6xAImz8MEChClbXmE3VbveFtBUU5bzM6IPVWqzyADIgdkS2Ws/6Xo7W2TeZWjQ==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.2.tgz", | ||||
|             "integrity": "sha512-4W/9lLuE+v27O/oe7hXJKjNtBLnZE8tQAFpapdxwSVHqtmIoPB1gph3+ahNwVuNL37BX7YQHyGF9Xv6XCnIX2Q==", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/scope-manager": "5.10.0", | ||||
|                 "@typescript-eslint/type-utils": "5.10.0", | ||||
|                 "@typescript-eslint/utils": "5.10.0", | ||||
|                 "@typescript-eslint/scope-manager": "5.10.2", | ||||
|                 "@typescript-eslint/type-utils": "5.10.2", | ||||
|                 "@typescript-eslint/utils": "5.10.2", | ||||
|                 "debug": "^4.3.2", | ||||
|                 "functional-red-black-tree": "^1.0.1", | ||||
|                 "ignore": "^5.1.8", | ||||
| @ -2898,13 +2898,13 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/parser": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.10.0.tgz", | ||||
|             "integrity": "sha512-pJB2CCeHWtwOAeIxv8CHVGJhI5FNyJAIpx5Pt72YkK3QfEzt6qAlXZuyaBmyfOdM62qU0rbxJzNToPTVeJGrQw==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.10.2.tgz", | ||||
|             "integrity": "sha512-JaNYGkaQVhP6HNF+lkdOr2cAs2wdSZBoalE22uYWq8IEv/OVH0RksSGydk+sW8cLoSeYmC+OHvRyv2i4AQ7Czg==", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/scope-manager": "5.10.0", | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/typescript-estree": "5.10.0", | ||||
|                 "@typescript-eslint/scope-manager": "5.10.2", | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "@typescript-eslint/typescript-estree": "5.10.2", | ||||
|                 "debug": "^4.3.2" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -2924,12 +2924,12 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/scope-manager": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.0.tgz", | ||||
|             "integrity": "sha512-tgNgUgb4MhqK6DoKn3RBhyZ9aJga7EQrw+2/OiDk5hKf3pTVZWyqBi7ukP+Z0iEEDMF5FDa64LqODzlfE4O/Dg==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.2.tgz", | ||||
|             "integrity": "sha512-39Tm6f4RoZoVUWBYr3ekS75TYgpr5Y+X0xLZxXqcZNDWZdJdYbKd3q2IR4V9y5NxxiPu/jxJ8XP7EgHiEQtFnw==", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/visitor-keys": "5.10.0" | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "@typescript-eslint/visitor-keys": "5.10.2" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": "^12.22.0 || ^14.17.0 || >=16.0.0" | ||||
| @ -2940,11 +2940,11 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/type-utils": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.10.0.tgz", | ||||
|             "integrity": "sha512-TzlyTmufJO5V886N+hTJBGIfnjQDQ32rJYxPaeiyWKdjsv2Ld5l8cbS7pxim4DeNs62fKzRSt8Q14Evs4JnZyQ==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.10.2.tgz", | ||||
|             "integrity": "sha512-uRKSvw/Ccs5FYEoXW04Z5VfzF2iiZcx8Fu7DGIB7RHozuP0VbKNzP1KfZkHBTM75pCpsWxIthEH1B33dmGBKHw==", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/utils": "5.10.0", | ||||
|                 "@typescript-eslint/utils": "5.10.2", | ||||
|                 "debug": "^4.3.2", | ||||
|                 "tsutils": "^3.21.0" | ||||
|             }, | ||||
| @ -2965,9 +2965,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/types": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.10.0.tgz", | ||||
|             "integrity": "sha512-wUljCgkqHsMZbw60IbOqT/puLfyqqD5PquGiBo1u1IS3PLxdi3RDGlyf032IJyh+eQoGhz9kzhtZa+VC4eWTlQ==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.10.2.tgz", | ||||
|             "integrity": "sha512-Qfp0qk/5j2Rz3p3/WhWgu4S1JtMcPgFLnmAKAW061uXxKSa7VWKZsDXVaMXh2N60CX9h6YLaBoy9PJAfCOjk3w==", | ||||
|             "engines": { | ||||
|                 "node": "^12.22.0 || ^14.17.0 || >=16.0.0" | ||||
|             }, | ||||
| @ -2977,12 +2977,12 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/typescript-estree": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.0.tgz", | ||||
|             "integrity": "sha512-x+7e5IqfwLwsxTdliHRtlIYkgdtYXzE0CkFeV6ytAqq431ZyxCFzNMNR5sr3WOlIG/ihVZr9K/y71VHTF/DUQA==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.2.tgz", | ||||
|             "integrity": "sha512-WHHw6a9vvZls6JkTgGljwCsMkv8wu8XU8WaYKeYhxhWXH/atZeiMW6uDFPLZOvzNOGmuSMvHtZKd6AuC8PrwKQ==", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/visitor-keys": "5.10.0", | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "@typescript-eslint/visitor-keys": "5.10.2", | ||||
|                 "debug": "^4.3.2", | ||||
|                 "globby": "^11.0.4", | ||||
|                 "is-glob": "^4.0.3", | ||||
| @ -3017,14 +3017,14 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/utils": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.10.0.tgz", | ||||
|             "integrity": "sha512-IGYwlt1CVcFoE2ueW4/ioEwybR60RAdGeiJX/iDAw0t5w0wK3S7QncDwpmsM70nKgGTuVchEWB8lwZwHqPAWRg==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.10.2.tgz", | ||||
|             "integrity": "sha512-vuJaBeig1NnBRkf7q9tgMLREiYD7zsMrsN1DA3wcoMDvr3BTFiIpKjGiYZoKPllfEwN7spUjv7ZqD+JhbVjEPg==", | ||||
|             "dependencies": { | ||||
|                 "@types/json-schema": "^7.0.9", | ||||
|                 "@typescript-eslint/scope-manager": "5.10.0", | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/typescript-estree": "5.10.0", | ||||
|                 "@typescript-eslint/scope-manager": "5.10.2", | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "@typescript-eslint/typescript-estree": "5.10.2", | ||||
|                 "eslint-scope": "^5.1.1", | ||||
|                 "eslint-utils": "^3.0.0" | ||||
|             }, | ||||
| @ -3040,11 +3040,11 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/visitor-keys": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.0.tgz", | ||||
|             "integrity": "sha512-GMxj0K1uyrFLPKASLmZzCuSddmjZVbVj3Ouy5QVuIGKZopxvOr24JsS7gruz6C3GExE01mublZ3mIBOaon9zuQ==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.2.tgz", | ||||
|             "integrity": "sha512-zHIhYGGGrFJvvyfwHk5M08C5B5K4bewkm+rrvNTKk1/S15YHR+SA/QUF8ZWscXSfEaB8Nn2puZj+iHcoxVOD/Q==", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "eslint-visitor-keys": "^3.0.0" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -3831,12 +3831,9 @@ | ||||
|             "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" | ||||
|         }, | ||||
|         "node_modules/construct-style-sheets-polyfill": { | ||||
|             "version": "3.0.5", | ||||
|             "resolved": "https://registry.npmjs.org/construct-style-sheets-polyfill/-/construct-style-sheets-polyfill-3.0.5.tgz", | ||||
|             "integrity": "sha512-prLKSx9gYwtmqWtq+pZxppU1SaH9o4ug7JIc0I/1zMV2bFE3GvRtQaMTIpotlhw33XjtC7rGQFOZJsOFnlAAhQ==", | ||||
|             "engines": { | ||||
|                 "npm": ">=7" | ||||
|             } | ||||
|             "version": "3.1.0", | ||||
|             "resolved": "https://registry.npmjs.org/construct-style-sheets-polyfill/-/construct-style-sheets-polyfill-3.1.0.tgz", | ||||
|             "integrity": "sha512-HBLKP0chz8BAY6rBdzda11c3wAZeCZ+kIG4weVC2NM3AXzxx09nhe8t0SQNdloAvg5GLuHwq/0SPOOSPvtCcKw==" | ||||
|         }, | ||||
|         "node_modules/convert-source-map": { | ||||
|             "version": "1.8.0", | ||||
| @ -3909,9 +3906,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/country-flag-icons": { | ||||
|             "version": "1.4.19", | ||||
|             "resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.4.19.tgz", | ||||
|             "integrity": "sha512-1hmXFJ4UURQt0Ex0990B7oOL4n9KLpT9NOSEmZoYh+/5DQ7/pikyqaptqCLUFFv/bYHyvYFeo0fqV82XxU6VOA==" | ||||
|             "version": "1.4.20", | ||||
|             "resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.4.20.tgz", | ||||
|             "integrity": "sha512-f9/cO9IEDIkLdOQeTUMDLEWMcDk4qbTRjbQLpy5pm+yil7Fa7QkKxgiMOQ2z1+Jht8/BAD3JJAmPG4qtK/tbUw==" | ||||
|         }, | ||||
|         "node_modules/create-require": { | ||||
|             "version": "1.1.1", | ||||
| @ -4105,9 +4102,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/eslint": { | ||||
|             "version": "8.7.0", | ||||
|             "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz", | ||||
|             "integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==", | ||||
|             "version": "8.8.0", | ||||
|             "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", | ||||
|             "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", | ||||
|             "dependencies": { | ||||
|                 "@eslint/eslintrc": "^1.0.5", | ||||
|                 "@humanwhocodes/config-array": "^0.9.2", | ||||
| @ -5782,9 +5779,9 @@ | ||||
|             "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" | ||||
|         }, | ||||
|         "node_modules/lit": { | ||||
|             "version": "2.1.1", | ||||
|             "resolved": "https://registry.npmjs.org/lit/-/lit-2.1.1.tgz", | ||||
|             "integrity": "sha512-yqDqf36IhXwOxIQSFqCMgpfvDCRdxLCLZl7m/+tO5C9W/OBHUj17qZpiMBT35v97QMVKcKEi1KZ3hZRyTwBNsQ==", | ||||
|             "version": "2.1.2", | ||||
|             "resolved": "https://registry.npmjs.org/lit/-/lit-2.1.2.tgz", | ||||
|             "integrity": "sha512-XacK89dJXF7BJbpiZSMvzT4RxHag7Wt+yNx7tErEVgGVlOFAeN871bj7ivotCMgYeBFWVp/hjKF/PDTk6L7gMA==", | ||||
|             "dependencies": { | ||||
|                 "@lit/reactive-element": "^1.1.0", | ||||
|                 "lit-element": "^3.1.0", | ||||
| @ -7308,9 +7305,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/rollup": { | ||||
|             "version": "2.66.0", | ||||
|             "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.0.tgz", | ||||
|             "integrity": "sha512-L6mKOkdyP8HK5kKJXaiWG7KZDumPJjuo1P+cfyHOJPNNTK3Moe7zCH5+fy7v8pVmHXtlxorzaBjvkBMB23s98g==", | ||||
|             "version": "2.66.1", | ||||
|             "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.1.tgz", | ||||
|             "integrity": "sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w==", | ||||
|             "bin": { | ||||
|                 "rollup": "dist/bin/rollup" | ||||
|             }, | ||||
| @ -10026,28 +10023,28 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@formatjs/ecma402-abstract": { | ||||
|             "version": "1.11.1", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.1.tgz", | ||||
|             "integrity": "sha512-tgtNODZUGuUI6PAcnvaLZpGrZLVkXnnAvgzOiueYMzFdOdcOw4iH1WKhCe3+r6VR8rHKToJ2HksUGNCB+zt/bg==", | ||||
|             "version": "1.11.2", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.2.tgz", | ||||
|             "integrity": "sha512-qDgOL0vtfJ51cc0pRbFB/oXc4qDbamG22Z6h/QWy6FBxaQgppiy8JF0iYbmNO35cC8r88bQGsgfd/eM6/eTEQQ==", | ||||
|             "requires": { | ||||
|                 "@formatjs/intl-localematcher": "0.2.22", | ||||
|                 "@formatjs/intl-localematcher": "0.2.23", | ||||
|                 "tslib": "^2.1.0" | ||||
|             } | ||||
|         }, | ||||
|         "@formatjs/intl-listformat": { | ||||
|             "version": "6.5.0", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.5.0.tgz", | ||||
|             "integrity": "sha512-gVyAV5QWWtq84MK4cAyJITW+Wb74c2+FT+wa8jhSPxXUky9B5z/k/Ff7or4Vb3KV0YYZuVBQ/vMIoD8Gr182ww==", | ||||
|             "version": "6.5.1", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/intl-listformat/-/intl-listformat-6.5.1.tgz", | ||||
|             "integrity": "sha512-ijsOM7J7aNnGx+1JYUGWgMAcisnK0CxdlPx7KJpUXKj9Mf2Ph28H2WMTL1h1xv9T7SSvH0Nd6asI0Qw4ffw17w==", | ||||
|             "requires": { | ||||
|                 "@formatjs/ecma402-abstract": "1.11.1", | ||||
|                 "@formatjs/intl-localematcher": "0.2.22", | ||||
|                 "@formatjs/ecma402-abstract": "1.11.2", | ||||
|                 "@formatjs/intl-localematcher": "0.2.23", | ||||
|                 "tslib": "^2.1.0" | ||||
|             } | ||||
|         }, | ||||
|         "@formatjs/intl-localematcher": { | ||||
|             "version": "0.2.22", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.22.tgz", | ||||
|             "integrity": "sha512-z+TvbHW8Q/g2l7/PnfUl0mV9gWxV4d0HT6GQyzkO5QI6QjCvCZGiztnmLX7zoyS16uSMvZ2PoMDfSK9xvZkRRA==", | ||||
|             "version": "0.2.23", | ||||
|             "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.2.23.tgz", | ||||
|             "integrity": "sha512-oCe2TOciTtB1bEbJ85EvYrXQxD0epusmVJfJ7AduO0tlbXP42CmDIYIH2CZ+kP2GE+PTLQD1Hbt9kpOpl939MQ==", | ||||
|             "requires": { | ||||
|                 "tslib": "^2.1.0" | ||||
|             } | ||||
| @ -10058,9 +10055,9 @@ | ||||
|             "integrity": "sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg==" | ||||
|         }, | ||||
|         "@goauthentik/api": { | ||||
|             "version": "2022.1.1-1642874681", | ||||
|             "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2022.1.1-1642874681.tgz", | ||||
|             "integrity": "sha512-MOFu1g/5dvQu+BTj8qqc2IMT9fpBICqzERkC949JiDxDSqHg0kuqmxe23vPnFceryQM5zktTBJ+VxXjzR9lX3g==" | ||||
|             "version": "2022.1.3-1643236150", | ||||
|             "resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2022.1.3-1643236150.tgz", | ||||
|             "integrity": "sha512-eteq3Y/4eME6bffuQy8cB6ZrV3DB7rk1IKdvzfUbr9I1hSRzXEBtlzmXp+lhY6RxlEy9hhcJHZO8/OCKFI5l9A==" | ||||
|         }, | ||||
|         "@humanwhocodes/config-array": { | ||||
|             "version": "0.9.2", | ||||
| @ -10145,28 +10142,28 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@lingui/babel-plugin-extract-messages": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.13.1.tgz", | ||||
|             "integrity": "sha512-K0ekhQI49ZTE90bVxvndqdxO80X1ZjacVdznWn4RJq6EEN9ElppMKkWUmAe/vfHGJRCH/2aUIp73xvaXPJPbGg==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.13.2.tgz", | ||||
|             "integrity": "sha512-SyvwfrPqkyj9XM2CB/YK25o0Zi+B8ikoCENwqNSk7201n80YfOJoksc6lQ3X/QODqvy+iuOsiQrVT3qzKblOmg==", | ||||
|             "requires": { | ||||
|                 "@babel/generator": "^7.11.6", | ||||
|                 "@babel/runtime": "^7.11.2", | ||||
|                 "@lingui/conf": "^3.13.1", | ||||
|                 "@lingui/conf": "^3.13.2", | ||||
|                 "mkdirp": "^1.0.4" | ||||
|             } | ||||
|         }, | ||||
|         "@lingui/cli": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.13.1.tgz", | ||||
|             "integrity": "sha512-JGfbdAn1qxHBjuhnLeERMhCLe7UXSFafqq9S//g3+VNHKHfVHfa0CKFUmISMDKMLFdKmbdJCZpYU3DRZNrUGyQ==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.13.2.tgz", | ||||
|             "integrity": "sha512-wPYlsKI7hx1hyntc6enUVUdKVwBM8XW+DnwHslWWw4ShMNvh98gLgAOW1ajXtUym7x0WTjhR+/s436hdxfZ/Og==", | ||||
|             "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.13.1", | ||||
|                 "@lingui/conf": "^3.13.1", | ||||
|                 "@lingui/babel-plugin-extract-messages": "^3.13.2", | ||||
|                 "@lingui/conf": "^3.13.2", | ||||
|                 "babel-plugin-macros": "^3.0.1", | ||||
|                 "bcp-47": "^1.0.7", | ||||
|                 "chalk": "^4.1.0", | ||||
| @ -10239,9 +10236,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@lingui/conf": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.13.1.tgz", | ||||
|             "integrity": "sha512-xWJVdgNiGqYzkYIxHg4c6KqSNleN5/96M2ly+GzBOmA5H75r4hz27DfQpxuC4FuBUAPC+Mk1HTBO9/aFO0BCZg==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.13.2.tgz", | ||||
|             "integrity": "sha512-JhiIBxnh2X4QmLP0/+dnTBc7xnZ6qk5MRsQtJqkEOWGFl09CTrha5uPVqjr5MgkmBOQ6Q8+cRYWG+qtJsuUH5A==", | ||||
|             "requires": { | ||||
|                 "@babel/runtime": "^7.11.2", | ||||
|                 "@endemolshinegroup/cosmiconfig-typescript-loader": "^3.0.2", | ||||
| @ -10297,9 +10294,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@lingui/core": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.13.1.tgz", | ||||
|             "integrity": "sha512-spzRJ/fca9Ddpns27Xmz2f9lgiesrvTZjcpOO2wKJq9QozF1qtv7n1bViQ1Erh2uFaO0kaEzUjkAYU3LtlP4PQ==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.13.2.tgz", | ||||
|             "integrity": "sha512-ic1uC+bS7hpfM4oVugHKel8UhlLAwykSv2TYw3oyeEQhvCS232nSzh+PFbP0BXK1hZ0UdHve7mODpgADuwHIQA==", | ||||
|             "requires": { | ||||
|                 "@babel/runtime": "^7.11.2", | ||||
|                 "make-plural": "^6.2.2", | ||||
| @ -10307,17 +10304,17 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@lingui/detect-locale": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.13.1.tgz", | ||||
|             "integrity": "sha512-ZY/jo3whJ5+QlkpUjZgXzzmON6vA9s0qbXgsKue6xIEOGZ7/z5p05tnHb8RYa6jhpRSYN+CJARx2H82QZMrtwA==" | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.13.2.tgz", | ||||
|             "integrity": "sha512-1fouly1ecq1wCKUGtYgFn0Hdsjuz4bBYxh/oIjrqEeb4+bKdjaHbCT2ypsX7rRxs88yOfOWGUYuuzG0EoJXiSw==" | ||||
|         }, | ||||
|         "@lingui/macro": { | ||||
|             "version": "3.13.1", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.13.1.tgz", | ||||
|             "integrity": "sha512-iXdAbREJpIUs3s78Erbg+7ZRuJsD0S0nyGCeEo9Ml/NDO/MtVYo7XCHecwtCdNxDe/h0NItB3m/7uPZ/BvOLOA==", | ||||
|             "version": "3.13.2", | ||||
|             "resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.13.2.tgz", | ||||
|             "integrity": "sha512-0BdybZkBq8bl4NrT8txX7k8BodyJ/4uQbMIK0ucPJvQ/6Lhj824CodBq5KuMWpcXoMSxUWjQIkIGr1Fi1ckLGg==", | ||||
|             "requires": { | ||||
|                 "@babel/runtime": "^7.11.2", | ||||
|                 "@lingui/conf": "^3.13.1", | ||||
|                 "@lingui/conf": "^3.13.2", | ||||
|                 "ramda": "^0.27.1" | ||||
|             } | ||||
|         }, | ||||
| @ -10369,9 +10366,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@patternfly/patternfly": { | ||||
|             "version": "4.164.2", | ||||
|             "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.164.2.tgz", | ||||
|             "integrity": "sha512-gezQi83JKd6tW0z1J6Q5VvMCW/a58+ys4TWcTuXUMqcV3APQdNxVP+ZV6FIv5353oIPi9HuWAaApVwcCxYZYYg==" | ||||
|             "version": "4.171.1", | ||||
|             "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.171.1.tgz", | ||||
|             "integrity": "sha512-e5Ykg+QOo8TsyOyG6SqytAs52MJXwaP020z3twb8z9G3ZNra92uNsrxGgZEqPJoWbjU4K7LGDxy2DOM1FeRoFw==" | ||||
|         }, | ||||
|         "@polymer/font-roboto": { | ||||
|             "version": "3.0.2", | ||||
| @ -10588,13 +10585,13 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@sentry/browser": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.16.1.tgz", | ||||
|             "integrity": "sha512-F2I5RL7RTLQF9CccMrqt73GRdK3FdqaChED3RulGQX5lH6U3exHGFxwyZxSrY4x6FedfBFYlfXWWCJXpLnFkow==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-6.17.3.tgz", | ||||
|             "integrity": "sha512-UElPk6/Q/78eL8tHGHy080uHVQAuieWXlSMSzrJMVNa+vwXPwEeyL+WbPtKkND2jGwdODjg+pSj960RqhIv+ig==", | ||||
|             "requires": { | ||||
|                 "@sentry/core": "6.16.1", | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/utils": "6.16.1", | ||||
|                 "@sentry/core": "6.17.3", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "@sentry/utils": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "dependencies": { | ||||
| @ -10606,14 +10603,14 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@sentry/core": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.16.1.tgz", | ||||
|             "integrity": "sha512-UFI0264CPUc5cR1zJH+S2UPOANpm6dLJOnsvnIGTjsrwzR0h8Hdl6rC2R/GPq+WNbnipo9hkiIwDlqbqvIU5vw==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.17.3.tgz", | ||||
|             "integrity": "sha512-h7WgrNL0RVlr8Dceh97ZiXNdmEumDutpoqFijjiX4x72IiC6zSaVD4IsqrdGln+v8iJ3l3lX44HHqzubDub1OQ==", | ||||
|             "requires": { | ||||
|                 "@sentry/hub": "6.16.1", | ||||
|                 "@sentry/minimal": "6.16.1", | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/utils": "6.16.1", | ||||
|                 "@sentry/hub": "6.17.3", | ||||
|                 "@sentry/minimal": "6.17.3", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "@sentry/utils": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "dependencies": { | ||||
| @ -10625,12 +10622,12 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@sentry/hub": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.16.1.tgz", | ||||
|             "integrity": "sha512-4PGtg6AfpqMkreTpL7ymDeQ/U1uXv03bKUuFdtsSTn/FRf9TLS4JB0KuTZCxfp1IRgAA+iFg6B784dDkT8R9eg==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.17.3.tgz", | ||||
|             "integrity": "sha512-TDxv8nRvk45xvfQg6zs8GYzQzgo0EMhI3wjQZLiNfW2rzybKmIwVp2x3O4PAc3WPzwg4bYNgSAkYKVlHmYjRCg==", | ||||
|             "requires": { | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/utils": "6.16.1", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "@sentry/utils": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "dependencies": { | ||||
| @ -10642,12 +10639,12 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@sentry/minimal": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.16.1.tgz", | ||||
|             "integrity": "sha512-dq+mI1EQIvUM+zJtGCVgH3/B3Sbx4hKlGf2Usovm9KoqWYA+QpfVBholYDe/H2RXgO7LFEefDLvOdHDkqeJoyA==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.17.3.tgz", | ||||
|             "integrity": "sha512-zvGGfHNNA92Lqx6P8ZwOUkmRmAiQl0AQFRXl9So1Ayq9bJRnFLJZv4YFVnp2wE4HXYIlfBYb51+GlGB5LIuPmw==", | ||||
|             "requires": { | ||||
|                 "@sentry/hub": "6.16.1", | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/hub": "6.17.3", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "dependencies": { | ||||
| @ -10659,14 +10656,14 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@sentry/tracing": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.16.1.tgz", | ||||
|             "integrity": "sha512-MPSbqXX59P+OEeST+U2V/8Hu/8QjpTUxTNeNyTHWIbbchdcMMjDbXTS3etCgajZR6Ro+DHElOz5cdSxH6IBGlA==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.17.3.tgz", | ||||
|             "integrity": "sha512-GnHugxw5qkWwYmeQbbrswuWpb0bpYqyJr/dO25QQOCwp+cckQrvBYTMC8zGJG10u94O4el0lQaQnNFz9WF3r6g==", | ||||
|             "requires": { | ||||
|                 "@sentry/hub": "6.16.1", | ||||
|                 "@sentry/minimal": "6.16.1", | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/utils": "6.16.1", | ||||
|                 "@sentry/hub": "6.17.3", | ||||
|                 "@sentry/minimal": "6.17.3", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "@sentry/utils": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "dependencies": { | ||||
| @ -10678,16 +10675,16 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@sentry/types": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.16.1.tgz", | ||||
|             "integrity": "sha512-Wh354g30UsJ5kYJbercektGX4ZMc9MHU++1NjeN2bTMnbofEcpUDWIiKeulZEY65IC1iU+1zRQQgtYO+/hgCUQ==" | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.17.3.tgz", | ||||
|             "integrity": "sha512-0AXCjYcfl8Vx26GfyLY4rBQ78Lyt1oND3UozTTMaVXlcKYIjzV+f7TOo5IZx+Kbr6EGUNDLdpA4xfbkWdW/1NA==" | ||||
|         }, | ||||
|         "@sentry/utils": { | ||||
|             "version": "6.16.1", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.16.1.tgz", | ||||
|             "integrity": "sha512-7ngq/i4R8JZitJo9Sl8PDnjSbDehOxgr1vsoMmerIsyRZ651C/8B+jVkMhaAPgSdyJ0AlE3O7DKKTP1FXFw9qw==", | ||||
|             "version": "6.17.3", | ||||
|             "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.17.3.tgz", | ||||
|             "integrity": "sha512-6/2awDIeHSj0JgiC7DDdV1lxvLmf+/BisWhw09dKvmhVQB3ADvQZbohjUgM+Qam5zE0xmZAfQhvuDwC41W8Wnw==", | ||||
|             "requires": { | ||||
|                 "@sentry/types": "6.16.1", | ||||
|                 "@sentry/types": "6.17.3", | ||||
|                 "tslib": "^1.9.3" | ||||
|             }, | ||||
|             "dependencies": { | ||||
| @ -10963,13 +10960,13 @@ | ||||
|             "integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==" | ||||
|         }, | ||||
|         "@typescript-eslint/eslint-plugin": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.0.tgz", | ||||
|             "integrity": "sha512-XXVKnMsq2fuu9K2KsIxPUGqb6xAImz8MEChClbXmE3VbveFtBUU5bzM6IPVWqzyADIgdkS2Ws/6Xo7W2TeZWjQ==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.2.tgz", | ||||
|             "integrity": "sha512-4W/9lLuE+v27O/oe7hXJKjNtBLnZE8tQAFpapdxwSVHqtmIoPB1gph3+ahNwVuNL37BX7YQHyGF9Xv6XCnIX2Q==", | ||||
|             "requires": { | ||||
|                 "@typescript-eslint/scope-manager": "5.10.0", | ||||
|                 "@typescript-eslint/type-utils": "5.10.0", | ||||
|                 "@typescript-eslint/utils": "5.10.0", | ||||
|                 "@typescript-eslint/scope-manager": "5.10.2", | ||||
|                 "@typescript-eslint/type-utils": "5.10.2", | ||||
|                 "@typescript-eslint/utils": "5.10.2", | ||||
|                 "debug": "^4.3.2", | ||||
|                 "functional-red-black-tree": "^1.0.1", | ||||
|                 "ignore": "^5.1.8", | ||||
| @ -10994,47 +10991,47 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@typescript-eslint/parser": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.10.0.tgz", | ||||
|             "integrity": "sha512-pJB2CCeHWtwOAeIxv8CHVGJhI5FNyJAIpx5Pt72YkK3QfEzt6qAlXZuyaBmyfOdM62qU0rbxJzNToPTVeJGrQw==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.10.2.tgz", | ||||
|             "integrity": "sha512-JaNYGkaQVhP6HNF+lkdOr2cAs2wdSZBoalE22uYWq8IEv/OVH0RksSGydk+sW8cLoSeYmC+OHvRyv2i4AQ7Czg==", | ||||
|             "requires": { | ||||
|                 "@typescript-eslint/scope-manager": "5.10.0", | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/typescript-estree": "5.10.0", | ||||
|                 "@typescript-eslint/scope-manager": "5.10.2", | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "@typescript-eslint/typescript-estree": "5.10.2", | ||||
|                 "debug": "^4.3.2" | ||||
|             } | ||||
|         }, | ||||
|         "@typescript-eslint/scope-manager": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.0.tgz", | ||||
|             "integrity": "sha512-tgNgUgb4MhqK6DoKn3RBhyZ9aJga7EQrw+2/OiDk5hKf3pTVZWyqBi7ukP+Z0iEEDMF5FDa64LqODzlfE4O/Dg==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.10.2.tgz", | ||||
|             "integrity": "sha512-39Tm6f4RoZoVUWBYr3ekS75TYgpr5Y+X0xLZxXqcZNDWZdJdYbKd3q2IR4V9y5NxxiPu/jxJ8XP7EgHiEQtFnw==", | ||||
|             "requires": { | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/visitor-keys": "5.10.0" | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "@typescript-eslint/visitor-keys": "5.10.2" | ||||
|             } | ||||
|         }, | ||||
|         "@typescript-eslint/type-utils": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.10.0.tgz", | ||||
|             "integrity": "sha512-TzlyTmufJO5V886N+hTJBGIfnjQDQ32rJYxPaeiyWKdjsv2Ld5l8cbS7pxim4DeNs62fKzRSt8Q14Evs4JnZyQ==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.10.2.tgz", | ||||
|             "integrity": "sha512-uRKSvw/Ccs5FYEoXW04Z5VfzF2iiZcx8Fu7DGIB7RHozuP0VbKNzP1KfZkHBTM75pCpsWxIthEH1B33dmGBKHw==", | ||||
|             "requires": { | ||||
|                 "@typescript-eslint/utils": "5.10.0", | ||||
|                 "@typescript-eslint/utils": "5.10.2", | ||||
|                 "debug": "^4.3.2", | ||||
|                 "tsutils": "^3.21.0" | ||||
|             } | ||||
|         }, | ||||
|         "@typescript-eslint/types": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.10.0.tgz", | ||||
|             "integrity": "sha512-wUljCgkqHsMZbw60IbOqT/puLfyqqD5PquGiBo1u1IS3PLxdi3RDGlyf032IJyh+eQoGhz9kzhtZa+VC4eWTlQ==" | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.10.2.tgz", | ||||
|             "integrity": "sha512-Qfp0qk/5j2Rz3p3/WhWgu4S1JtMcPgFLnmAKAW061uXxKSa7VWKZsDXVaMXh2N60CX9h6YLaBoy9PJAfCOjk3w==" | ||||
|         }, | ||||
|         "@typescript-eslint/typescript-estree": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.0.tgz", | ||||
|             "integrity": "sha512-x+7e5IqfwLwsxTdliHRtlIYkgdtYXzE0CkFeV6ytAqq431ZyxCFzNMNR5sr3WOlIG/ihVZr9K/y71VHTF/DUQA==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.2.tgz", | ||||
|             "integrity": "sha512-WHHw6a9vvZls6JkTgGljwCsMkv8wu8XU8WaYKeYhxhWXH/atZeiMW6uDFPLZOvzNOGmuSMvHtZKd6AuC8PrwKQ==", | ||||
|             "requires": { | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/visitor-keys": "5.10.0", | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "@typescript-eslint/visitor-keys": "5.10.2", | ||||
|                 "debug": "^4.3.2", | ||||
|                 "globby": "^11.0.4", | ||||
|                 "is-glob": "^4.0.3", | ||||
| @ -11053,24 +11050,24 @@ | ||||
|             } | ||||
|         }, | ||||
|         "@typescript-eslint/utils": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.10.0.tgz", | ||||
|             "integrity": "sha512-IGYwlt1CVcFoE2ueW4/ioEwybR60RAdGeiJX/iDAw0t5w0wK3S7QncDwpmsM70nKgGTuVchEWB8lwZwHqPAWRg==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.10.2.tgz", | ||||
|             "integrity": "sha512-vuJaBeig1NnBRkf7q9tgMLREiYD7zsMrsN1DA3wcoMDvr3BTFiIpKjGiYZoKPllfEwN7spUjv7ZqD+JhbVjEPg==", | ||||
|             "requires": { | ||||
|                 "@types/json-schema": "^7.0.9", | ||||
|                 "@typescript-eslint/scope-manager": "5.10.0", | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/typescript-estree": "5.10.0", | ||||
|                 "@typescript-eslint/scope-manager": "5.10.2", | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "@typescript-eslint/typescript-estree": "5.10.2", | ||||
|                 "eslint-scope": "^5.1.1", | ||||
|                 "eslint-utils": "^3.0.0" | ||||
|             } | ||||
|         }, | ||||
|         "@typescript-eslint/visitor-keys": { | ||||
|             "version": "5.10.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.0.tgz", | ||||
|             "integrity": "sha512-GMxj0K1uyrFLPKASLmZzCuSddmjZVbVj3Ouy5QVuIGKZopxvOr24JsS7gruz6C3GExE01mublZ3mIBOaon9zuQ==", | ||||
|             "version": "5.10.2", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.2.tgz", | ||||
|             "integrity": "sha512-zHIhYGGGrFJvvyfwHk5M08C5B5K4bewkm+rrvNTKk1/S15YHR+SA/QUF8ZWscXSfEaB8Nn2puZj+iHcoxVOD/Q==", | ||||
|             "requires": { | ||||
|                 "@typescript-eslint/types": "5.10.0", | ||||
|                 "@typescript-eslint/types": "5.10.2", | ||||
|                 "eslint-visitor-keys": "^3.0.0" | ||||
|             }, | ||||
|             "dependencies": { | ||||
| @ -11636,9 +11633,9 @@ | ||||
|             "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" | ||||
|         }, | ||||
|         "construct-style-sheets-polyfill": { | ||||
|             "version": "3.0.5", | ||||
|             "resolved": "https://registry.npmjs.org/construct-style-sheets-polyfill/-/construct-style-sheets-polyfill-3.0.5.tgz", | ||||
|             "integrity": "sha512-prLKSx9gYwtmqWtq+pZxppU1SaH9o4ug7JIc0I/1zMV2bFE3GvRtQaMTIpotlhw33XjtC7rGQFOZJsOFnlAAhQ==" | ||||
|             "version": "3.1.0", | ||||
|             "resolved": "https://registry.npmjs.org/construct-style-sheets-polyfill/-/construct-style-sheets-polyfill-3.1.0.tgz", | ||||
|             "integrity": "sha512-HBLKP0chz8BAY6rBdzda11c3wAZeCZ+kIG4weVC2NM3AXzxx09nhe8t0SQNdloAvg5GLuHwq/0SPOOSPvtCcKw==" | ||||
|         }, | ||||
|         "convert-source-map": { | ||||
|             "version": "1.8.0", | ||||
| @ -11692,9 +11689,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "country-flag-icons": { | ||||
|             "version": "1.4.19", | ||||
|             "resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.4.19.tgz", | ||||
|             "integrity": "sha512-1hmXFJ4UURQt0Ex0990B7oOL4n9KLpT9NOSEmZoYh+/5DQ7/pikyqaptqCLUFFv/bYHyvYFeo0fqV82XxU6VOA==" | ||||
|             "version": "1.4.20", | ||||
|             "resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.4.20.tgz", | ||||
|             "integrity": "sha512-f9/cO9IEDIkLdOQeTUMDLEWMcDk4qbTRjbQLpy5pm+yil7Fa7QkKxgiMOQ2z1+Jht8/BAD3JJAmPG4qtK/tbUw==" | ||||
|         }, | ||||
|         "create-require": { | ||||
|             "version": "1.1.1", | ||||
| @ -11837,9 +11834,9 @@ | ||||
|             "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" | ||||
|         }, | ||||
|         "eslint": { | ||||
|             "version": "8.7.0", | ||||
|             "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz", | ||||
|             "integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==", | ||||
|             "version": "8.8.0", | ||||
|             "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.8.0.tgz", | ||||
|             "integrity": "sha512-H3KXAzQGBH1plhYS3okDix2ZthuYJlQQEGE5k0IKuEqUSiyu4AmxxlJ2MtTYeJ3xB4jDhcYCwGOg2TXYdnDXlQ==", | ||||
|             "requires": { | ||||
|                 "@eslint/eslintrc": "^1.0.5", | ||||
|                 "@humanwhocodes/config-array": "^0.9.2", | ||||
| @ -13074,9 +13071,9 @@ | ||||
|             "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" | ||||
|         }, | ||||
|         "lit": { | ||||
|             "version": "2.1.1", | ||||
|             "resolved": "https://registry.npmjs.org/lit/-/lit-2.1.1.tgz", | ||||
|             "integrity": "sha512-yqDqf36IhXwOxIQSFqCMgpfvDCRdxLCLZl7m/+tO5C9W/OBHUj17qZpiMBT35v97QMVKcKEi1KZ3hZRyTwBNsQ==", | ||||
|             "version": "2.1.2", | ||||
|             "resolved": "https://registry.npmjs.org/lit/-/lit-2.1.2.tgz", | ||||
|             "integrity": "sha512-XacK89dJXF7BJbpiZSMvzT4RxHag7Wt+yNx7tErEVgGVlOFAeN871bj7ivotCMgYeBFWVp/hjKF/PDTk6L7gMA==", | ||||
|             "requires": { | ||||
|                 "@lit/reactive-element": "^1.1.0", | ||||
|                 "lit-element": "^3.1.0", | ||||
| @ -14218,9 +14215,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "rollup": { | ||||
|             "version": "2.66.0", | ||||
|             "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.0.tgz", | ||||
|             "integrity": "sha512-L6mKOkdyP8HK5kKJXaiWG7KZDumPJjuo1P+cfyHOJPNNTK3Moe7zCH5+fy7v8pVmHXtlxorzaBjvkBMB23s98g==", | ||||
|             "version": "2.66.1", | ||||
|             "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.66.1.tgz", | ||||
|             "integrity": "sha512-crSgLhSkLMnKr4s9iZ/1qJCplgAgrRY+igWv8KhG/AjKOJ0YX/WpmANyn8oxrw+zenF3BXWDLa7Xl/QZISH+7w==", | ||||
|             "requires": { | ||||
|                 "fsevents": "~2.3.2" | ||||
|             } | ||||
|  | ||||
| @ -20,7 +20,9 @@ | ||||
|             "en", | ||||
|             "pseudo-LOCALE", | ||||
|             "fr_FR", | ||||
|             "tr" | ||||
|             "tr", | ||||
|             "es", | ||||
|             "pl" | ||||
|         ], | ||||
|         "formatOptions": { | ||||
|             "lineNumbers": false | ||||
| @ -51,15 +53,15 @@ | ||||
|         "@babel/plugin-transform-runtime": "^7.16.10", | ||||
|         "@babel/preset-env": "^7.16.11", | ||||
|         "@babel/preset-typescript": "^7.16.7", | ||||
|         "@formatjs/intl-listformat": "^6.5.0", | ||||
|         "@formatjs/intl-listformat": "^6.5.1", | ||||
|         "@fortawesome/fontawesome-free": "^5.15.4", | ||||
|         "@goauthentik/api": "^2022.1.1-1642874681", | ||||
|         "@goauthentik/api": "^2022.1.3-1643236150", | ||||
|         "@jackfranklin/rollup-plugin-markdown": "^0.3.0", | ||||
|         "@lingui/cli": "^3.13.1", | ||||
|         "@lingui/core": "^3.13.1", | ||||
|         "@lingui/detect-locale": "^3.13.1", | ||||
|         "@lingui/macro": "^3.13.1", | ||||
|         "@patternfly/patternfly": "^4.164.2", | ||||
|         "@lingui/cli": "^3.13.2", | ||||
|         "@lingui/core": "^3.13.2", | ||||
|         "@lingui/detect-locale": "^3.13.2", | ||||
|         "@lingui/macro": "^3.13.2", | ||||
|         "@patternfly/patternfly": "^4.171.1", | ||||
|         "@polymer/iron-form": "^3.0.1", | ||||
|         "@polymer/paper-input": "^3.2.1", | ||||
|         "@rollup/plugin-babel": "^5.3.0", | ||||
| @ -67,34 +69,34 @@ | ||||
|         "@rollup/plugin-node-resolve": "^13.1.3", | ||||
|         "@rollup/plugin-replace": "^3.0.1", | ||||
|         "@rollup/plugin-typescript": "^8.3.0", | ||||
|         "@sentry/browser": "^6.16.1", | ||||
|         "@sentry/tracing": "^6.16.1", | ||||
|         "@sentry/browser": "^6.17.3", | ||||
|         "@sentry/tracing": "^6.17.3", | ||||
|         "@squoosh/cli": "^0.7.2", | ||||
|         "@trivago/prettier-plugin-sort-imports": "^3.1.1", | ||||
|         "@types/chart.js": "^2.9.35", | ||||
|         "@types/codemirror": "5.60.5", | ||||
|         "@types/grecaptcha": "^3.0.3", | ||||
|         "@typescript-eslint/eslint-plugin": "^5.10.0", | ||||
|         "@typescript-eslint/parser": "^5.10.0", | ||||
|         "@typescript-eslint/eslint-plugin": "^5.10.2", | ||||
|         "@typescript-eslint/parser": "^5.10.2", | ||||
|         "@webcomponents/webcomponentsjs": "^2.6.0", | ||||
|         "babel-plugin-macros": "^3.1.0", | ||||
|         "base64-js": "^1.5.1", | ||||
|         "chart.js": "^3.7.0", | ||||
|         "chartjs-adapter-moment": "^1.0.0", | ||||
|         "codemirror": "^5.65.1", | ||||
|         "construct-style-sheets-polyfill": "^3.0.5", | ||||
|         "country-flag-icons": "^1.4.19", | ||||
|         "eslint": "^8.7.0", | ||||
|         "construct-style-sheets-polyfill": "^3.1.0", | ||||
|         "country-flag-icons": "^1.4.20", | ||||
|         "eslint": "^8.8.0", | ||||
|         "eslint-config-google": "^0.14.0", | ||||
|         "eslint-plugin-custom-elements": "0.0.4", | ||||
|         "eslint-plugin-lit": "^1.6.1", | ||||
|         "flowchart.js": "^1.17.0", | ||||
|         "fuse.js": "^6.5.3", | ||||
|         "lit": "^2.1.1", | ||||
|         "lit": "^2.1.2", | ||||
|         "moment": "^2.29.1", | ||||
|         "prettier": "^2.5.1", | ||||
|         "rapidoc": "^9.1.4", | ||||
|         "rollup": "^2.66.0", | ||||
|         "rollup": "^2.66.1", | ||||
|         "rollup-plugin-copy": "^3.4.0", | ||||
|         "rollup-plugin-cssimport": "^1.0.2", | ||||
|         "rollup-plugin-minify-html-literals": "^1.2.6", | ||||
|  | ||||
| @ -3,7 +3,7 @@ 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 = "2022.1.2"; | ||||
| export const VERSION = "2022.1.4"; | ||||
| export const TITLE_DEFAULT = "authentik"; | ||||
| export const ROUTE_SEPARATOR = ";"; | ||||
|  | ||||
|  | ||||
| @ -113,6 +113,9 @@ export class FlowExecutor extends LitElement implements StageHost { | ||||
|             .pf-c-drawer__content { | ||||
|                 background-color: transparent; | ||||
|             } | ||||
|             .pf-c-login__main { | ||||
|                 width: 100%; | ||||
|             } | ||||
|         `); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -1,11 +1,13 @@ | ||||
| import { en, fr, tr } from "make-plural/plurals"; | ||||
| import { en, es, fr, pl, tr } from "make-plural/plurals"; | ||||
|  | ||||
| import { Messages, i18n } from "@lingui/core"; | ||||
| import { detect, fromNavigator, fromStorage, fromUrl } from "@lingui/detect-locale"; | ||||
| import { t } from "@lingui/macro"; | ||||
|  | ||||
| import { messages as localeEN } from "../locales/en"; | ||||
| import { messages as localeES } from "../locales/es"; | ||||
| import { messages as localeFR_FR } from "../locales/fr_FR"; | ||||
| import { messages as localePL } from "../locales/pl"; | ||||
| import { messages as localeDEBUG } from "../locales/pseudo-LOCALE"; | ||||
| import { messages as localeTR } from "../locales/tr"; | ||||
|  | ||||
| @ -29,7 +31,7 @@ export const LOCALES: { | ||||
|         locale: localeDEBUG, | ||||
|     }, | ||||
|     { | ||||
|         code: "fr_FR", | ||||
|         code: "fr", | ||||
|         plurals: fr, | ||||
|         label: t`French`, | ||||
|         locale: localeFR_FR, | ||||
| @ -40,6 +42,18 @@ export const LOCALES: { | ||||
|         label: t`Turkish`, | ||||
|         locale: localeTR, | ||||
|     }, | ||||
|     { | ||||
|         code: "es", | ||||
|         plurals: es, | ||||
|         label: t`Spanish`, | ||||
|         locale: localeES, | ||||
|     }, | ||||
|     { | ||||
|         code: "pl", | ||||
|         plurals: pl, | ||||
|         label: t`Polish`, | ||||
|         locale: localePL, | ||||
|     }, | ||||
| ]; | ||||
|  | ||||
| LOCALES.forEach((locale) => { | ||||
| @ -50,9 +64,13 @@ LOCALES.forEach((locale) => { | ||||
| const DEFAULT_FALLBACK = () => "en"; | ||||
|  | ||||
| export function autoDetectLanguage() { | ||||
|     const detected = | ||||
|     let detected = | ||||
|         detect(fromUrl("lang"), fromStorage("lang"), fromNavigator(), DEFAULT_FALLBACK) || | ||||
|         DEFAULT_FALLBACK(); | ||||
|     // For now we only care about the first locale part | ||||
|     if (detected.includes("_")) { | ||||
|         detected = detected.split("_")[0]; | ||||
|     } | ||||
|     if (detected in i18n._messages) { | ||||
|         console.debug(`authentik/locale: Activating detected locale '${detected}'`); | ||||
|         i18n.activate(detected); | ||||
|  | ||||
| @ -3608,6 +3608,10 @@ msgstr "Policy {0}" | ||||
| msgid "Policy-specific settings" | ||||
| msgstr "Policy-specific settings" | ||||
|  | ||||
| #: src/interfaces/locale.ts | ||||
| msgid "Polish" | ||||
| msgstr "Polish" | ||||
|  | ||||
| #: src/pages/providers/saml/SAMLProviderForm.ts | ||||
| msgid "Post" | ||||
| msgstr "Post" | ||||
| @ -4433,6 +4437,10 @@ msgstr "Sources" | ||||
| msgid "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves." | ||||
| msgstr "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves." | ||||
|  | ||||
| #: src/interfaces/locale.ts | ||||
| msgid "Spanish" | ||||
| msgstr "Spanish" | ||||
|  | ||||
| #: src/pages/sources/ldap/LDAPSourceForm.ts | ||||
| msgid "Specify multiple server URIs by separating them with a comma." | ||||
| msgstr "Specify multiple server URIs by separating them with a comma." | ||||
|  | ||||
							
								
								
									
										6090
									
								
								web/src/locales/es.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6090
									
								
								web/src/locales/es.po
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -3580,6 +3580,10 @@ msgstr "Poliitique {0}" | ||||
| msgid "Policy-specific settings" | ||||
| msgstr "Paramètres spécifiques à la politique" | ||||
|  | ||||
| #: src/interfaces/locale.ts | ||||
| msgid "Polish" | ||||
| msgstr "" | ||||
|  | ||||
| #: src/pages/providers/saml/SAMLProviderForm.ts | ||||
| msgid "Post" | ||||
| msgstr "Appliquer" | ||||
| @ -4395,6 +4399,10 @@ msgstr "Sources" | ||||
| msgid "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves." | ||||
| msgstr "Sources d'identités, qui peuvent soit être synchronisées dans la base de données d'Authentik, soit être utilisées par les utilisateurs pour s'authentifier et s'inscrire." | ||||
|  | ||||
| #: src/interfaces/locale.ts | ||||
| msgid "Spanish" | ||||
| msgstr "" | ||||
|  | ||||
| #: src/pages/sources/ldap/LDAPSourceForm.ts | ||||
| msgid "Specify multiple server URIs by separating them with a comma." | ||||
| msgstr "" | ||||
|  | ||||
							
								
								
									
										6090
									
								
								web/src/locales/pl.po
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6090
									
								
								web/src/locales/pl.po
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -3598,6 +3598,10 @@ msgstr "" | ||||
| msgid "Policy-specific settings" | ||||
| msgstr "" | ||||
|  | ||||
| #: src/interfaces/locale.ts | ||||
| msgid "Polish" | ||||
| msgstr "" | ||||
|  | ||||
| #: src/pages/providers/saml/SAMLProviderForm.ts | ||||
| msgid "Post" | ||||
| msgstr "" | ||||
| @ -4423,6 +4427,10 @@ msgstr "" | ||||
| msgid "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves." | ||||
| msgstr "" | ||||
|  | ||||
| #: src/interfaces/locale.ts | ||||
| msgid "Spanish" | ||||
| msgstr "" | ||||
|  | ||||
| #: src/pages/sources/ldap/LDAPSourceForm.ts | ||||
| msgid "Specify multiple server URIs by separating them with a comma." | ||||
| msgstr "" | ||||
|  | ||||
| @ -3546,6 +3546,10 @@ msgstr "İlke {0}" | ||||
| msgid "Policy-specific settings" | ||||
| msgstr "İlke özel ayarlar" | ||||
|  | ||||
| #: src/interfaces/locale.ts | ||||
| msgid "Polish" | ||||
| msgstr "" | ||||
|  | ||||
| #: src/pages/providers/saml/SAMLProviderForm.ts | ||||
| msgid "Post" | ||||
| msgstr "Post" | ||||
| @ -4344,6 +4348,10 @@ msgstr "Kaynaklar" | ||||
| msgid "Sources of identities, which can either be synced into authentik's database, or can be used by users to authenticate and enroll themselves." | ||||
| msgstr "Auentik'in veritabanına senkronize edilebilen ya da kullanıcılar tarafından kimlik doğrulaması ve kayıt yaptırmak için kullanılabilen kimliklerin kaynakları." | ||||
|  | ||||
| #: src/interfaces/locale.ts | ||||
| msgid "Spanish" | ||||
| msgstr "" | ||||
|  | ||||
| #: src/pages/sources/ldap/LDAPSourceForm.ts | ||||
| msgid "Specify multiple server URIs by separating them with a comma." | ||||
| msgstr "Birden çok sunucu URI'lerini virgülle ayırarak belirtin." | ||||
|  | ||||
| @ -216,6 +216,7 @@ export class SAMLProviderViewPage extends LitElement { | ||||
|                                       ${t`Download`} | ||||
|                                   </a> | ||||
|                                   <ak-action-button | ||||
|                                       class="pf-m-secondary" | ||||
|                                       .apiRequest=${() => { | ||||
|                                           const fullUrl = | ||||
|                                               window.location.origin + | ||||
|  | ||||
| @ -34,7 +34,7 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage, | ||||
|     } | ||||
|  | ||||
|     @property({ attribute: false }) | ||||
|     provider?: ProviderEnum; | ||||
|     provider: ProviderEnum = ProviderEnum.Twilio; | ||||
|  | ||||
|     @property({ attribute: false }) | ||||
|     authType?: AuthTypeEnum; | ||||
| @ -60,6 +60,101 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage, | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     renderProviderTwillio(): TemplateResult { | ||||
|         return html` <ak-form-element-horizontal | ||||
|                 label=${t`Twilio Account SID`} | ||||
|                 ?required=${true} | ||||
|                 name="accountSid" | ||||
|             > | ||||
|                 <input | ||||
|                     type="text" | ||||
|                     value="${ifDefined(this.instance?.accountSid || "")}" | ||||
|                     class="pf-c-form-control" | ||||
|                     required | ||||
|                 /> | ||||
|                 <p class="pf-c-form__helper-text"> | ||||
|                     ${t`Get this value from https://console.twilio.com`} | ||||
|                 </p> | ||||
|             </ak-form-element-horizontal> | ||||
|             <ak-form-element-horizontal label=${t`Twilio Auth Token`} ?required=${true} name="auth"> | ||||
|                 <input | ||||
|                     type="text" | ||||
|                     value="${ifDefined(this.instance?.auth || "")}" | ||||
|                     class="pf-c-form-control" | ||||
|                     required | ||||
|                 /> | ||||
|                 <p class="pf-c-form__helper-text"> | ||||
|                     ${t`Get this value from https://console.twilio.com`} | ||||
|                 </p> | ||||
|             </ak-form-element-horizontal>`; | ||||
|     } | ||||
|  | ||||
|     renderProviderGeneric(): TemplateResult { | ||||
|         return html` <ak-form-element-horizontal | ||||
|                 label=${t`Authentication Type`} | ||||
|                 @change=${(ev: Event) => { | ||||
|                     const current = (ev.target as HTMLInputElement).value; | ||||
|                     this.authType = current as AuthTypeEnum; | ||||
|                 }} | ||||
|                 ?required=${true} | ||||
|                 name="authType" | ||||
|             > | ||||
|                 <select class="pf-c-form-control"> | ||||
|                     <option | ||||
|                         value="${AuthTypeEnum.Basic}" | ||||
|                         ?selected=${this.instance?.authType === AuthTypeEnum.Basic} | ||||
|                     > | ||||
|                         ${t`Basic Auth`} | ||||
|                     </option> | ||||
|                     <option | ||||
|                         value="${AuthTypeEnum.Bearer}" | ||||
|                         ?selected=${this.instance?.authType === AuthTypeEnum.Bearer} | ||||
|                     > | ||||
|                         ${t`Bearer Token`} | ||||
|                     </option> | ||||
|                 </select> | ||||
|             </ak-form-element-horizontal> | ||||
|             <ak-form-element-horizontal | ||||
|                 label=${t`External API URL`} | ||||
|                 ?required=${true} | ||||
|                 name="accountSid" | ||||
|             > | ||||
|                 <input | ||||
|                     type="text" | ||||
|                     value="${ifDefined(this.instance?.accountSid || "")}" | ||||
|                     class="pf-c-form-control" | ||||
|                     required | ||||
|                 /> | ||||
|                 <p class="pf-c-form__helper-text"> | ||||
|                     ${t`This is the full endpoint to send POST requests to.`} | ||||
|                 </p> | ||||
|             </ak-form-element-horizontal> | ||||
|             <ak-form-element-horizontal label=${t`API Auth Username`} ?required=${true} name="auth"> | ||||
|                 <input | ||||
|                     type="text" | ||||
|                     value="${ifDefined(this.instance?.auth || "")}" | ||||
|                     class="pf-c-form-control" | ||||
|                 /> | ||||
|                 <p class="pf-c-form__helper-text"> | ||||
|                     ${t`This is the username to be used with basic auth or the token when used with bearer token`} | ||||
|                 </p> | ||||
|             </ak-form-element-horizontal> | ||||
|             <ak-form-element-horizontal | ||||
|                 label=${t`API Auth password`} | ||||
|                 ?required=${false} | ||||
|                 name="authPassword" | ||||
|             > | ||||
|                 <input | ||||
|                     type="text" | ||||
|                     value="${ifDefined(this.instance?.authPassword)}" | ||||
|                     class="pf-c-form-control" | ||||
|                 /> | ||||
|                 <p class="pf-c-form__helper-text"> | ||||
|                     ${t`This is the password to be used with basic auth`} | ||||
|                 </p> | ||||
|             </ak-form-element-horizontal>`; | ||||
|     } | ||||
|  | ||||
|     renderForm(): TemplateResult { | ||||
|         return html`<form class="pf-c-form pf-m-horizontal"> | ||||
|             <div class="form-help-text"> | ||||
| @ -117,113 +212,9 @@ export class AuthenticatorSMSStageForm extends ModelForm<AuthenticatorSMSStage, | ||||
|                             ${t`Number the SMS will be sent from.`} | ||||
|                         </p> | ||||
|                     </ak-form-element-horizontal> | ||||
|  | ||||
|                     <ak-form-element-horizontal | ||||
|                         label=${t`Twilio Account SID`} | ||||
|                         ?hidden=${this.provider !== ProviderEnum.Twilio} | ||||
|                         ?required=${true} | ||||
|                         name="accountSid" | ||||
|                     > | ||||
|                         <input | ||||
|                             type="text" | ||||
|                             value="${ifDefined(this.instance?.accountSid || "")}" | ||||
|                             class="pf-c-form-control" | ||||
|                             required | ||||
|                         /> | ||||
|                         <p class="pf-c-form__helper-text"> | ||||
|                             ${t`Get this value from https://console.twilio.com`} | ||||
|                         </p> | ||||
|                     </ak-form-element-horizontal> | ||||
|                     <ak-form-element-horizontal | ||||
|                         label=${t`Twilio Auth Token`} | ||||
|                         ?hidden=${this.provider !== ProviderEnum.Twilio} | ||||
|                         ?required=${true} | ||||
|                         name="auth" | ||||
|                     > | ||||
|                         <input | ||||
|                             type="text" | ||||
|                             value="${ifDefined(this.instance?.auth || "")}" | ||||
|                             class="pf-c-form-control" | ||||
|                             required | ||||
|                         /> | ||||
|                         <p class="pf-c-form__helper-text"> | ||||
|                             ${t`Get this value from https://console.twilio.com`} | ||||
|                         </p> | ||||
|                     </ak-form-element-horizontal> | ||||
|                     <ak-form-element-horizontal | ||||
|                         label=${t`Authentication Type`} | ||||
|                         ?hidden=${this.provider !== ProviderEnum.Generic} | ||||
|                         @change=${(ev: Event) => { | ||||
|                             const current = (ev.target as HTMLInputElement).value; | ||||
|                             this.authType = current as AuthTypeEnum; | ||||
|                         }} | ||||
|                         ?required=${true} | ||||
|                         name="authType" | ||||
|                     > | ||||
|                         <select class="pf-c-form-control"> | ||||
|                             <option | ||||
|                                 value="${AuthTypeEnum.Basic}" | ||||
|                                 ?selected=${this.instance?.authType === AuthTypeEnum.Basic} | ||||
|                             > | ||||
|                                 ${t`Basic Auth`} | ||||
|                             </option> | ||||
|                             <option | ||||
|                                 value="${AuthTypeEnum.Bearer}" | ||||
|                                 ?selected=${this.instance?.authType === AuthTypeEnum.Bearer} | ||||
|                             > | ||||
|                                 ${t`Bearer Token`} | ||||
|                             </option> | ||||
|                         </select> | ||||
|                     </ak-form-element-horizontal> | ||||
|                     <ak-form-element-horizontal | ||||
|                         label=${t`External API URL`} | ||||
|                         ?hidden=${this.provider !== ProviderEnum.Generic} | ||||
|                         ?required=${true} | ||||
|                         name="accountSid" | ||||
|                     > | ||||
|                         <input | ||||
|                             type="text" | ||||
|                             value="${ifDefined(this.instance?.accountSid || "")}" | ||||
|                             class="pf-c-form-control" | ||||
|                             required | ||||
|                         /> | ||||
|                         <p class="pf-c-form__helper-text"> | ||||
|                             ${t`This is the full endpoint to send POST requests to.`} | ||||
|                         </p> | ||||
|                     </ak-form-element-horizontal> | ||||
|                     <ak-form-element-horizontal | ||||
|                         label=${t`API Auth Username`} | ||||
|                         ?hidden=${this.provider !== ProviderEnum.Generic} | ||||
|                         ?required=${true} | ||||
|                         name="auth" | ||||
|                     > | ||||
|                         <input | ||||
|                             type="text" | ||||
|                             value="${ifDefined(this.instance?.auth || "")}" | ||||
|                             class="pf-c-form-control" | ||||
|                         /> | ||||
|                         <p class="pf-c-form__helper-text"> | ||||
|                             ${t`This is the username to be used with basic auth or the token when used with bearer token`} | ||||
|                         </p> | ||||
|                     </ak-form-element-horizontal> | ||||
|                     <ak-form-element-horizontal | ||||
|                         label=${t`API Auth password`} | ||||
|                         ?hidden=${!( | ||||
|                             this.provider === ProviderEnum.Generic && | ||||
|                             this.authType === AuthTypeEnum.Basic | ||||
|                         )} | ||||
|                         ?required=${false} | ||||
|                         name="authPassword" | ||||
|                     > | ||||
|                         <input | ||||
|                             type="text" | ||||
|                             value="${ifDefined(this.instance?.authPassword)}" | ||||
|                             class="pf-c-form-control" | ||||
|                         /> | ||||
|                         <p class="pf-c-form__helper-text"> | ||||
|                             ${t`This is the password to be used with basic auth`} | ||||
|                         </p> | ||||
|                     </ak-form-element-horizontal> | ||||
|                     ${this.provider === ProviderEnum.Generic | ||||
|                         ? this.renderProviderGeneric() | ||||
|                         : this.renderProviderTwillio()} | ||||
|                     <ak-form-element-horizontal label=${t`Configuration flow`} name="configureFlow"> | ||||
|                         <select class="pf-c-form-control"> | ||||
|                             <option | ||||
|  | ||||
| @ -227,6 +227,7 @@ export class UserListPage extends TablePage<User> { | ||||
|                                             } | ||||
|                                             return html` | ||||
|                                                 <ak-action-button | ||||
|                                                     class="pf-m-secondary" | ||||
|                                                     .apiRequest=${() => { | ||||
|                                                         return new CoreApi(DEFAULT_CONFIG) | ||||
|                                                             .coreUsersRecoveryRetrieve({ | ||||
|  | ||||
| @ -103,7 +103,7 @@ export class UserDetailsForm extends ModelForm<UserSelf, number> { | ||||
|                                     value=${locale.code} | ||||
|                                     ?selected=${config.locale === locale.code} | ||||
|                                 > | ||||
|                                     ${locale.label} | ||||
|                                     ${locale.code.toUpperCase()} - ${locale.label} | ||||
|                                 </option>`; | ||||
|                             })} | ||||
|                         </select> | ||||
|  | ||||
							
								
								
									
										38
									
								
								website/developer-docs/docs/writing-documentation.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								website/developer-docs/docs/writing-documentation.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| --- | ||||
| title: Writing documentation | ||||
| --- | ||||
|  | ||||
| Writing documentation for authentik is a great way for both new and experienced users to improve and contribute to the project. Here are a few guidelines to ensure | ||||
| the documentation is easy to read and uses similar phrasing. | ||||
|  | ||||
| # General guidelines | ||||
|  | ||||
| - authentik should always be stylized as `authentik` (with a lower-case a and ending with a k) | ||||
| - Documentation should use American english | ||||
| - Feel free to use Docusaurus-specific features, see [here](https://docusaurus.io/docs/next/markdown-features) | ||||
| - Use abbreviations where it makes sense (for commonly used terms like SAML and OAuth) | ||||
| - Phrasing should never blame the user, and should be subjective, i.e | ||||
|  | ||||
|     - **DON'T** `You may never click x.` | ||||
|     - **DO** `x should never be clicked.` | ||||
|  | ||||
| - When referring to other objects in authentik, use cursive text, and link to the corresponding documentation if possible. | ||||
| - When referring to external tools, give an example how to use the tools or explain how the user can use them. | ||||
| - Make sure to add the documentation to add to the sidebar, if adding a new page. | ||||
| - Test how the documentation renders using the Netlify Preview, especially when using Docusaurus-specific features. | ||||
|  | ||||
| If you find any documentation that doesn't match these guidelines, feel free to either open an Issue or a PR so they can be fixed. | ||||
|  | ||||
| ## Integration guidelines | ||||
|  | ||||
| These guidelines apply in addition to the ones above. | ||||
|  | ||||
| - For placeholders, use angle brackets (`<placeholder-name>`). | ||||
|  | ||||
|     Make sure to also define if the placeholder is something the user needs to define, something another system defines, or randomly generated. | ||||
|  | ||||
|     If you're adding configuration snippets to the documentation, and the snippet is in a language that supports comments, | ||||
|     other placeholders may be used, for example comments referencing an earlier step. | ||||
|  | ||||
| - For placeholder domains, use `authentik.company` and `app-name.company`, where `app-name` is the name of the application you are writing documentation for. | ||||
| - Try to order the documentation in the order that makes it easiest for the user to configure. | ||||
| @ -1,11 +1,15 @@ | ||||
| --- | ||||
| title: Translation | ||||
| title: Translations | ||||
| --- | ||||
|  | ||||
| Translation in authentik is done in two places. Most of the text is defined in the frontend in `web/`, and a subset of messages is defined in the backend. | ||||
|  | ||||
| The frontend uses [lingui](https://lingui.js.org/), and the backend uses the built-in django translation tools. | ||||
|  | ||||
| :::info | ||||
| Please review the [Writing documentation](./docs/writing-documentation) guidelines as they apply to documentation too. | ||||
| ::: | ||||
|  | ||||
| ## Online translation | ||||
|  | ||||
| To simplify translation you can use https://www.transifex.com/beryjuorg/authentik/, which has no local requirements. | ||||
|  | ||||
| @ -18,6 +18,17 @@ Example: | ||||
| user_email_local = regex_replace(request.user.email, '(.+)@.+', '') | ||||
| ``` | ||||
|  | ||||
| ### `list_flatten(value: list[Any] | Any) -> Optional[Any}` | ||||
|  | ||||
| Flatten a list by either returning its first element, None if the list is empty, or the passed in object if its not a list. | ||||
|  | ||||
| Example: | ||||
|  | ||||
| ```python | ||||
| user = list_flatten(["foo"]) | ||||
| # user = "foo" | ||||
| ``` | ||||
|  | ||||
| ### `ak_is_group_member(user: User, **group_filters) -> bool` | ||||
|  | ||||
| Check if `user` is member of a group matching `**group_filters`. | ||||
|  | ||||
| @ -23,12 +23,12 @@ The container is created with the following hardcoded properties: | ||||
|     Additionally, the proxy outposts have the following extra labels to add themselves into traefik automatically. | ||||
|  | ||||
|     - `traefik.enable`: "true" | ||||
|     - `traefik.http.routers.ak-outpost-<outpost-id>-router.rule`: `Host(...)` | ||||
|     - `traefik.http.routers.ak-outpost-<outpost-id>-router.service`: `ak-outpost-<outpost-id>-service` | ||||
|     - `traefik.http.routers.ak-outpost-<outpost-id>-router.tls`: "true" | ||||
|     - `traefik.http.services.ak-outpost-<outpost-id>-service.loadbalancer.healthcheck.path`: "/akprox/ping" | ||||
|     - `traefik.http.services.ak-outpost-<outpost-id>-service.loadbalancer.healthcheck.port`: "9300" | ||||
|     - `traefik.http.services.ak-outpost-<outpost-id>-service.loadbalancer.server.port`: "9000" | ||||
|     - `traefik.http.routers.ak-outpost-<outpost-name>-router.rule`: `Host(...)` | ||||
|     - `traefik.http.routers.ak-outpost-<outpost-name>-router.service`: `ak-outpost-<outpost-name>-service` | ||||
|     - `traefik.http.routers.ak-outpost-<outpost-name>-router.tls`: "true" | ||||
|     - `traefik.http.services.ak-outpost-<outpost-name>-service.loadbalancer.healthcheck.path`: "/akprox/ping" | ||||
|     - `traefik.http.services.ak-outpost-<outpost-name>-service.loadbalancer.healthcheck.port`: "9300" | ||||
|     - `traefik.http.services.ak-outpost-<outpost-name>-service.loadbalancer.server.port`: "9000" | ||||
|  | ||||
| ## Permissions | ||||
|  | ||||
|  | ||||
| @ -32,5 +32,5 @@ metadata: | ||||
|     nginx.ingress.kubernetes.io/auth-response-headers: | | ||||
|       Set-Cookie,X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid | ||||
|     nginx.ingress.kubernetes.io/auth-snippet: | | ||||
|        proxy_set_header X-Forwarded-Host $http_host; | ||||
|        proxy_set_header Host $http_host; | ||||
| ``` | ||||
|  | ||||
| @ -6,8 +6,6 @@ For Nginx Proxy Manager you can use this snippet | ||||
| # header from upstream' error when trying to access an application protected by goauthentik | ||||
| proxy_buffers 8 16k; | ||||
| proxy_buffer_size 32k; | ||||
| fastcgi_buffers 16 16k; | ||||
| fastcgi_buffer_size 32k; | ||||
|  | ||||
| location / { | ||||
|     # Put your proxy_pass to your application here | ||||
| @ -16,6 +14,8 @@ location / { | ||||
|     # authentik-specific config | ||||
|     auth_request        /akprox/auth/nginx; | ||||
|     error_page          401 = @akprox_signin; | ||||
|     auth_request_set $auth_cookie $upstream_http_set_cookie; | ||||
|     add_header Set-Cookie $auth_cookie; | ||||
|  | ||||
|     # translate headers from the outposts back to the actual upstream | ||||
|     auth_request_set $authentik_username $upstream_http_x_authentik_username; | ||||
| @ -37,6 +37,7 @@ location /akprox { | ||||
|     # ensure the host of this vserver matches your external URL you've configured | ||||
|     # in authentik | ||||
|     proxy_set_header    Host $host; | ||||
|     proxy_set_header    X-Original-URL $scheme://$http_host$request_uri; | ||||
|     add_header          Set-Cookie $auth_cookie; | ||||
|     auth_request_set    $auth_cookie $upstream_http_set_cookie; | ||||
| } | ||||
|  | ||||
| @ -13,8 +13,6 @@ server { | ||||
|     # header from upstream' error when trying to access an application protected by goauthentik | ||||
|     proxy_buffers 8 16k; | ||||
|     proxy_buffer_size 32k; | ||||
|     fastcgi_buffers 16 16k; | ||||
|     fastcgi_buffer_size 32k; | ||||
|  | ||||
|     location / { | ||||
|         # Put your proxy_pass to your application here | ||||
| @ -25,6 +23,8 @@ server { | ||||
|         error_page          401 = @akprox_signin; | ||||
|         # For domain level, use the below error_page to redirect to your authentik server with the full redirect path | ||||
|         # error_page          401 =302 https://authentik.company/akprox/start?rd=$scheme://$http_host$request_uri; | ||||
|         auth_request_set $auth_cookie $upstream_http_set_cookie; | ||||
|         add_header Set-Cookie $auth_cookie; | ||||
|  | ||||
|         # translate headers from the outposts back to the actual upstream | ||||
|         auth_request_set $authentik_username $upstream_http_x_authentik_username; | ||||
| @ -46,6 +46,7 @@ server { | ||||
|         # ensure the host of this vserver matches your external URL you've configured | ||||
|         # in authentik | ||||
|         proxy_set_header    Host $host; | ||||
|         proxy_set_header    X-Original-URL $scheme://$http_host$request_uri; | ||||
|         add_header          Set-Cookie $auth_cookie; | ||||
|         auth_request_set    $auth_cookie $upstream_http_set_cookie; | ||||
|     } | ||||
|  | ||||
| @ -58,6 +58,50 @@ This release mostly removes legacy fields and features that have been deprecated | ||||
| - web/admin: fix missing configure flow setting on webuahtn setup stage form | ||||
| - web/flows: remove node directly instead of using removeChild() | ||||
|  | ||||
| ## Fixed in 2022.1.2 | ||||
|  | ||||
| - internal/proxyv2: only allow access to /akprox in nginx mode when forward url could be extracted | ||||
| - lib: disable backup by default, add note to configuration | ||||
| - lifecycle: replace lowercase, deprecated prometheus_multiproc_dir | ||||
| - outposts: allow custom label for docker containers | ||||
| - policies/hibp: ensure password is encodable | ||||
| - providers/proxy: add PathPrefix to auto-traefik labels | ||||
| - root: upgrade python dependencies | ||||
|  | ||||
| ## Fixed in 2022.1.3 | ||||
|  | ||||
| - internal: add support for X-Original-URL | ||||
| - internal: add optional debug server listening on 9900 | ||||
| - internal: don't override server header | ||||
| - internal: start adding tests to outpost | ||||
| - lifecycle: make secret_key warning more prominent | ||||
| - lifecycle: wait for db in worker | ||||
| - outposts/ldap: Fix more case sensitivity issues. (#2144) | ||||
| - outposts/proxy: add more test cases for domain-level auth | ||||
| - outposts/proxy: fix potential empty redirect, add tests | ||||
| - outposts/proxy: trace full headers to debug | ||||
| - providers/proxy: fix traefik label | ||||
| - root: add max-requests for gunicorn and max tasks for celery | ||||
| - root: fix redis passwords not being encoded correctly | ||||
| - web/admin: fix links which look like labels | ||||
| - web/admin: fix SMS Stage form not working | ||||
|  | ||||
| ## Fixed in 2022.1.4 | ||||
|  | ||||
| - core: fix view_token permission not being assigned on token creation for non-admin user | ||||
| - lifecycle: remove gunicorn reload option | ||||
| - lifecycle: send analytics in gunicorn config to decrease outgoing requests when workers get restarted | ||||
| - providers/proxy: add support for X-Original-URI in nginx, better handle missing headers and report errors to authentik | ||||
| - providers/proxy: don't include hostname and scheme in redirect when we only got a path and not a full URL | ||||
| - providers/proxy: fix routing for external_host when using forward_auth_domain | ||||
| - providers/proxy: set traefik labels using object_naming_template instead of UUID | ||||
| - sources/ldap: add list_flatten function to property mappings, enable on managed LDAP mappings | ||||
| - web: add es locale | ||||
| - web: add pl locale | ||||
| - web/admin: only check first half of locale when detecting | ||||
| - web/flows: fix width on flow container | ||||
| - web/user: include locale code in locale selection | ||||
|  | ||||
| ## Upgrading | ||||
|  | ||||
| This release does not introduce any new requirements. | ||||
|  | ||||
							
								
								
									
										72
									
								
								website/integrations/services/zulip/index.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								website/integrations/services/zulip/index.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | ||||
| --- | ||||
| title: Zulip | ||||
| --- | ||||
|  | ||||
| ## What is Zulip | ||||
|  | ||||
| From https://zulip.com | ||||
|  | ||||
| :::note | ||||
| **Zulip**: Chat for distributed teams. Zulip combines the immediacy of real-time chat with an email threading model. | ||||
| With Zulip, you can catch up on important conversations while ignoring irrelevant ones.  | ||||
| ::: | ||||
|  | ||||
| ## Preperation | ||||
|  | ||||
| The following placeholders will be used: | ||||
|  | ||||
| - `authentik.company` is the FQDN of the authentik install. | ||||
| - `zulip.company` is the FQDN of the Zulip instance. | ||||
|  | ||||
| Create an application in authentik and note the slug, as this will be used later. Create a SAML provider with the following parameters: | ||||
|  | ||||
| - ACS URL: `https://zulip.company/complete/saml/` | ||||
| - Issuer: `https://authentik.company` | ||||
| - Service Provider Binding: `Post` | ||||
| - Signing Keypair: Select any certificate you have. | ||||
| - Property mappings: Select all Managed mappings. | ||||
|  | ||||
| ## Zulip Configuration | ||||
|  | ||||
| Zulip is a Django application and is configured using `/etc/zulip/settings.py`. Only settings that differ | ||||
| from the defaults are displayed below. Please make sure you have the latest `settings.py` file as more settings  | ||||
| might have been added to defaults since you installed Zulip. | ||||
|  | ||||
| Uncomment `zproject.backends.SAMLAuthBackend` inside the `AUTHENTICATION_BACKENDS` parameter to enable SAML support | ||||
| and fill in the following required configuration. | ||||
|  | ||||
| ``` | ||||
| SOCIAL_AUTH_SAML_ORG_INFO = { | ||||
|     "en-US": { | ||||
|         "displayname": "authentik Zulip", | ||||
|         "name": "zulip", | ||||
|         "url": "{}{}".format("https://", EXTERNAL_HOST), | ||||
|     }, | ||||
| } | ||||
|  | ||||
| SOCIAL_AUTH_SAML_ENABLED_IDPS: Dict[str, Any] = { | ||||
|     # idp identifier and settings | ||||
|     "authentik": { | ||||
|         | ||||
| 	    # KEEP OTHER SETTINGS AS DEFAULT OR CONFIGURE THEM ACCORDING TO YOUR PREFERENCES | ||||
|         "entity_id": "https://authentik.company", | ||||
|         "url": "https://authentik.company/application/saml/<application slug>/sso/binding/redirect/", | ||||
|         "display_name": "authentik SAML", | ||||
|     }, | ||||
| } | ||||
|  | ||||
| ``` | ||||
|  | ||||
| Place the certificate you associated with the SAML provider in authentik inside the `/etc/zulip/saml/idps` directory.  | ||||
| The certificate file name must match the idp identifier name you set in the configuration (i.e. authentik.crt). | ||||
|  | ||||
| :::note | ||||
| Remember to restart Zulip. | ||||
| ::: | ||||
| ## Additional Resources | ||||
|  | ||||
| Please refer to the following for further information: | ||||
|  | ||||
| - https://zulip.com/ | ||||
| - https://zulip.readthedocs.io | ||||
| - https://chat.zulip.org/ (Official public Zulip Chat instance) | ||||
| @ -31,17 +31,17 @@ The following placeholders will be used: | ||||
|  | ||||
|      | ||||
|  | ||||
| Additional infos: https://support.microfocus.com/kb/doc.php?id=7023371 | ||||
| Additional info: https://support.microfocus.com/kb/doc.php?id=7023371 | ||||
|  | ||||
| ## authentik Setup | ||||
|  | ||||
| In authentik, create a new LDAP Source in Resources -> Sources. | ||||
| In authentik, create a new LDAP Source in Directory -> Federation & Social login. | ||||
|  | ||||
| Use these settings: | ||||
|  | ||||
| - Server URI: `ldap://ad.company` | ||||
|  | ||||
|     For authentik to be able to write passwords back to Active Directory, make sure to use `ldaps://` | ||||
|     For authentik to be able to write passwords back to Active Directory, make sure to use `ldaps://`. You can test to verify LDAPS is working using `ldp.exe`. | ||||
|  | ||||
|     You can specify multiple servers by separating URIs with a comma, like `ldap://dc1.ad.company,ldap://dc2.ad.company`. | ||||
|  | ||||
| @ -53,17 +53,16 @@ Use these settings: | ||||
| - Property mappings: Control/Command-select all Mappings which start with "authentik default LDAP" and "authentik default Active Directory" | ||||
| - Group property mappings: Select "authentik default LDAP Mapping: Name" | ||||
|  | ||||
| The other settings might need to be adjusted based on the setup of your domain. | ||||
| Additional settings that might need to be adjusted based on the setup of your domain: | ||||
|  | ||||
| - Addition User/Group DN: Additional DN which is _prepended_ to your Base DN for user synchronization. | ||||
| - Addition Group DN: Additional DN which is _prepended_ to your Base DN for group synchronization. | ||||
| - User object filter: Which objects should be considered users. | ||||
| - Group: If enabled, all synchronized groups will be given this group as a parent. | ||||
| - Addition User/Group DN: Additional DN which is _prepended_ to your Base DN configured above to limit the scope of synchronization for Users and Groups | ||||
| - User object filter: Which objects should be considered users. For Active Directory set it to `(&(objectClass=user)(!(objectClass=computer)))` to exclude Computer accounts. | ||||
| - Group object filter: Which objects should be considered groups. | ||||
| - Group membership field: Which user field saves the group membership | ||||
| - Object uniqueness field: A user field which contains a unique Identifier | ||||
| - Sync parent group: If enabled, all synchronized groups will be given this group as a parent. | ||||
|  | ||||
| After you save the source, a synchronization will start in the background. When its done, you cen see the summary on the System Tasks page. | ||||
| After you save the source, a synchronization will start in the background. When its done, you can see the summary under Dashboards -> System Tasks. | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -33,3 +33,11 @@ For FreeIPA, follow the [FreeIPA Integration](../freeipa/) | ||||
| - Sync groups: Enable/disable group synchronization. Groups are synced in the background every 5 minutes. | ||||
| - Sync parent group: Optionally set this group as the parent group for all synced groups. An example use case of this would be to import Active Directory groups under a root `imported-from-ad` group. | ||||
| - Property mappings: Define which LDAP properties map to which authentik properties. The default set of property mappings is generated for Active Directory. See also [LDAP Property Mappings](../../../docs/property-mappings/#ldap-property-mapping) | ||||
|  | ||||
| ## Property mappings | ||||
|  | ||||
| LDAP property mappings can be used to convert the raw LDAP response into an authentik user/group. | ||||
|  | ||||
| By default, authentik ships with some pre-configured mappings for the most common LDAP setups. | ||||
|  | ||||
| You can assign the value of a mapping to any user attribute, or save it as a custom attribute by prefixing the object field with `attribute.` Keep in mind though, data types from the LDAP server will be carried over. This means that with some implementations, where fields ar stored as array in LDAP, they will be saved as array in authentik. To prevent this, use the built-in `list_flatten` function. | ||||
|  | ||||
							
								
								
									
										3023
									
								
								website/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										3023
									
								
								website/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -12,8 +12,8 @@ | ||||
|         "serve": "docusaurus serve" | ||||
|     }, | ||||
|     "dependencies": { | ||||
|         "@docusaurus/plugin-client-redirects": "2.0.0-beta.14", | ||||
|         "@docusaurus/preset-classic": "2.0.0-beta.14", | ||||
|         "@docusaurus/plugin-client-redirects": "2.0.0-beta.15", | ||||
|         "@docusaurus/preset-classic": "2.0.0-beta.15", | ||||
|         "@mdx-js/react": "^1.6.22", | ||||
|         "clsx": "^1.1.1", | ||||
|         "postcss": "^8.4.5", | ||||
|  | ||||
| @ -26,5 +26,9 @@ module.exports = { | ||||
|             type: "doc", | ||||
|             id: "translation", | ||||
|         }, | ||||
|         { | ||||
|             type: "doc", | ||||
|             id: "docs/writing-documentation", | ||||
|         }, | ||||
|     ], | ||||
| }; | ||||
|  | ||||
| @ -42,6 +42,7 @@ module.exports = { | ||||
|                 "services/wiki-js/index", | ||||
|                 "services/wordpress/index", | ||||
|                 "services/zabbix/index", | ||||
|                 "services/zulip/index", | ||||
|             ], | ||||
|         }, | ||||
|         { | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	