Compare commits
	
		
			150 Commits
		
	
	
		
			dependabot
			...
			website/do
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 2706fc0c4f | |||
| 10cc63883f | |||
| 53a6eb2b89 | |||
| 4a174944ff | |||
| 4cca1e517e | |||
| ec02f30be0 | |||
| 09c5dd3c9e | |||
| d436801768 | |||
| c15e74e5fc | |||
| 837cd3bcb0 | |||
| 53a9c147cd | |||
| d7f166f260 | |||
| 8ce9343457 | |||
| 6af27d0c90 | |||
| 6fd48ccf9b | |||
| 5567967848 | |||
| 090a377c78 | |||
| 3e7bda87ea | |||
| f22a539b50 | |||
| 54811b2b05 | |||
| 35263f71ee | |||
| f0bc809389 | |||
| 75b45312ee | |||
| e4eeb43f8a | |||
| 04850e5c84 | |||
| fbae9f2f34 | |||
| 3c966d9252 | |||
| 9f1cef18b2 | |||
| aae20dc399 | |||
| 4dc43b788a | |||
| a3b40a97ef | |||
| 852106f02f | |||
| 7a34428aff | |||
| c1b6a681a0 | |||
| 7a8c2e7ad9 | |||
| a57381ca4a | |||
| 154dde9a9a | |||
| a15365a9f1 | |||
| 10f11cbc31 | |||
| caec23d52a | |||
| 7e1781ed76 | |||
| 0cfdbbbec6 | |||
| 8a1b7cb166 | |||
| d2cd829818 | |||
| f367a84676 | |||
| 32d6b03a3c | |||
| 08027bf0ad | |||
| 8c02b25677 | |||
| 160f137707 | |||
| 52c35fab06 | |||
| 69a07c1c88 | |||
| 1b018f33de | |||
| 93e55fe59a | |||
| 691a0d66ee | |||
| 3f4328bf2a | |||
| e9944fab9d | |||
| d81c199a89 | |||
| b945552b7c | |||
| 5347b85c9f | |||
| fb2401cf9e | |||
| b161315811 | |||
| 0fa2267b86 | |||
| 4bbdddb876 | |||
| bca9c0965e | |||
| dd58b5044e | |||
| c4f081cb68 | |||
| 59aad31459 | |||
| de9db3cb83 | |||
| 24eb5fcda9 | |||
| 556ae6a5cb | |||
| a479d9c1d8 | |||
| b8bb969ee7 | |||
| 7d361e4734 | |||
| dc7c7686a3 | |||
| 94b4977397 | |||
| 7f822e1cb7 | |||
| fb3ec1f38b | |||
| 87505517ee | |||
| 4c5fe84f92 | |||
| 5faa224c81 | |||
| 736da3abef | |||
| 52d90f8d3b | |||
| 7b812de977 | |||
| a4bd2cc263 | |||
| 14038ba8d2 | |||
| eaff59b6b0 | |||
| cb702ca07a | |||
| cb0bfb0dad | |||
| bf46d5c916 | |||
| 59e686c8b9 | |||
| 9e736f2838 | |||
| c2dd3d9c1b | |||
| 42302d3187 | |||
| 20ccabf3ec | |||
| 8f939fa577 | |||
| 2519bcef89 | |||
| 3e3615a859 | |||
| 79e82c8dc9 | |||
| ccd4432e1f | |||
| b3137f5307 | |||
| 2591ed9840 | |||
| b3e89ef570 | |||
| 45b48c5cd6 | |||
| 1eefd834fc | |||
| 4cc6ed97c5 | |||
| bb55d9b3de | |||
| 3972afb865 | |||
| 04a013cc1b | |||
| fb396f7737 | |||
| cf120ff3ff | |||
| 3e4923d52e | |||
| 01793088f0 | |||
| e2bf2ec2cc | |||
| 4dfbe28709 | |||
| b2021a7191 | |||
| 81e5fb0c18 | |||
| a2a2d940a8 | |||
| c034930219 | |||
| da3dc51d87 | |||
| d217a39513 | |||
| 7729a9317c | |||
| be5f5dd3f0 | |||
| bed8d5da4b | |||
| 4f70f84e80 | |||
| 97b8551866 | |||
| 9a0b67e700 | |||
| 97e4c89cec | |||
| 65aedde8f7 | |||
| 17450f23bf | |||
| ab3ad6b7fd | |||
| 45bc3cbd41 | |||
| 9c1bcac6af | |||
| 0a133265c5 | |||
| 57f25a97c9 | |||
| 8f32242787 | |||
| c4bb19051d | |||
| 10f4fae711 | |||
| 2d9eab3f60 | |||
| fa66195619 | |||
| 134eb126b6 | |||
| f5a6136a58 | |||
| 1a82dfcd61 | |||
| 61fc1dc1fb | |||
| 1f921cc18e | |||
| 2f94ee3f1f | |||
| 154fba12e0 | |||
| 0d18c1d797 | |||
| e905dd52d8 | |||
| 245126a1c3 | |||
| 15d84d30ba | 
| @ -1,5 +1,5 @@ | ||||
| [bumpversion] | ||||
| current_version = 2025.4.1 | ||||
| current_version = 2025.6.0 | ||||
| tag = True | ||||
| commit = True | ||||
| parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))? | ||||
|  | ||||
							
								
								
									
										2
									
								
								.github/actions/setup/action.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/actions/setup/action.yml
									
									
									
									
										vendored
									
									
								
							| @ -36,7 +36,7 @@ runs: | ||||
|       with: | ||||
|         go-version-file: "go.mod" | ||||
|     - name: Setup docker cache | ||||
|       uses: ScribeMD/docker-cache@0.5.0 | ||||
|       uses: AndreKurait/docker-cache@0fe76702a40db986d9663c24954fc14c6a6031b7 | ||||
|       with: | ||||
|         key: docker-images-${{ runner.os }}-${{ hashFiles('.github/actions/setup/docker-compose.yml', 'Makefile') }}-${{ inputs.postgresql_version }} | ||||
|     - name: Setup dependencies | ||||
|  | ||||
| @ -94,7 +94,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \ | ||||
|     /bin/sh -c "GEOIPUPDATE_LICENSE_KEY_FILE=/run/secrets/GEOIPUPDATE_LICENSE_KEY /usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0" | ||||
|  | ||||
| # Stage 5: Download uv | ||||
| FROM ghcr.io/astral-sh/uv:0.7.8 AS uv | ||||
| FROM ghcr.io/astral-sh/uv:0.7.10 AS uv | ||||
| # Stage 6: Base python image | ||||
| FROM ghcr.io/goauthentik/fips-python:3.13.3-slim-bookworm-fips AS python-base | ||||
|  | ||||
|  | ||||
| @ -20,8 +20,8 @@ Even if the issue is not a CVE, we still greatly appreciate your help in hardeni | ||||
|  | ||||
| | Version   | Supported | | ||||
| | --------- | --------- | | ||||
| | 2025.2.x  | ✅        | | ||||
| | 2025.4.x  | ✅        | | ||||
| | 2025.6.x  | ✅        | | ||||
|  | ||||
| ## Reporting a Vulnerability | ||||
|  | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
|  | ||||
| from os import environ | ||||
|  | ||||
| __version__ = "2025.4.1" | ||||
| __version__ = "2025.6.0" | ||||
| ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -84,6 +84,7 @@ from authentik.flows.views.executor import QS_KEY_TOKEN | ||||
| from authentik.lib.avatars import get_avatar | ||||
| from authentik.rbac.decorators import permission_required | ||||
| from authentik.rbac.models import get_permission_choices | ||||
| from authentik.stages.email.flow import pickle_flow_token_for_email | ||||
| from authentik.stages.email.models import EmailStage | ||||
| from authentik.stages.email.tasks import send_mails | ||||
| from authentik.stages.email.utils import TemplateEmailMessage | ||||
| @ -451,7 +452,7 @@ class UserViewSet(UsedByMixin, ModelViewSet): | ||||
|     def list(self, request, *args, **kwargs): | ||||
|         return super().list(request, *args, **kwargs) | ||||
|  | ||||
|     def _create_recovery_link(self) -> tuple[str, Token]: | ||||
|     def _create_recovery_link(self, for_email=False) -> tuple[str, Token]: | ||||
|         """Create a recovery link (when the current brand has a recovery flow set), | ||||
|         that can either be shown to an admin or sent to the user directly""" | ||||
|         brand: Brand = self.request._request.brand | ||||
| @ -473,12 +474,16 @@ class UserViewSet(UsedByMixin, ModelViewSet): | ||||
|             raise ValidationError( | ||||
|                 {"non_field_errors": "Recovery flow not applicable to user"} | ||||
|             ) from None | ||||
|         _plan = FlowToken.pickle(plan) | ||||
|         if for_email: | ||||
|             _plan = pickle_flow_token_for_email(plan) | ||||
|         token, __ = FlowToken.objects.update_or_create( | ||||
|             identifier=f"{user.uid}-password-reset", | ||||
|             defaults={ | ||||
|                 "user": user, | ||||
|                 "flow": flow, | ||||
|                 "_plan": FlowToken.pickle(plan), | ||||
|                 "_plan": _plan, | ||||
|                 "revoke_on_execution": not for_email, | ||||
|             }, | ||||
|         ) | ||||
|         querystring = urlencode({QS_KEY_TOKEN: token.key}) | ||||
| @ -648,7 +653,7 @@ class UserViewSet(UsedByMixin, ModelViewSet): | ||||
|         if for_user.email == "": | ||||
|             LOGGER.debug("User doesn't have an email address") | ||||
|             raise ValidationError({"non_field_errors": "User does not have an email address set."}) | ||||
|         link, token = self._create_recovery_link() | ||||
|         link, token = self._create_recovery_link(for_email=True) | ||||
|         # Lookup the email stage to assure the current user can access it | ||||
|         stages = get_objects_for_user( | ||||
|             request.user, "authentik_stages_email.view_emailstage" | ||||
|  | ||||
| @ -79,6 +79,7 @@ def _migrate_session( | ||||
|         AuthenticatedSession.objects.using(db_alias).create( | ||||
|             session=session, | ||||
|             user=old_auth_session.user, | ||||
|             uuid=old_auth_session.uuid, | ||||
|         ) | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -1,10 +1,81 @@ | ||||
| # Generated by Django 5.1.9 on 2025-05-14 11:15 | ||||
|  | ||||
| from django.apps.registry import Apps | ||||
| from django.apps.registry import Apps, apps as global_apps | ||||
| from django.db import migrations | ||||
| from django.contrib.contenttypes.management import create_contenttypes | ||||
| from django.contrib.auth.management import create_permissions | ||||
| from django.db.backends.base.schema import BaseDatabaseSchemaEditor | ||||
|  | ||||
|  | ||||
| def migrate_authenticated_session_permissions(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): | ||||
|     """Migrate permissions from OldAuthenticatedSession to AuthenticatedSession""" | ||||
|     db_alias = schema_editor.connection.alias | ||||
|  | ||||
|     # `apps` here is just an instance of `django.db.migrations.state.AppConfigStub`, we need the | ||||
|     # real config for creating permissions and content types | ||||
|     authentik_core_config = global_apps.get_app_config("authentik_core") | ||||
|     # These are only ran by django after all migrations, but we need them right now. | ||||
|     # `global_apps` is needed, | ||||
|     create_permissions(authentik_core_config, using=db_alias, verbosity=1) | ||||
|     create_contenttypes(authentik_core_config, using=db_alias, verbosity=1) | ||||
|  | ||||
|     # But from now on, this is just a regular migration, so use `apps` | ||||
|     Permission = apps.get_model("auth", "Permission") | ||||
|     ContentType = apps.get_model("contenttypes", "ContentType") | ||||
|  | ||||
|     try: | ||||
|         old_ct = ContentType.objects.using(db_alias).get( | ||||
|             app_label="authentik_core", model="oldauthenticatedsession" | ||||
|         ) | ||||
|         new_ct = ContentType.objects.using(db_alias).get( | ||||
|             app_label="authentik_core", model="authenticatedsession" | ||||
|         ) | ||||
|     except ContentType.DoesNotExist: | ||||
|         # This should exist at this point, but if not, let's cut our losses | ||||
|         return | ||||
|  | ||||
|     # Get all permissions for the old content type | ||||
|     old_perms = Permission.objects.using(db_alias).filter(content_type=old_ct) | ||||
|  | ||||
|     # Create equivalent permissions for the new content type | ||||
|     for old_perm in old_perms: | ||||
|         new_perm = ( | ||||
|             Permission.objects.using(db_alias) | ||||
|             .filter( | ||||
|                 content_type=new_ct, | ||||
|                 codename=old_perm.codename, | ||||
|             ) | ||||
|             .first() | ||||
|         ) | ||||
|         if not new_perm: | ||||
|             # This should exist at this point, but if not, let's cut our losses | ||||
|             continue | ||||
|  | ||||
|         # Global user permissions | ||||
|         User = apps.get_model("authentik_core", "User") | ||||
|         User.user_permissions.through.objects.using(db_alias).filter( | ||||
|             permission=old_perm | ||||
|         ).all().update(permission=new_perm) | ||||
|  | ||||
|         # Global role permissions | ||||
|         DjangoGroup = apps.get_model("auth", "Group") | ||||
|         DjangoGroup.permissions.through.objects.using(db_alias).filter( | ||||
|             permission=old_perm | ||||
|         ).all().update(permission=new_perm) | ||||
|  | ||||
|         # Object user permissions | ||||
|         UserObjectPermission = apps.get_model("guardian", "UserObjectPermission") | ||||
|         UserObjectPermission.objects.using(db_alias).filter(permission=old_perm).all().update( | ||||
|             permission=new_perm, content_type=new_ct | ||||
|         ) | ||||
|  | ||||
|         # Object role permissions | ||||
|         GroupObjectPermission = apps.get_model("guardian", "GroupObjectPermission") | ||||
|         GroupObjectPermission.objects.using(db_alias).filter(permission=old_perm).all().update( | ||||
|             permission=new_perm, content_type=new_ct | ||||
|         ) | ||||
|  | ||||
|  | ||||
| def remove_old_authenticated_session_content_type( | ||||
|     apps: Apps, schema_editor: BaseDatabaseSchemaEditor | ||||
| ): | ||||
| @ -21,7 +92,12 @@ class Migration(migrations.Migration): | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.RunPython( | ||||
|             code=migrate_authenticated_session_permissions, | ||||
|             reverse_code=migrations.RunPython.noop, | ||||
|         ), | ||||
|         migrations.RunPython( | ||||
|             code=remove_old_authenticated_session_content_type, | ||||
|             reverse_code=migrations.RunPython.noop, | ||||
|         ), | ||||
|     ] | ||||
|  | ||||
| @ -0,0 +1,18 @@ | ||||
| # Generated by Django 5.1.9 on 2025-05-27 12:52 | ||||
|  | ||||
| from django.db import migrations, models | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("authentik_flows", "0027_auto_20231028_1424"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name="flowtoken", | ||||
|             name="revoke_on_execution", | ||||
|             field=models.BooleanField(default=True), | ||||
|         ), | ||||
|     ] | ||||
| @ -303,9 +303,10 @@ class FlowToken(Token): | ||||
|  | ||||
|     flow = models.ForeignKey(Flow, on_delete=models.CASCADE) | ||||
|     _plan = models.TextField() | ||||
|     revoke_on_execution = models.BooleanField(default=True) | ||||
|  | ||||
|     @staticmethod | ||||
|     def pickle(plan) -> str: | ||||
|     def pickle(plan: "FlowPlan") -> str: | ||||
|         """Pickle into string""" | ||||
|         data = dumps(plan) | ||||
|         return b64encode(data).decode() | ||||
|  | ||||
| @ -99,9 +99,10 @@ class ChallengeStageView(StageView): | ||||
|             self.logger.debug("Got StageInvalidException", exc=exc) | ||||
|             return self.executor.stage_invalid() | ||||
|         if not challenge.is_valid(): | ||||
|             self.logger.warning( | ||||
|             self.logger.error( | ||||
|                 "f(ch): Invalid challenge", | ||||
|                 errors=challenge.errors, | ||||
|                 challenge=challenge.data, | ||||
|             ) | ||||
|         return HttpChallengeResponse(challenge) | ||||
|  | ||||
|  | ||||
| @ -146,6 +146,7 @@ class FlowExecutorView(APIView): | ||||
|         except (AttributeError, EOFError, ImportError, IndexError) as exc: | ||||
|             LOGGER.warning("f(exec): Failed to restore token plan", exc=exc) | ||||
|         finally: | ||||
|             if token.revoke_on_execution: | ||||
|                 token.delete() | ||||
|         if not isinstance(plan, FlowPlan): | ||||
|             return None | ||||
|  | ||||
| @ -81,7 +81,6 @@ debugger: false | ||||
|  | ||||
| log_level: info | ||||
|  | ||||
| session_storage: cache | ||||
| sessions: | ||||
|   unauthenticated_age: days=1 | ||||
|  | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| from collections.abc import Callable | ||||
| from dataclasses import asdict | ||||
|  | ||||
| from celery import group | ||||
| from celery.exceptions import Retry | ||||
| from celery.result import allow_join_result | ||||
| from django.core.paginator import Paginator | ||||
| @ -82,21 +83,41 @@ class SyncTasks: | ||||
|                 self.logger.debug("Failed to acquire sync lock, skipping", provider=provider.name) | ||||
|                 return | ||||
|             try: | ||||
|                 for page in users_paginator.page_range: | ||||
|                     messages.append(_("Syncing page {page} of users".format(page=page))) | ||||
|                     for msg in sync_objects.apply_async( | ||||
|                 messages.append(_("Syncing users")) | ||||
|                 user_results = ( | ||||
|                     group( | ||||
|                         [ | ||||
|                             sync_objects.signature( | ||||
|                                 args=(class_to_path(User), page, provider_pk), | ||||
|                                 time_limit=PAGE_TIMEOUT, | ||||
|                                 soft_time_limit=PAGE_TIMEOUT, | ||||
|                     ).get(): | ||||
|                             ) | ||||
|                             for page in users_paginator.page_range | ||||
|                         ] | ||||
|                     ) | ||||
|                     .apply_async() | ||||
|                     .get() | ||||
|                 ) | ||||
|                 for result in user_results: | ||||
|                     for msg in result: | ||||
|                         messages.append(LogEvent(**msg)) | ||||
|                 for page in groups_paginator.page_range: | ||||
|                     messages.append(_("Syncing page {page} of groups".format(page=page))) | ||||
|                     for msg in sync_objects.apply_async( | ||||
|                 messages.append(_("Syncing groups")) | ||||
|                 group_results = ( | ||||
|                     group( | ||||
|                         [ | ||||
|                             sync_objects.signature( | ||||
|                                 args=(class_to_path(Group), page, provider_pk), | ||||
|                                 time_limit=PAGE_TIMEOUT, | ||||
|                                 soft_time_limit=PAGE_TIMEOUT, | ||||
|                     ).get(): | ||||
|                             ) | ||||
|                             for page in groups_paginator.page_range | ||||
|                         ] | ||||
|                     ) | ||||
|                     .apply_async() | ||||
|                     .get() | ||||
|                 ) | ||||
|                 for result in group_results: | ||||
|                     for msg in result: | ||||
|                         messages.append(LogEvent(**msg)) | ||||
|             except TransientSyncException as exc: | ||||
|                 self.logger.warning("transient sync exception", exc=exc) | ||||
| @ -109,7 +130,7 @@ class SyncTasks: | ||||
|     def sync_objects( | ||||
|         self, object_type: str, page: int, provider_pk: int, override_dry_run=False, **filter | ||||
|     ): | ||||
|         _object_type = path_to_class(object_type) | ||||
|         _object_type: type[Model] = path_to_class(object_type) | ||||
|         self.logger = get_logger().bind( | ||||
|             provider_type=class_to_path(self._provider_model), | ||||
|             provider_pk=provider_pk, | ||||
| @ -132,6 +153,19 @@ class SyncTasks: | ||||
|             self.logger.debug("starting discover") | ||||
|             client.discover() | ||||
|         self.logger.debug("starting sync for page", page=page) | ||||
|         messages.append( | ||||
|             asdict( | ||||
|                 LogEvent( | ||||
|                     _( | ||||
|                         "Syncing page {page} of {object_type}".format( | ||||
|                             page=page, object_type=_object_type._meta.verbose_name_plural | ||||
|                         ) | ||||
|                     ), | ||||
|                     log_level="info", | ||||
|                     logger=f"{provider._meta.verbose_name}@{object_type}", | ||||
|                 ) | ||||
|             ) | ||||
|         ) | ||||
|         for obj in paginator.page(page).object_list: | ||||
|             obj: Model | ||||
|             try: | ||||
|  | ||||
| @ -166,7 +166,6 @@ class ConnectionToken(ExpiringModel): | ||||
|         always_merger.merge(settings, default_settings) | ||||
|         always_merger.merge(settings, self.endpoint.provider.settings) | ||||
|         always_merger.merge(settings, self.endpoint.settings) | ||||
|         always_merger.merge(settings, self.settings) | ||||
|  | ||||
|         def mapping_evaluator(mappings: QuerySet): | ||||
|             for mapping in mappings: | ||||
| @ -191,6 +190,7 @@ class ConnectionToken(ExpiringModel): | ||||
|         mapping_evaluator( | ||||
|             RACPropertyMapping.objects.filter(endpoint__in=[self.endpoint]).order_by("name") | ||||
|         ) | ||||
|         always_merger.merge(settings, self.settings) | ||||
|  | ||||
|         settings["drive-path"] = f"/tmp/connection/{self.token}"  # nosec | ||||
|         settings["create-drive-path"] = "true" | ||||
|  | ||||
| @ -90,23 +90,6 @@ class TestModels(TransactionTestCase): | ||||
|                 "resize-method": "display-update", | ||||
|             }, | ||||
|         ) | ||||
|         # Set settings in token | ||||
|         token.settings = { | ||||
|             "level": "token", | ||||
|         } | ||||
|         token.save() | ||||
|         self.assertEqual( | ||||
|             token.get_settings(), | ||||
|             { | ||||
|                 "hostname": self.endpoint.host.split(":")[0], | ||||
|                 "port": "1324", | ||||
|                 "client-name": f"authentik - {self.user}", | ||||
|                 "drive-path": path, | ||||
|                 "create-drive-path": "true", | ||||
|                 "level": "token", | ||||
|                 "resize-method": "display-update", | ||||
|             }, | ||||
|         ) | ||||
|         # Set settings in property mapping (provider) | ||||
|         mapping = RACPropertyMapping.objects.create( | ||||
|             name=generate_id(), | ||||
| @ -151,3 +134,22 @@ class TestModels(TransactionTestCase): | ||||
|                 "resize-method": "display-update", | ||||
|             }, | ||||
|         ) | ||||
|         # Set settings in token | ||||
|         token.settings = { | ||||
|             "level": "token", | ||||
|         } | ||||
|         token.save() | ||||
|         self.assertEqual( | ||||
|             token.get_settings(), | ||||
|             { | ||||
|                 "hostname": self.endpoint.host.split(":")[0], | ||||
|                 "port": "1324", | ||||
|                 "client-name": f"authentik - {self.user}", | ||||
|                 "drive-path": path, | ||||
|                 "create-drive-path": "true", | ||||
|                 "foo": "true", | ||||
|                 "bar": "6", | ||||
|                 "resize-method": "display-update", | ||||
|                 "level": "token", | ||||
|             }, | ||||
|         ) | ||||
|  | ||||
| @ -47,15 +47,16 @@ class SCIMGroupClient(SCIMClient[Group, SCIMProviderGroup, SCIMGroupSchema]): | ||||
|  | ||||
|     def to_schema(self, obj: Group, connection: SCIMProviderGroup) -> SCIMGroupSchema: | ||||
|         """Convert authentik user into SCIM""" | ||||
|         raw_scim_group = super().to_schema( | ||||
|             obj, | ||||
|             connection, | ||||
|             schemas=(SCIM_GROUP_SCHEMA,), | ||||
|         ) | ||||
|         raw_scim_group = super().to_schema(obj, connection) | ||||
|         try: | ||||
|             scim_group = SCIMGroupSchema.model_validate(delete_none_values(raw_scim_group)) | ||||
|         except ValidationError as exc: | ||||
|             raise StopSync(exc, obj) from exc | ||||
|         if SCIM_GROUP_SCHEMA not in scim_group.schemas: | ||||
|             scim_group.schemas.insert(0, SCIM_GROUP_SCHEMA) | ||||
|         # As this might be unset, we need to tell pydantic it's set so ensure the schemas | ||||
|         # are included, even if its just the defaults | ||||
|         scim_group.schemas = list(scim_group.schemas) | ||||
|         if not scim_group.externalId: | ||||
|             scim_group.externalId = str(obj.pk) | ||||
|  | ||||
|  | ||||
| @ -31,15 +31,16 @@ class SCIMUserClient(SCIMClient[User, SCIMProviderUser, SCIMUserSchema]): | ||||
|  | ||||
|     def to_schema(self, obj: User, connection: SCIMProviderUser) -> SCIMUserSchema: | ||||
|         """Convert authentik user into SCIM""" | ||||
|         raw_scim_user = super().to_schema( | ||||
|             obj, | ||||
|             connection, | ||||
|             schemas=(SCIM_USER_SCHEMA,), | ||||
|         ) | ||||
|         raw_scim_user = super().to_schema(obj, connection) | ||||
|         try: | ||||
|             scim_user = SCIMUserSchema.model_validate(delete_none_values(raw_scim_user)) | ||||
|         except ValidationError as exc: | ||||
|             raise StopSync(exc, obj) from exc | ||||
|         if SCIM_USER_SCHEMA not in scim_user.schemas: | ||||
|             scim_user.schemas.insert(0, SCIM_USER_SCHEMA) | ||||
|         # As this might be unset, we need to tell pydantic it's set so ensure the schemas | ||||
|         # are included, even if its just the defaults | ||||
|         scim_user.schemas = list(scim_user.schemas) | ||||
|         if not scim_user.externalId: | ||||
|             scim_user.externalId = str(obj.uid) | ||||
|         return scim_user | ||||
|  | ||||
| @ -91,6 +91,57 @@ class SCIMUserTests(TestCase): | ||||
|             }, | ||||
|         ) | ||||
|  | ||||
|     @Mocker() | ||||
|     def test_user_create_custom_schema(self, mock: Mocker): | ||||
|         """Test user creation with custom schema""" | ||||
|         schema = SCIMMapping.objects.create( | ||||
|             name="custom_schema", | ||||
|             expression="""return {"schemas": ["foo"]}""", | ||||
|         ) | ||||
|         self.provider.property_mappings.add(schema) | ||||
|         scim_id = generate_id() | ||||
|         mock.get( | ||||
|             "https://localhost/ServiceProviderConfig", | ||||
|             json={}, | ||||
|         ) | ||||
|         mock.post( | ||||
|             "https://localhost/Users", | ||||
|             json={ | ||||
|                 "id": scim_id, | ||||
|             }, | ||||
|         ) | ||||
|         uid = generate_id() | ||||
|         user = User.objects.create( | ||||
|             username=uid, | ||||
|             name=f"{uid} {uid}", | ||||
|             email=f"{uid}@goauthentik.io", | ||||
|         ) | ||||
|         self.assertEqual(mock.call_count, 2) | ||||
|         self.assertEqual(mock.request_history[0].method, "GET") | ||||
|         self.assertEqual(mock.request_history[1].method, "POST") | ||||
|         self.assertJSONEqual( | ||||
|             mock.request_history[1].body, | ||||
|             { | ||||
|                 "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User", "foo"], | ||||
|                 "active": True, | ||||
|                 "emails": [ | ||||
|                     { | ||||
|                         "primary": True, | ||||
|                         "type": "other", | ||||
|                         "value": f"{uid}@goauthentik.io", | ||||
|                     } | ||||
|                 ], | ||||
|                 "externalId": user.uid, | ||||
|                 "name": { | ||||
|                     "familyName": uid, | ||||
|                     "formatted": f"{uid} {uid}", | ||||
|                     "givenName": uid, | ||||
|                 }, | ||||
|                 "displayName": f"{uid} {uid}", | ||||
|                 "userName": uid, | ||||
|             }, | ||||
|         ) | ||||
|  | ||||
|     @Mocker() | ||||
|     def test_user_create_different_provider_same_id(self, mock: Mocker): | ||||
|         """Test user creation with multiple providers that happen | ||||
| @ -384,7 +435,7 @@ class SCIMUserTests(TestCase): | ||||
|                 self.assertIn(request.method, SAFE_METHODS) | ||||
|         task = SystemTask.objects.filter(uid=slugify(self.provider.name)).first() | ||||
|         self.assertIsNotNone(task) | ||||
|         drop_msg = task.messages[2] | ||||
|         drop_msg = task.messages[3] | ||||
|         self.assertEqual(drop_msg["event"], "Dropping mutating request due to dry run") | ||||
|         self.assertIsNotNone(drop_msg["attributes"]["url"]) | ||||
|         self.assertIsNotNone(drop_msg["attributes"]["body"]) | ||||
|  | ||||
| @ -424,7 +424,7 @@ else: | ||||
|         "BACKEND": "authentik.root.storages.FileStorage", | ||||
|         "OPTIONS": { | ||||
|             "location": Path(CONFIG.get("storage.media.file.path")), | ||||
|             "base_url": "/media/", | ||||
|             "base_url": CONFIG.get("web.path", "/") + "media/", | ||||
|         }, | ||||
|     } | ||||
|     # Compatibility for apps not supporting top-level STORAGES | ||||
|  | ||||
| @ -31,6 +31,8 @@ class PytestTestRunner(DiscoverRunner):  # pragma: no cover | ||||
|  | ||||
|         if kwargs.get("randomly_seed", None): | ||||
|             self.args.append(f"--randomly-seed={kwargs['randomly_seed']}") | ||||
|         if kwargs.get("no_capture", False): | ||||
|             self.args.append("--capture=no") | ||||
|  | ||||
|         settings.TEST = True | ||||
|         settings.CELERY["task_always_eager"] = True | ||||
| @ -64,6 +66,11 @@ class PytestTestRunner(DiscoverRunner):  # pragma: no cover | ||||
|             "Default behaviour: use random.Random().getrandbits(32), so the seed is" | ||||
|             "different on each run.", | ||||
|         ) | ||||
|         parser.add_argument( | ||||
|             "--no-capture", | ||||
|             action="store_true", | ||||
|             help="Disable any capturing of stdout/stderr during tests.", | ||||
|         ) | ||||
|  | ||||
|     def run_tests(self, test_labels, extra_tests=None, **kwargs): | ||||
|         """Run pytest and return the exitcode. | ||||
|  | ||||
| @ -103,6 +103,7 @@ class LDAPSourceSerializer(SourceSerializer): | ||||
|             "user_object_filter", | ||||
|             "group_object_filter", | ||||
|             "group_membership_field", | ||||
|             "user_membership_attribute", | ||||
|             "object_uniqueness_field", | ||||
|             "password_login_update_internal_password", | ||||
|             "sync_users", | ||||
| @ -111,6 +112,7 @@ class LDAPSourceSerializer(SourceSerializer): | ||||
|             "sync_parent_group", | ||||
|             "connectivity", | ||||
|             "lookup_groups_from_user", | ||||
|             "delete_not_found_objects", | ||||
|         ] | ||||
|         extra_kwargs = {"bind_password": {"write_only": True}} | ||||
|  | ||||
| @ -138,6 +140,7 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet): | ||||
|         "user_object_filter", | ||||
|         "group_object_filter", | ||||
|         "group_membership_field", | ||||
|         "user_membership_attribute", | ||||
|         "object_uniqueness_field", | ||||
|         "password_login_update_internal_password", | ||||
|         "sync_users", | ||||
| @ -147,6 +150,7 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet): | ||||
|         "user_property_mappings", | ||||
|         "group_property_mappings", | ||||
|         "lookup_groups_from_user", | ||||
|         "delete_not_found_objects", | ||||
|     ] | ||||
|     search_fields = ["name", "slug"] | ||||
|     ordering = ["name"] | ||||
|  | ||||
| @ -0,0 +1,48 @@ | ||||
| # Generated by Django 5.1.9 on 2025-05-28 08:15 | ||||
|  | ||||
| from django.db import migrations, models | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("authentik_core", "0048_delete_oldauthenticatedsession_content_type"), | ||||
|         ("authentik_sources_ldap", "0008_groupldapsourceconnection_userldapsourceconnection"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name="groupldapsourceconnection", | ||||
|             name="validated_by", | ||||
|             field=models.UUIDField( | ||||
|                 blank=True, | ||||
|                 help_text="Unique ID used while checking if this object still exists in the directory.", | ||||
|                 null=True, | ||||
|             ), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name="ldapsource", | ||||
|             name="delete_not_found_objects", | ||||
|             field=models.BooleanField( | ||||
|                 default=False, | ||||
|                 help_text="Delete authentik users and groups which were previously supplied by this source, but are now missing from it.", | ||||
|             ), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name="userldapsourceconnection", | ||||
|             name="validated_by", | ||||
|             field=models.UUIDField( | ||||
|                 blank=True, | ||||
|                 help_text="Unique ID used while checking if this object still exists in the directory.", | ||||
|                 null=True, | ||||
|             ), | ||||
|         ), | ||||
|         migrations.AddIndex( | ||||
|             model_name="groupldapsourceconnection", | ||||
|             index=models.Index(fields=["validated_by"], name="authentik_s_validat_b70447_idx"), | ||||
|         ), | ||||
|         migrations.AddIndex( | ||||
|             model_name="userldapsourceconnection", | ||||
|             index=models.Index(fields=["validated_by"], name="authentik_s_validat_ff2ebc_idx"), | ||||
|         ), | ||||
|     ] | ||||
| @ -0,0 +1,32 @@ | ||||
| # Generated by Django 5.1.9 on 2025-05-29 11:22 | ||||
|  | ||||
| from django.apps.registry import Apps | ||||
| from django.db import migrations, models | ||||
| from django.db.backends.base.schema import BaseDatabaseSchemaEditor | ||||
|  | ||||
|  | ||||
| def set_user_membership_attribute(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): | ||||
|     LDAPSource = apps.get_model("authentik_sources_ldap", "LDAPSource") | ||||
|     db_alias = schema_editor.connection.alias | ||||
|  | ||||
|     LDAPSource.objects.using(db_alias).filter(group_membership_field="memberUid").all().update( | ||||
|         user_membership_attribute="ldap_uniq" | ||||
|     ) | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|     dependencies = [ | ||||
|         ("authentik_sources_ldap", "0009_groupldapsourceconnection_validated_by_and_more"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name="ldapsource", | ||||
|             name="user_membership_attribute", | ||||
|             field=models.TextField( | ||||
|                 default="distinguishedName", | ||||
|                 help_text="Attribute which matches the value of `group_membership_field`.", | ||||
|             ), | ||||
|         ), | ||||
|         migrations.RunPython(set_user_membership_attribute, migrations.RunPython.noop), | ||||
|     ] | ||||
| @ -100,6 +100,10 @@ class LDAPSource(Source): | ||||
|         default="(objectClass=person)", | ||||
|         help_text=_("Consider Objects matching this filter to be Users."), | ||||
|     ) | ||||
|     user_membership_attribute = models.TextField( | ||||
|         default=LDAP_DISTINGUISHED_NAME, | ||||
|         help_text=_("Attribute which matches the value of `group_membership_field`."), | ||||
|     ) | ||||
|     group_membership_field = models.TextField( | ||||
|         default="member", help_text=_("Field which contains members of a group.") | ||||
|     ) | ||||
| @ -137,6 +141,14 @@ class LDAPSource(Source): | ||||
|         ), | ||||
|     ) | ||||
|  | ||||
|     delete_not_found_objects = models.BooleanField( | ||||
|         default=False, | ||||
|         help_text=_( | ||||
|             "Delete authentik users and groups which were previously supplied by this source, " | ||||
|             "but are now missing from it." | ||||
|         ), | ||||
|     ) | ||||
|  | ||||
|     @property | ||||
|     def component(self) -> str: | ||||
|         return "ak-source-ldap-form" | ||||
| @ -321,6 +333,12 @@ class LDAPSourcePropertyMapping(PropertyMapping): | ||||
|  | ||||
|  | ||||
| class UserLDAPSourceConnection(UserSourceConnection): | ||||
|     validated_by = models.UUIDField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         help_text=_("Unique ID used while checking if this object still exists in the directory."), | ||||
|     ) | ||||
|  | ||||
|     @property | ||||
|     def serializer(self) -> type[Serializer]: | ||||
|         from authentik.sources.ldap.api import ( | ||||
| @ -332,9 +350,18 @@ class UserLDAPSourceConnection(UserSourceConnection): | ||||
|     class Meta: | ||||
|         verbose_name = _("User LDAP Source Connection") | ||||
|         verbose_name_plural = _("User LDAP Source Connections") | ||||
|         indexes = [ | ||||
|             models.Index(fields=["validated_by"]), | ||||
|         ] | ||||
|  | ||||
|  | ||||
| class GroupLDAPSourceConnection(GroupSourceConnection): | ||||
|     validated_by = models.UUIDField( | ||||
|         null=True, | ||||
|         blank=True, | ||||
|         help_text=_("Unique ID used while checking if this object still exists in the directory."), | ||||
|     ) | ||||
|  | ||||
|     @property | ||||
|     def serializer(self) -> type[Serializer]: | ||||
|         from authentik.sources.ldap.api import ( | ||||
| @ -346,3 +373,6 @@ class GroupLDAPSourceConnection(GroupSourceConnection): | ||||
|     class Meta: | ||||
|         verbose_name = _("Group LDAP Source Connection") | ||||
|         verbose_name_plural = _("Group LDAP Source Connections") | ||||
|         indexes = [ | ||||
|             models.Index(fields=["validated_by"]), | ||||
|         ] | ||||
|  | ||||
| @ -9,7 +9,7 @@ from structlog.stdlib import BoundLogger, get_logger | ||||
| from authentik.core.sources.mapper import SourceMapper | ||||
| from authentik.lib.config import CONFIG | ||||
| from authentik.lib.sync.mapper import PropertyMappingManager | ||||
| from authentik.sources.ldap.models import LDAPSource | ||||
| from authentik.sources.ldap.models import LDAPSource, flatten | ||||
|  | ||||
|  | ||||
| class BaseLDAPSynchronizer: | ||||
| @ -77,6 +77,16 @@ class BaseLDAPSynchronizer: | ||||
|         """Get objects from LDAP, implemented in subclass""" | ||||
|         raise NotImplementedError() | ||||
|  | ||||
|     def get_attributes(self, object): | ||||
|         if "attributes" not in object: | ||||
|             return | ||||
|         return object.get("attributes", {}) | ||||
|  | ||||
|     def get_identifier(self, attributes: dict): | ||||
|         if not attributes.get(self._source.object_uniqueness_field): | ||||
|             return | ||||
|         return flatten(attributes[self._source.object_uniqueness_field]) | ||||
|  | ||||
|     def search_paginator(  # noqa: PLR0913 | ||||
|         self, | ||||
|         search_base, | ||||
|  | ||||
							
								
								
									
										61
									
								
								authentik/sources/ldap/sync/forward_delete_groups.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								authentik/sources/ldap/sync/forward_delete_groups.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| from collections.abc import Generator | ||||
| from itertools import batched | ||||
| from uuid import uuid4 | ||||
|  | ||||
| from ldap3 import SUBTREE | ||||
|  | ||||
| from authentik.core.models import Group | ||||
| from authentik.sources.ldap.models import GroupLDAPSourceConnection | ||||
| from authentik.sources.ldap.sync.base import BaseLDAPSynchronizer | ||||
| from authentik.sources.ldap.sync.forward_delete_users import DELETE_CHUNK_SIZE, UPDATE_CHUNK_SIZE | ||||
|  | ||||
|  | ||||
| class GroupLDAPForwardDeletion(BaseLDAPSynchronizer): | ||||
|     """Delete LDAP Groups from authentik""" | ||||
|  | ||||
|     @staticmethod | ||||
|     def name() -> str: | ||||
|         return "group_deletions" | ||||
|  | ||||
|     def get_objects(self, **kwargs) -> Generator: | ||||
|         if not self._source.sync_groups or not self._source.delete_not_found_objects: | ||||
|             self.message("Group syncing is disabled for this Source") | ||||
|             return iter(()) | ||||
|  | ||||
|         uuid = uuid4() | ||||
|         groups = self._source.connection().extend.standard.paged_search( | ||||
|             search_base=self.base_dn_groups, | ||||
|             search_filter=self._source.group_object_filter, | ||||
|             search_scope=SUBTREE, | ||||
|             attributes=[self._source.object_uniqueness_field], | ||||
|             generator=True, | ||||
|             **kwargs, | ||||
|         ) | ||||
|         for batch in batched(groups, UPDATE_CHUNK_SIZE, strict=False): | ||||
|             identifiers = [] | ||||
|             for group in batch: | ||||
|                 if not (attributes := self.get_attributes(group)): | ||||
|                     continue | ||||
|                 if identifier := self.get_identifier(attributes): | ||||
|                     identifiers.append(identifier) | ||||
|             GroupLDAPSourceConnection.objects.filter(identifier__in=identifiers).update( | ||||
|                 validated_by=uuid | ||||
|             ) | ||||
|  | ||||
|         return batched( | ||||
|             GroupLDAPSourceConnection.objects.filter(source=self._source) | ||||
|             .exclude(validated_by=uuid) | ||||
|             .values_list("group", flat=True) | ||||
|             .iterator(chunk_size=DELETE_CHUNK_SIZE), | ||||
|             DELETE_CHUNK_SIZE, | ||||
|             strict=False, | ||||
|         ) | ||||
|  | ||||
|     def sync(self, group_pks: tuple) -> int: | ||||
|         """Delete authentik groups""" | ||||
|         if not self._source.sync_groups or not self._source.delete_not_found_objects: | ||||
|             self.message("Group syncing is disabled for this Source") | ||||
|             return -1 | ||||
|         self._logger.debug("Deleting groups", group_pks=group_pks) | ||||
|         _, deleted_per_type = Group.objects.filter(pk__in=group_pks).delete() | ||||
|         return deleted_per_type.get(Group._meta.label, 0) | ||||
							
								
								
									
										63
									
								
								authentik/sources/ldap/sync/forward_delete_users.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								authentik/sources/ldap/sync/forward_delete_users.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,63 @@ | ||||
| from collections.abc import Generator | ||||
| from itertools import batched | ||||
| from uuid import uuid4 | ||||
|  | ||||
| from ldap3 import SUBTREE | ||||
|  | ||||
| from authentik.core.models import User | ||||
| from authentik.sources.ldap.models import UserLDAPSourceConnection | ||||
| from authentik.sources.ldap.sync.base import BaseLDAPSynchronizer | ||||
|  | ||||
| UPDATE_CHUNK_SIZE = 10_000 | ||||
| DELETE_CHUNK_SIZE = 50 | ||||
|  | ||||
|  | ||||
| class UserLDAPForwardDeletion(BaseLDAPSynchronizer): | ||||
|     """Delete LDAP Users from authentik""" | ||||
|  | ||||
|     @staticmethod | ||||
|     def name() -> str: | ||||
|         return "user_deletions" | ||||
|  | ||||
|     def get_objects(self, **kwargs) -> Generator: | ||||
|         if not self._source.sync_users or not self._source.delete_not_found_objects: | ||||
|             self.message("User syncing is disabled for this Source") | ||||
|             return iter(()) | ||||
|  | ||||
|         uuid = uuid4() | ||||
|         users = self._source.connection().extend.standard.paged_search( | ||||
|             search_base=self.base_dn_users, | ||||
|             search_filter=self._source.user_object_filter, | ||||
|             search_scope=SUBTREE, | ||||
|             attributes=[self._source.object_uniqueness_field], | ||||
|             generator=True, | ||||
|             **kwargs, | ||||
|         ) | ||||
|         for batch in batched(users, UPDATE_CHUNK_SIZE, strict=False): | ||||
|             identifiers = [] | ||||
|             for user in batch: | ||||
|                 if not (attributes := self.get_attributes(user)): | ||||
|                     continue | ||||
|                 if identifier := self.get_identifier(attributes): | ||||
|                     identifiers.append(identifier) | ||||
|             UserLDAPSourceConnection.objects.filter(identifier__in=identifiers).update( | ||||
|                 validated_by=uuid | ||||
|             ) | ||||
|  | ||||
|         return batched( | ||||
|             UserLDAPSourceConnection.objects.filter(source=self._source) | ||||
|             .exclude(validated_by=uuid) | ||||
|             .values_list("user", flat=True) | ||||
|             .iterator(chunk_size=DELETE_CHUNK_SIZE), | ||||
|             DELETE_CHUNK_SIZE, | ||||
|             strict=False, | ||||
|         ) | ||||
|  | ||||
|     def sync(self, user_pks: tuple) -> int: | ||||
|         """Delete authentik users""" | ||||
|         if not self._source.sync_users or not self._source.delete_not_found_objects: | ||||
|             self.message("User syncing is disabled for this Source") | ||||
|             return -1 | ||||
|         self._logger.debug("Deleting users", user_pks=user_pks) | ||||
|         _, deleted_per_type = User.objects.filter(pk__in=user_pks).delete() | ||||
|         return deleted_per_type.get(User._meta.label, 0) | ||||
| @ -58,18 +58,16 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer): | ||||
|             return -1 | ||||
|         group_count = 0 | ||||
|         for group in page_data: | ||||
|             if "attributes" not in group: | ||||
|             if (attributes := self.get_attributes(group)) is None: | ||||
|                 continue | ||||
|             attributes = group.get("attributes", {}) | ||||
|             group_dn = flatten(flatten(group.get("entryDN", group.get("dn")))) | ||||
|             if not attributes.get(self._source.object_uniqueness_field): | ||||
|             if not (uniq := self.get_identifier(attributes)): | ||||
|                 self.message( | ||||
|                     f"Uniqueness field not found/not set in attributes: '{group_dn}'", | ||||
|                     attributes=attributes.keys(), | ||||
|                     dn=group_dn, | ||||
|                 ) | ||||
|                 continue | ||||
|             uniq = flatten(attributes[self._source.object_uniqueness_field]) | ||||
|             try: | ||||
|                 defaults = { | ||||
|                     k: flatten(v) | ||||
|  | ||||
| @ -63,25 +63,19 @@ class MembershipLDAPSynchronizer(BaseLDAPSynchronizer): | ||||
|                     group_member_dn = group_member.get("dn", {}) | ||||
|                     members.append(group_member_dn) | ||||
|             else: | ||||
|                 if "attributes" not in group: | ||||
|                 if (attributes := self.get_attributes(group)) is None: | ||||
|                     continue | ||||
|                 members = group.get("attributes", {}).get(self._source.group_membership_field, []) | ||||
|                 members = attributes.get(self._source.group_membership_field, []) | ||||
|  | ||||
|             ak_group = self.get_group(group) | ||||
|             if not ak_group: | ||||
|                 continue | ||||
|  | ||||
|             membership_mapping_attribute = LDAP_DISTINGUISHED_NAME | ||||
|             if self._source.group_membership_field == "memberUid": | ||||
|                 # If memberships are based on the posixGroup's 'memberUid' | ||||
|                 # attribute we use the RDN instead of the FDN to lookup members. | ||||
|                 membership_mapping_attribute = LDAP_UNIQUENESS | ||||
|  | ||||
|             users = User.objects.filter( | ||||
|                 Q(**{f"attributes__{membership_mapping_attribute}__in": members}) | ||||
|                 Q(**{f"attributes__{self._source.user_membership_attribute}__in": members}) | ||||
|                 | Q( | ||||
|                     **{ | ||||
|                         f"attributes__{membership_mapping_attribute}__isnull": True, | ||||
|                         f"attributes__{self._source.user_membership_attribute}__isnull": True, | ||||
|                         "ak_groups__in": [ak_group], | ||||
|                     } | ||||
|                 ) | ||||
|  | ||||
| @ -60,18 +60,16 @@ class UserLDAPSynchronizer(BaseLDAPSynchronizer): | ||||
|             return -1 | ||||
|         user_count = 0 | ||||
|         for user in page_data: | ||||
|             if "attributes" not in user: | ||||
|             if (attributes := self.get_attributes(user)) is None: | ||||
|                 continue | ||||
|             attributes = user.get("attributes", {}) | ||||
|             user_dn = flatten(user.get("entryDN", user.get("dn"))) | ||||
|             if not attributes.get(self._source.object_uniqueness_field): | ||||
|             if not (uniq := self.get_identifier(attributes)): | ||||
|                 self.message( | ||||
|                     f"Uniqueness field not found/not set in attributes: '{user_dn}'", | ||||
|                     attributes=attributes.keys(), | ||||
|                     dn=user_dn, | ||||
|                 ) | ||||
|                 continue | ||||
|             uniq = flatten(attributes[self._source.object_uniqueness_field]) | ||||
|             try: | ||||
|                 defaults = { | ||||
|                     k: flatten(v) | ||||
|  | ||||
| @ -17,6 +17,8 @@ from authentik.lib.utils.reflection import class_to_path, path_to_class | ||||
| from authentik.root.celery import CELERY_APP | ||||
| from authentik.sources.ldap.models import LDAPSource | ||||
| from authentik.sources.ldap.sync.base import BaseLDAPSynchronizer | ||||
| from authentik.sources.ldap.sync.forward_delete_groups import GroupLDAPForwardDeletion | ||||
| from authentik.sources.ldap.sync.forward_delete_users import UserLDAPForwardDeletion | ||||
| from authentik.sources.ldap.sync.groups import GroupLDAPSynchronizer | ||||
| from authentik.sources.ldap.sync.membership import MembershipLDAPSynchronizer | ||||
| from authentik.sources.ldap.sync.users import UserLDAPSynchronizer | ||||
| @ -52,11 +54,11 @@ def ldap_connectivity_check(pk: str | None = None): | ||||
|  | ||||
|  | ||||
| @CELERY_APP.task( | ||||
|     # We take the configured hours timeout time by 2.5 as we run user and | ||||
|     # group in parallel and then membership, so 2x is to cover the serial tasks, | ||||
|     # We take the configured hours timeout time by 3.5 as we run user and | ||||
|     # group in parallel and then membership, then deletions, so 3x is to cover the serial tasks, | ||||
|     # and 0.5x on top of that to give some more leeway | ||||
|     soft_time_limit=(60 * 60 * CONFIG.get_int("ldap.task_timeout_hours")) * 2.5, | ||||
|     task_time_limit=(60 * 60 * CONFIG.get_int("ldap.task_timeout_hours")) * 2.5, | ||||
|     soft_time_limit=(60 * 60 * CONFIG.get_int("ldap.task_timeout_hours")) * 3.5, | ||||
|     task_time_limit=(60 * 60 * CONFIG.get_int("ldap.task_timeout_hours")) * 3.5, | ||||
| ) | ||||
| def ldap_sync_single(source_pk: str): | ||||
|     """Sync a single source""" | ||||
| @ -79,6 +81,25 @@ def ldap_sync_single(source_pk: str): | ||||
|             group( | ||||
|                 ldap_sync_paginator(source, MembershipLDAPSynchronizer), | ||||
|             ), | ||||
|             # Finally, deletions. What we'd really like to do here is something like | ||||
|             # ``` | ||||
|             # user_identifiers = <ldap query> | ||||
|             # User.objects.exclude( | ||||
|             #     usersourceconnection__identifier__in=user_uniqueness_identifiers, | ||||
|             # ).delete() | ||||
|             # ``` | ||||
|             # This runs into performance issues in large installations. So instead we spread the | ||||
|             # work out into three steps: | ||||
|             # 1. Get every object from the LDAP source. | ||||
|             # 2. Mark every object as "safe" in the database. This is quick, but any error could | ||||
|             #    mean deleting users which should not be deleted, so we do it immediately, in | ||||
|             #    large chunks, and only queue the deletion step afterwards. | ||||
|             # 3. Delete every unmarked item. This is slow, so we spread it over many tasks in | ||||
|             #    small chunks. | ||||
|             group( | ||||
|                 ldap_sync_paginator(source, UserLDAPForwardDeletion) | ||||
|                 + ldap_sync_paginator(source, GroupLDAPForwardDeletion), | ||||
|             ), | ||||
|         ) | ||||
|         task() | ||||
|  | ||||
|  | ||||
| @ -2,6 +2,33 @@ | ||||
|  | ||||
| from ldap3 import MOCK_SYNC, OFFLINE_SLAPD_2_4, Connection, Server | ||||
|  | ||||
| # The mock modifies these in place, so we have to define them per string | ||||
| user_in_slapd_dn = "cn=user_in_slapd_cn,ou=users,dc=goauthentik,dc=io" | ||||
| user_in_slapd_cn = "user_in_slapd_cn" | ||||
| user_in_slapd_uid = "user_in_slapd_uid" | ||||
| user_in_slapd_object_class = "person" | ||||
| user_in_slapd = { | ||||
|     "dn": user_in_slapd_dn, | ||||
|     "attributes": { | ||||
|         "cn": user_in_slapd_cn, | ||||
|         "uid": user_in_slapd_uid, | ||||
|         "objectClass": user_in_slapd_object_class, | ||||
|     }, | ||||
| } | ||||
| group_in_slapd_dn = "cn=user_in_slapd_cn,ou=groups,dc=goauthentik,dc=io" | ||||
| group_in_slapd_cn = "group_in_slapd_cn" | ||||
| group_in_slapd_uid = "group_in_slapd_uid" | ||||
| group_in_slapd_object_class = "groupOfNames" | ||||
| group_in_slapd = { | ||||
|     "dn": group_in_slapd_dn, | ||||
|     "attributes": { | ||||
|         "cn": group_in_slapd_cn, | ||||
|         "uid": group_in_slapd_uid, | ||||
|         "objectClass": group_in_slapd_object_class, | ||||
|         "member": [user_in_slapd["dn"]], | ||||
|     }, | ||||
| } | ||||
|  | ||||
|  | ||||
| def mock_slapd_connection(password: str) -> Connection: | ||||
|     """Create mock SLAPD connection""" | ||||
| @ -96,5 +123,14 @@ def mock_slapd_connection(password: str) -> Connection: | ||||
|             "objectClass": "posixAccount", | ||||
|         }, | ||||
|     ) | ||||
|     # Known user and group | ||||
|     connection.strategy.add_entry( | ||||
|         user_in_slapd["dn"], | ||||
|         user_in_slapd["attributes"], | ||||
|     ) | ||||
|     connection.strategy.add_entry( | ||||
|         group_in_slapd["dn"], | ||||
|         group_in_slapd["attributes"], | ||||
|     ) | ||||
|     connection.bind() | ||||
|     return connection | ||||
|  | ||||
| @ -13,14 +13,26 @@ from authentik.events.system_tasks import TaskStatus | ||||
| from authentik.lib.generators import generate_id, generate_key | ||||
| from authentik.lib.sync.outgoing.exceptions import StopSync | ||||
| from authentik.lib.utils.reflection import class_to_path | ||||
| from authentik.sources.ldap.models import LDAPSource, LDAPSourcePropertyMapping | ||||
| from authentik.sources.ldap.models import ( | ||||
|     GroupLDAPSourceConnection, | ||||
|     LDAPSource, | ||||
|     LDAPSourcePropertyMapping, | ||||
|     UserLDAPSourceConnection, | ||||
| ) | ||||
| from authentik.sources.ldap.sync.forward_delete_users import DELETE_CHUNK_SIZE | ||||
| from authentik.sources.ldap.sync.groups import GroupLDAPSynchronizer | ||||
| from authentik.sources.ldap.sync.membership import MembershipLDAPSynchronizer | ||||
| from authentik.sources.ldap.sync.users import UserLDAPSynchronizer | ||||
| from authentik.sources.ldap.tasks import ldap_sync, ldap_sync_all | ||||
| from authentik.sources.ldap.tests.mock_ad import mock_ad_connection | ||||
| from authentik.sources.ldap.tests.mock_freeipa import mock_freeipa_connection | ||||
| from authentik.sources.ldap.tests.mock_slapd import mock_slapd_connection | ||||
| from authentik.sources.ldap.tests.mock_slapd import ( | ||||
|     group_in_slapd_cn, | ||||
|     group_in_slapd_uid, | ||||
|     mock_slapd_connection, | ||||
|     user_in_slapd_cn, | ||||
|     user_in_slapd_uid, | ||||
| ) | ||||
|  | ||||
| LDAP_PASSWORD = generate_key() | ||||
|  | ||||
| @ -257,11 +269,55 @@ class LDAPSyncTests(TestCase): | ||||
|         self.source.group_membership_field = "memberUid" | ||||
|         self.source.user_object_filter = "(objectClass=posixAccount)" | ||||
|         self.source.group_object_filter = "(objectClass=posixGroup)" | ||||
|         self.source.user_membership_attribute = "uid" | ||||
|         self.source.user_property_mappings.set( | ||||
|             LDAPSourcePropertyMapping.objects.filter( | ||||
|             [ | ||||
|                 *LDAPSourcePropertyMapping.objects.filter( | ||||
|                     Q(managed__startswith="goauthentik.io/sources/ldap/default") | ||||
|                     | Q(managed__startswith="goauthentik.io/sources/ldap/openldap") | ||||
|                 ).all(), | ||||
|                 LDAPSourcePropertyMapping.objects.create( | ||||
|                     name="name", | ||||
|                     expression='return {"attributes": {"uid": list_flatten(ldap.get("uid"))}}', | ||||
|                 ), | ||||
|             ] | ||||
|         ) | ||||
|         self.source.group_property_mappings.set( | ||||
|             LDAPSourcePropertyMapping.objects.filter( | ||||
|                 managed="goauthentik.io/sources/ldap/openldap-cn" | ||||
|             ) | ||||
|         ) | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             self.source.save() | ||||
|             user_sync = UserLDAPSynchronizer(self.source) | ||||
|             user_sync.sync_full() | ||||
|             group_sync = GroupLDAPSynchronizer(self.source) | ||||
|             group_sync.sync_full() | ||||
|             membership_sync = MembershipLDAPSynchronizer(self.source) | ||||
|             membership_sync.sync_full() | ||||
|             # Test if membership mapping based on memberUid works. | ||||
|             posix_group = Group.objects.filter(name="group-posix").first() | ||||
|             self.assertTrue(posix_group.users.filter(name="user-posix").exists()) | ||||
|  | ||||
|     def test_sync_groups_openldap_posix_group_nonstandard_membership_attribute(self): | ||||
|         """Test posix group sync""" | ||||
|         self.source.object_uniqueness_field = "cn" | ||||
|         self.source.group_membership_field = "memberUid" | ||||
|         self.source.user_object_filter = "(objectClass=posixAccount)" | ||||
|         self.source.group_object_filter = "(objectClass=posixGroup)" | ||||
|         self.source.user_membership_attribute = "cn" | ||||
|         self.source.user_property_mappings.set( | ||||
|             [ | ||||
|                 *LDAPSourcePropertyMapping.objects.filter( | ||||
|                     Q(managed__startswith="goauthentik.io/sources/ldap/default") | ||||
|                     | Q(managed__startswith="goauthentik.io/sources/ldap/openldap") | ||||
|                 ).all(), | ||||
|                 LDAPSourcePropertyMapping.objects.create( | ||||
|                     name="name", | ||||
|                     expression='return {"attributes": {"cn": list_flatten(ldap.get("cn"))}}', | ||||
|                 ), | ||||
|             ] | ||||
|         ) | ||||
|         self.source.group_property_mappings.set( | ||||
|             LDAPSourcePropertyMapping.objects.filter( | ||||
| @ -308,3 +364,160 @@ class LDAPSyncTests(TestCase): | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|  | ||||
|     def test_user_deletion(self): | ||||
|         """Test user deletion""" | ||||
|         user = User.objects.create_user(username="not-in-the-source") | ||||
|         UserLDAPSourceConnection.objects.create( | ||||
|             user=user, source=self.source, identifier="not-in-the-source" | ||||
|         ) | ||||
|         self.source.object_uniqueness_field = "uid" | ||||
|         self.source.group_object_filter = "(objectClass=groupOfNames)" | ||||
|         self.source.delete_not_found_objects = True | ||||
|         self.source.save() | ||||
|  | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|         self.assertFalse(User.objects.filter(username="not-in-the-source").exists()) | ||||
|  | ||||
|     def test_user_deletion_still_in_source(self): | ||||
|         """Test that user is not deleted if it's still in the source""" | ||||
|         username = user_in_slapd_cn | ||||
|         identifier = user_in_slapd_uid | ||||
|         user = User.objects.create_user(username=username) | ||||
|         UserLDAPSourceConnection.objects.create( | ||||
|             user=user, source=self.source, identifier=identifier | ||||
|         ) | ||||
|         self.source.object_uniqueness_field = "uid" | ||||
|         self.source.group_object_filter = "(objectClass=groupOfNames)" | ||||
|         self.source.delete_not_found_objects = True | ||||
|         self.source.save() | ||||
|  | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|         self.assertTrue(User.objects.filter(username=username).exists()) | ||||
|  | ||||
|     def test_user_deletion_no_sync(self): | ||||
|         """Test that user is not deleted if sync_users is False""" | ||||
|         user = User.objects.create_user(username="not-in-the-source") | ||||
|         UserLDAPSourceConnection.objects.create( | ||||
|             user=user, source=self.source, identifier="not-in-the-source" | ||||
|         ) | ||||
|         self.source.object_uniqueness_field = "uid" | ||||
|         self.source.group_object_filter = "(objectClass=groupOfNames)" | ||||
|         self.source.delete_not_found_objects = True | ||||
|         self.source.sync_users = False | ||||
|         self.source.save() | ||||
|  | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|         self.assertTrue(User.objects.filter(username="not-in-the-source").exists()) | ||||
|  | ||||
|     def test_user_deletion_no_delete(self): | ||||
|         """Test that user is not deleted if delete_not_found_objects is False""" | ||||
|         user = User.objects.create_user(username="not-in-the-source") | ||||
|         UserLDAPSourceConnection.objects.create( | ||||
|             user=user, source=self.source, identifier="not-in-the-source" | ||||
|         ) | ||||
|         self.source.object_uniqueness_field = "uid" | ||||
|         self.source.group_object_filter = "(objectClass=groupOfNames)" | ||||
|         self.source.save() | ||||
|  | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|         self.assertTrue(User.objects.filter(username="not-in-the-source").exists()) | ||||
|  | ||||
|     def test_group_deletion(self): | ||||
|         """Test group deletion""" | ||||
|         group = Group.objects.create(name="not-in-the-source") | ||||
|         GroupLDAPSourceConnection.objects.create( | ||||
|             group=group, source=self.source, identifier="not-in-the-source" | ||||
|         ) | ||||
|         self.source.object_uniqueness_field = "uid" | ||||
|         self.source.group_object_filter = "(objectClass=groupOfNames)" | ||||
|         self.source.delete_not_found_objects = True | ||||
|         self.source.save() | ||||
|  | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|         self.assertFalse(Group.objects.filter(name="not-in-the-source").exists()) | ||||
|  | ||||
|     def test_group_deletion_still_in_source(self): | ||||
|         """Test that group is not deleted if it's still in the source""" | ||||
|         groupname = group_in_slapd_cn | ||||
|         identifier = group_in_slapd_uid | ||||
|         group = Group.objects.create(name=groupname) | ||||
|         GroupLDAPSourceConnection.objects.create( | ||||
|             group=group, source=self.source, identifier=identifier | ||||
|         ) | ||||
|         self.source.object_uniqueness_field = "uid" | ||||
|         self.source.group_object_filter = "(objectClass=groupOfNames)" | ||||
|         self.source.delete_not_found_objects = True | ||||
|         self.source.save() | ||||
|  | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|         self.assertTrue(Group.objects.filter(name=groupname).exists()) | ||||
|  | ||||
|     def test_group_deletion_no_sync(self): | ||||
|         """Test that group is not deleted if sync_groups is False""" | ||||
|         group = Group.objects.create(name="not-in-the-source") | ||||
|         GroupLDAPSourceConnection.objects.create( | ||||
|             group=group, source=self.source, identifier="not-in-the-source" | ||||
|         ) | ||||
|         self.source.object_uniqueness_field = "uid" | ||||
|         self.source.group_object_filter = "(objectClass=groupOfNames)" | ||||
|         self.source.delete_not_found_objects = True | ||||
|         self.source.sync_groups = False | ||||
|         self.source.save() | ||||
|  | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|         self.assertTrue(Group.objects.filter(name="not-in-the-source").exists()) | ||||
|  | ||||
|     def test_group_deletion_no_delete(self): | ||||
|         """Test that group is not deleted if delete_not_found_objects is False""" | ||||
|         group = Group.objects.create(name="not-in-the-source") | ||||
|         GroupLDAPSourceConnection.objects.create( | ||||
|             group=group, source=self.source, identifier="not-in-the-source" | ||||
|         ) | ||||
|         self.source.object_uniqueness_field = "uid" | ||||
|         self.source.group_object_filter = "(objectClass=groupOfNames)" | ||||
|         self.source.save() | ||||
|  | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|         self.assertTrue(Group.objects.filter(name="not-in-the-source").exists()) | ||||
|  | ||||
|     def test_batch_deletion(self): | ||||
|         """Test batch deletion""" | ||||
|         BATCH_SIZE = DELETE_CHUNK_SIZE + 1 | ||||
|         for i in range(BATCH_SIZE): | ||||
|             user = User.objects.create_user(username=f"not-in-the-source-{i}") | ||||
|             group = Group.objects.create(name=f"not-in-the-source-{i}") | ||||
|             group.users.add(user) | ||||
|             UserLDAPSourceConnection.objects.create( | ||||
|                 user=user, source=self.source, identifier=f"not-in-the-source-{i}-user" | ||||
|             ) | ||||
|             GroupLDAPSourceConnection.objects.create( | ||||
|                 group=group, source=self.source, identifier=f"not-in-the-source-{i}-group" | ||||
|             ) | ||||
|         self.source.object_uniqueness_field = "uid" | ||||
|         self.source.group_object_filter = "(objectClass=groupOfNames)" | ||||
|         self.source.delete_not_found_objects = True | ||||
|         self.source.save() | ||||
|  | ||||
|         connection = MagicMock(return_value=mock_slapd_connection(LDAP_PASSWORD)) | ||||
|         with patch("authentik.sources.ldap.models.LDAPSource.connection", connection): | ||||
|             ldap_sync_all.delay().get() | ||||
|  | ||||
|         self.assertFalse(User.objects.filter(username__startswith="not-in-the-source").exists()) | ||||
|         self.assertFalse(Group.objects.filter(name__startswith="not-in-the-source").exists()) | ||||
|  | ||||
| @ -9,6 +9,7 @@ from django.http.response import HttpResponseBadRequest | ||||
| from django.shortcuts import get_object_or_404, redirect | ||||
| from django.utils.decorators import method_decorator | ||||
| from django.utils.http import urlencode | ||||
| from django.utils.translation import gettext as _ | ||||
| from django.views import View | ||||
| from django.views.decorators.csrf import csrf_exempt | ||||
| from structlog.stdlib import get_logger | ||||
| @ -128,7 +129,9 @@ class InitiateView(View): | ||||
|         # otherwise we default to POST_AUTO, with direct redirect | ||||
|         if source.binding_type == SAMLBindingTypes.POST: | ||||
|             injected_stages.append(in_memory_stage(ConsentStageView)) | ||||
|             plan_kwargs[PLAN_CONTEXT_CONSENT_HEADER] = f"Continue to {source.name}" | ||||
|             plan_kwargs[PLAN_CONTEXT_CONSENT_HEADER] = _( | ||||
|                 "Continue to {source_name}".format(source_name=source.name) | ||||
|             ) | ||||
|         injected_stages.append(in_memory_stage(AutosubmitStageView)) | ||||
|         return self.handle_login_flow( | ||||
|             source, | ||||
|  | ||||
| @ -151,9 +151,7 @@ class AuthenticatorValidateStageWebAuthnTests(FlowTestCase): | ||||
|             webauthn_user_verification=UserVerification.PREFERRED, | ||||
|         ) | ||||
|         stage.webauthn_allowed_device_types.set( | ||||
|             WebAuthnDeviceType.objects.filter( | ||||
|                 description="Android Authenticator with SafetyNet Attestation" | ||||
|             ) | ||||
|             WebAuthnDeviceType.objects.filter(description="YubiKey 5 Series") | ||||
|         ) | ||||
|         session = self.client.session | ||||
|         plan = FlowPlan(flow_pk=flow.pk.hex) | ||||
| @ -339,9 +337,7 @@ class AuthenticatorValidateStageWebAuthnTests(FlowTestCase): | ||||
|             device_classes=[DeviceClasses.WEBAUTHN], | ||||
|         ) | ||||
|         stage.webauthn_allowed_device_types.set( | ||||
|             WebAuthnDeviceType.objects.filter( | ||||
|                 description="Android Authenticator with SafetyNet Attestation" | ||||
|             ) | ||||
|             WebAuthnDeviceType.objects.filter(description="YubiKey 5 Series") | ||||
|         ) | ||||
|         session = self.client.session | ||||
|         plan = FlowPlan(flow_pk=flow.pk.hex) | ||||
|  | ||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -141,9 +141,7 @@ class TestAuthenticatorWebAuthnStage(FlowTestCase): | ||||
|         """Test registration with restricted devices (fail)""" | ||||
|         webauthn_mds_import.delay(force=True).get() | ||||
|         self.stage.device_type_restrictions.set( | ||||
|             WebAuthnDeviceType.objects.filter( | ||||
|                 description="Android Authenticator with SafetyNet Attestation" | ||||
|             ) | ||||
|             WebAuthnDeviceType.objects.filter(description="YubiKey 5 Series") | ||||
|         ) | ||||
|  | ||||
|         plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()]) | ||||
|  | ||||
| @ -4,6 +4,8 @@ from uuid import uuid4 | ||||
|  | ||||
| from django.http import HttpRequest, HttpResponse | ||||
| from django.utils.timezone import now | ||||
| from django.utils.translation import gettext as _ | ||||
| from rest_framework.exceptions import ValidationError | ||||
| from rest_framework.fields import CharField | ||||
|  | ||||
| from authentik.core.api.utils import PassiveSerializer | ||||
| @ -47,6 +49,11 @@ class ConsentChallengeResponse(ChallengeResponse): | ||||
|     component = CharField(default="ak-stage-consent") | ||||
|     token = CharField(required=True) | ||||
|  | ||||
|     def validate_token(self, token: str): | ||||
|         if token != self.stage.executor.request.session[SESSION_KEY_CONSENT_TOKEN]: | ||||
|             raise ValidationError(_("Invalid consent token, re-showing prompt")) | ||||
|         return token | ||||
|  | ||||
|  | ||||
| class ConsentStageView(ChallengeStageView): | ||||
|     """Simple consent checker.""" | ||||
| @ -120,9 +127,6 @@ class ConsentStageView(ChallengeStageView): | ||||
|         return super().get(request, *args, **kwargs) | ||||
|  | ||||
|     def challenge_valid(self, response: ChallengeResponse) -> HttpResponse: | ||||
|         if response.data["token"] != self.request.session[SESSION_KEY_CONSENT_TOKEN]: | ||||
|             self.logger.info("Invalid consent token, re-showing prompt") | ||||
|             return self.get(self.request) | ||||
|         if self.should_always_prompt(): | ||||
|             return self.executor.stage_ok() | ||||
|         current_stage: ConsentStage = self.executor.current_stage | ||||
|  | ||||
| @ -17,6 +17,7 @@ from authentik.flows.views.executor import SESSION_KEY_PLAN | ||||
| from authentik.lib.generators import generate_id | ||||
| from authentik.stages.consent.models import ConsentMode, ConsentStage, UserConsent | ||||
| from authentik.stages.consent.stage import ( | ||||
|     PLAN_CONTEXT_CONSENT_HEADER, | ||||
|     PLAN_CONTEXT_CONSENT_PERMISSIONS, | ||||
|     SESSION_KEY_CONSENT_TOKEN, | ||||
| ) | ||||
| @ -33,6 +34,40 @@ class TestConsentStage(FlowTestCase): | ||||
|             slug=generate_id(), | ||||
|         ) | ||||
|  | ||||
|     def test_mismatched_token(self): | ||||
|         """Test incorrect token""" | ||||
|         flow = create_test_flow(FlowDesignation.AUTHENTICATION) | ||||
|         stage = ConsentStage.objects.create(name=generate_id(), mode=ConsentMode.ALWAYS_REQUIRE) | ||||
|         binding = FlowStageBinding.objects.create(target=flow, stage=stage, order=2) | ||||
|  | ||||
|         plan = FlowPlan(flow_pk=flow.pk.hex, bindings=[binding], markers=[StageMarker()]) | ||||
|         session = self.client.session | ||||
|         session[SESSION_KEY_PLAN] = plan | ||||
|         session.save() | ||||
|         response = self.client.get( | ||||
|             reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), | ||||
|         ) | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|  | ||||
|         session = self.client.session | ||||
|         response = self.client.post( | ||||
|             reverse("authentik_api:flow-executor", kwargs={"flow_slug": flow.slug}), | ||||
|             { | ||||
|                 "token": generate_id(), | ||||
|             }, | ||||
|         ) | ||||
|  | ||||
|         self.assertEqual(response.status_code, 200) | ||||
|         self.assertStageResponse( | ||||
|             response, | ||||
|             flow, | ||||
|             component="ak-stage-consent", | ||||
|             response_errors={ | ||||
|                 "token": [{"string": "Invalid consent token, re-showing prompt", "code": "invalid"}] | ||||
|             }, | ||||
|         ) | ||||
|         self.assertFalse(UserConsent.objects.filter(user=self.user).exists()) | ||||
|  | ||||
|     def test_always_required(self): | ||||
|         """Test always required consent""" | ||||
|         flow = create_test_flow(FlowDesignation.AUTHENTICATION) | ||||
| @ -158,6 +193,7 @@ class TestConsentStage(FlowTestCase): | ||||
|             context={ | ||||
|                 PLAN_CONTEXT_APPLICATION: self.application, | ||||
|                 PLAN_CONTEXT_CONSENT_PERMISSIONS: [PermissionDict(id="foo", name="foo-desc")], | ||||
|                 PLAN_CONTEXT_CONSENT_HEADER: "test header", | ||||
|             }, | ||||
|         ) | ||||
|         session = self.client.session | ||||
|  | ||||
							
								
								
									
										38
									
								
								authentik/stages/email/flow.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								authentik/stages/email/flow.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| from base64 import b64encode | ||||
| from copy import deepcopy | ||||
| from pickle import dumps  # nosec | ||||
|  | ||||
| from django.utils.translation import gettext as _ | ||||
|  | ||||
| from authentik.flows.models import FlowToken, in_memory_stage | ||||
| from authentik.flows.planner import PLAN_CONTEXT_IS_RESTORED, FlowPlan | ||||
| from authentik.stages.consent.stage import PLAN_CONTEXT_CONSENT_HEADER, ConsentStageView | ||||
|  | ||||
|  | ||||
| def pickle_flow_token_for_email(plan: FlowPlan): | ||||
|     """Insert a consent stage into the flow plan and pickle it for a FlowToken, | ||||
|     to be sent via Email. This is to prevent automated email scanners, which sometimes | ||||
|     open links in emails in a full browser from breaking the link.""" | ||||
|     plan_copy = deepcopy(plan) | ||||
|     plan_copy.insert_stage(in_memory_stage(EmailTokenRevocationConsentStageView), index=0) | ||||
|     plan_copy.context[PLAN_CONTEXT_CONSENT_HEADER] = _("Continue to confirm this email address.") | ||||
|     data = dumps(plan_copy) | ||||
|     return b64encode(data).decode() | ||||
|  | ||||
|  | ||||
| class EmailTokenRevocationConsentStageView(ConsentStageView): | ||||
|  | ||||
|     def get(self, request, *args, **kwargs): | ||||
|         token: FlowToken = self.executor.plan.context[PLAN_CONTEXT_IS_RESTORED] | ||||
|         try: | ||||
|             token.refresh_from_db() | ||||
|         except FlowToken.DoesNotExist: | ||||
|             return self.executor.stage_invalid( | ||||
|                 _("Link was already used, please request a new link.") | ||||
|             ) | ||||
|         return super().get(request, *args, **kwargs) | ||||
|  | ||||
|     def challenge_valid(self, response): | ||||
|         token: FlowToken = self.executor.plan.context[PLAN_CONTEXT_IS_RESTORED] | ||||
|         token.delete() | ||||
|         return super().challenge_valid(response) | ||||
| @ -23,6 +23,7 @@ from authentik.flows.stage import ChallengeStageView | ||||
| from authentik.flows.views.executor import QS_KEY_TOKEN, QS_QUERY | ||||
| from authentik.lib.utils.errors import exception_to_string | ||||
| from authentik.lib.utils.time import timedelta_from_string | ||||
| from authentik.stages.email.flow import pickle_flow_token_for_email | ||||
| from authentik.stages.email.models import EmailStage | ||||
| from authentik.stages.email.tasks import send_mails | ||||
| from authentik.stages.email.utils import TemplateEmailMessage | ||||
| @ -86,7 +87,8 @@ class EmailStageView(ChallengeStageView): | ||||
|                 user=pending_user, | ||||
|                 identifier=identifier, | ||||
|                 flow=self.executor.flow, | ||||
|                 _plan=FlowToken.pickle(self.executor.plan), | ||||
|                 _plan=pickle_flow_token_for_email(self.executor.plan), | ||||
|                 revoke_on_execution=False, | ||||
|             ) | ||||
|         token = tokens.first() | ||||
|         # Check if token is expired and rotate key if so | ||||
|  | ||||
| @ -174,5 +174,5 @@ class TestEmailStageSending(FlowTestCase): | ||||
|                 response = self.client.post(url) | ||||
|             response = self.client.post(url) | ||||
|             self.assertEqual(response.status_code, 200) | ||||
|             self.assertTrue(len(mail.outbox) >= 1) | ||||
|             self.assertGreaterEqual(len(mail.outbox), 1) | ||||
|             self.assertEqual(mail.outbox[0].subject, "authentik") | ||||
|  | ||||
| @ -17,6 +17,7 @@ from authentik.flows.tests import FlowTestCase | ||||
| from authentik.flows.views.executor import QS_KEY_TOKEN, SESSION_KEY_PLAN, FlowExecutorView | ||||
| from authentik.lib.config import CONFIG | ||||
| from authentik.lib.generators import generate_id | ||||
| from authentik.stages.consent.stage import SESSION_KEY_CONSENT_TOKEN | ||||
| from authentik.stages.email.models import EmailStage | ||||
| from authentik.stages.email.stage import PLAN_CONTEXT_EMAIL_OVERRIDE, EmailStageView | ||||
|  | ||||
| @ -160,6 +161,17 @@ class TestEmailStage(FlowTestCase): | ||||
|                     kwargs={"flow_slug": self.flow.slug}, | ||||
|                 ) | ||||
|             ) | ||||
|             self.assertStageResponse(response, self.flow, component="ak-stage-consent") | ||||
|             response = self.client.post( | ||||
|                 reverse( | ||||
|                     "authentik_api:flow-executor", | ||||
|                     kwargs={"flow_slug": self.flow.slug}, | ||||
|                 ), | ||||
|                 data={ | ||||
|                     "token": self.client.session[SESSION_KEY_CONSENT_TOKEN], | ||||
|                 }, | ||||
|                 follow=True, | ||||
|             ) | ||||
|  | ||||
|             self.assertEqual(response.status_code, 200) | ||||
|             self.assertStageRedirects(response, reverse("authentik_core:root-redirect")) | ||||
| @ -182,6 +194,7 @@ class TestEmailStage(FlowTestCase): | ||||
|         # Set flow token user to a different user | ||||
|         token: FlowToken = FlowToken.objects.get(user=self.user) | ||||
|         token.user = create_test_admin_user() | ||||
|         token.revoke_on_execution = True | ||||
|         token.save() | ||||
|  | ||||
|         with patch("authentik.flows.views.executor.FlowExecutorView.cancel", MagicMock()): | ||||
|  | ||||
| @ -11,7 +11,7 @@ from rest_framework.fields import BooleanField, CharField | ||||
| from authentik.core.models import Session, User | ||||
| from authentik.events.middleware import audit_ignore | ||||
| from authentik.flows.challenge import ChallengeResponse, WithUserInfoChallenge | ||||
| from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, PLAN_CONTEXT_SOURCE | ||||
| from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER | ||||
| from authentik.flows.stage import ChallengeStageView | ||||
| from authentik.lib.utils.time import timedelta_from_string | ||||
| from authentik.root.middleware import ClientIPMiddleware | ||||
| @ -108,10 +108,6 @@ class UserLoginStageView(ChallengeStageView): | ||||
|             flow_slug=self.executor.flow.slug, | ||||
|             session_duration=delta, | ||||
|         ) | ||||
|         # Only show success message if we don't have a source in the flow | ||||
|         # as sources show their own success messages | ||||
|         if not self.executor.plan.context.get(PLAN_CONTEXT_SOURCE, None): | ||||
|             messages.success(self.request, _("Successfully logged in!")) | ||||
|         if self.executor.current_stage.terminate_other_sessions: | ||||
|             Session.objects.filter( | ||||
|                 authenticatedsession__user=user, | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
|     "$schema": "http://json-schema.org/draft-07/schema", | ||||
|     "$id": "https://goauthentik.io/blueprints/schema.json", | ||||
|     "type": "object", | ||||
|     "title": "authentik 2025.4.1 Blueprint schema", | ||||
|     "title": "authentik 2025.6.0 Blueprint schema", | ||||
|     "required": [ | ||||
|         "version", | ||||
|         "entries" | ||||
| @ -8147,6 +8147,12 @@ | ||||
|                     "title": "Group membership field", | ||||
|                     "description": "Field which contains members of a group." | ||||
|                 }, | ||||
|                 "user_membership_attribute": { | ||||
|                     "type": "string", | ||||
|                     "minLength": 1, | ||||
|                     "title": "User membership attribute", | ||||
|                     "description": "Attribute which matches the value of `group_membership_field`." | ||||
|                 }, | ||||
|                 "object_uniqueness_field": { | ||||
|                     "type": "string", | ||||
|                     "minLength": 1, | ||||
| @ -8180,6 +8186,11 @@ | ||||
|                     "type": "boolean", | ||||
|                     "title": "Lookup groups from user", | ||||
|                     "description": "Lookup group membership based on a user attribute instead of a group attribute. This allows nested group resolution on systems like FreeIPA and Active Directory" | ||||
|                 }, | ||||
|                 "delete_not_found_objects": { | ||||
|                     "type": "boolean", | ||||
|                     "title": "Delete not found objects", | ||||
|                     "description": "Delete authentik users and groups which were previously supplied by this source, but are now missing from it." | ||||
|                 } | ||||
|             }, | ||||
|             "required": [] | ||||
|  | ||||
| @ -31,7 +31,7 @@ services: | ||||
|     volumes: | ||||
|       - redis:/data | ||||
|   server: | ||||
|     image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.1} | ||||
|     image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.0} | ||||
|     restart: unless-stopped | ||||
|     command: server | ||||
|     environment: | ||||
| @ -55,7 +55,7 @@ services: | ||||
|       redis: | ||||
|         condition: service_healthy | ||||
|   worker: | ||||
|     image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.4.1} | ||||
|     image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.0} | ||||
|     restart: unless-stopped | ||||
|     command: worker | ||||
|     environment: | ||||
|  | ||||
							
								
								
									
										4
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.mod
									
									
									
									
									
								
							| @ -21,13 +21,13 @@ require ( | ||||
| 	github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484 | ||||
| 	github.com/pires/go-proxyproto v0.8.1 | ||||
| 	github.com/prometheus/client_golang v1.22.0 | ||||
| 	github.com/redis/go-redis/v9 v9.8.0 | ||||
| 	github.com/redis/go-redis/v9 v9.9.0 | ||||
| 	github.com/sethvargo/go-envconfig v1.3.0 | ||||
| 	github.com/sirupsen/logrus v1.9.3 | ||||
| 	github.com/spf13/cobra v1.9.1 | ||||
| 	github.com/stretchr/testify v1.10.0 | ||||
| 	github.com/wwt/guac v1.3.2 | ||||
| 	goauthentik.io/api/v3 v3.2025041.2 | ||||
| 	goauthentik.io/api/v3 v3.2025041.4 | ||||
| 	golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab | ||||
| 	golang.org/x/oauth2 v0.30.0 | ||||
| 	golang.org/x/sync v0.14.0 | ||||
|  | ||||
							
								
								
									
										8
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								go.sum
									
									
									
									
									
								
							| @ -245,8 +245,8 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ | ||||
| github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= | ||||
| github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= | ||||
| github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= | ||||
| github.com/redis/go-redis/v9 v9.8.0 h1:q3nRvjrlge/6UD7eTu/DSg2uYiU2mCL0G/uzBWqhicI= | ||||
| github.com/redis/go-redis/v9 v9.8.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= | ||||
| github.com/redis/go-redis/v9 v9.9.0 h1:URbPQ4xVQSQhZ27WMQVmZSo3uT3pL+4IdHVcYq2nVfM= | ||||
| github.com/redis/go-redis/v9 v9.9.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= | ||||
| github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= | ||||
| github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= | ||||
| github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= | ||||
| @ -290,8 +290,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y | ||||
| go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= | ||||
| go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= | ||||
| go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= | ||||
| goauthentik.io/api/v3 v3.2025041.2 h1:vFYYnhcDcxL95RczZwhzt3i4LptFXMvIRN+vgf8sQYg= | ||||
| goauthentik.io/api/v3 v3.2025041.2/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw= | ||||
| goauthentik.io/api/v3 v3.2025041.4 h1:cGqzWYnUHrWDoaXWDpIL/kWnX9sFrIhkYDye0P0OEAo= | ||||
| goauthentik.io/api/v3 v3.2025041.4/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
| golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||||
|  | ||||
| @ -33,4 +33,4 @@ func UserAgent() string { | ||||
| 	return fmt.Sprintf("authentik@%s", FullVersion()) | ||||
| } | ||||
|  | ||||
| const VERSION = "2025.4.1" | ||||
| const VERSION = "2025.6.0" | ||||
|  | ||||
| @ -28,16 +28,18 @@ func NewSessionBinder(si server.LDAPServerInstance, oldBinder bind.Binder) *Sess | ||||
| 		si:  si, | ||||
| 		log: log.WithField("logger", "authentik.outpost.ldap.binder.session"), | ||||
| 	} | ||||
| 	if oldBinder != nil { | ||||
| 		if oldSb, ok := oldBinder.(*SessionBinder); ok { | ||||
| 			sb.DirectBinder = oldSb.DirectBinder | ||||
| 			sb.sessions = oldSb.sessions | ||||
| 			sb.log.Debug("re-initialised session binder") | ||||
| 	} else { | ||||
| 			return sb | ||||
| 		} | ||||
| 	} | ||||
| 	sb.sessions = ttlcache.New(ttlcache.WithDisableTouchOnHit[Credentials, ldap.LDAPResultCode]()) | ||||
| 	sb.DirectBinder = *direct.NewDirectBinder(si) | ||||
| 	go sb.sessions.Start() | ||||
| 	sb.log.Debug("initialised session binder") | ||||
| 	} | ||||
| 	return sb | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -16,6 +16,7 @@ import ( | ||||
| 	memorybind "goauthentik.io/internal/outpost/ldap/bind/memory" | ||||
| 	"goauthentik.io/internal/outpost/ldap/constants" | ||||
| 	"goauthentik.io/internal/outpost/ldap/flags" | ||||
| 	"goauthentik.io/internal/outpost/ldap/search" | ||||
| 	directsearch "goauthentik.io/internal/outpost/ldap/search/direct" | ||||
| 	memorysearch "goauthentik.io/internal/outpost/ldap/search/memory" | ||||
| ) | ||||
| @ -85,7 +86,11 @@ func (ls *LDAPServer) Refresh() error { | ||||
| 			providers[idx].certUUID = *kp | ||||
| 		} | ||||
| 		if *provider.SearchMode.Ptr() == api.LDAPAPIACCESSMODE_CACHED { | ||||
| 			providers[idx].searcher = memorysearch.NewMemorySearcher(providers[idx]) | ||||
| 			var oldSearcher search.Searcher | ||||
| 			if existing != nil { | ||||
| 				oldSearcher = existing.searcher | ||||
| 			} | ||||
| 			providers[idx].searcher = memorysearch.NewMemorySearcher(providers[idx], oldSearcher) | ||||
| 		} else if *provider.SearchMode.Ptr() == api.LDAPAPIACCESSMODE_DIRECT { | ||||
| 			providers[idx].searcher = directsearch.NewDirectSearcher(providers[idx]) | ||||
| 		} | ||||
|  | ||||
| @ -31,13 +31,26 @@ type MemorySearcher struct { | ||||
| 	groups []api.Group | ||||
| } | ||||
|  | ||||
| func NewMemorySearcher(si server.LDAPServerInstance) *MemorySearcher { | ||||
| func NewMemorySearcher(si server.LDAPServerInstance, existing search.Searcher) *MemorySearcher { | ||||
| 	ms := &MemorySearcher{ | ||||
| 		si:  si, | ||||
| 		log: log.WithField("logger", "authentik.outpost.ldap.searcher.memory"), | ||||
| 		ds:  direct.NewDirectSearcher(si), | ||||
| 	} | ||||
| 	if existing != nil { | ||||
| 		if ems, ok := existing.(*MemorySearcher); ok { | ||||
| 			ems.si = si | ||||
| 			ems.fetch() | ||||
| 			ems.log.Debug("re-initialised memory searcher") | ||||
| 			return ems | ||||
| 		} | ||||
| 	} | ||||
| 	ms.fetch() | ||||
| 	ms.log.Debug("initialised memory searcher") | ||||
| 	return ms | ||||
| } | ||||
|  | ||||
| func (ms *MemorySearcher) fetch() { | ||||
| 	// Error is not handled here, we get an empty/truncated list and the error is logged | ||||
| 	users, _ := ak.Paginator(ms.si.GetAPIClient().CoreApi.CoreUsersList(context.TODO()).IncludeGroups(true), ak.PaginatorOptions{ | ||||
| 		PageSize: 100, | ||||
| @ -49,7 +62,6 @@ func NewMemorySearcher(si server.LDAPServerInstance) *MemorySearcher { | ||||
| 		Logger:   ms.log, | ||||
| 	}) | ||||
| 	ms.groups = groups | ||||
| 	return ms | ||||
| } | ||||
|  | ||||
| func (ms *MemorySearcher) SearchBase(req *search.Request) (ldap.ServerSearchResult, error) { | ||||
|  | ||||
| @ -67,11 +67,15 @@ func (ws *WebServer) configureStatic() { | ||||
|  | ||||
| 	// Media files, if backend is file | ||||
| 	if config.Get().Storage.Media.Backend == "file" { | ||||
| 		fsMedia := http.StripPrefix("/media", http.FileServer(http.Dir(config.Get().Storage.Media.File.Path))) | ||||
| 		indexLessRouter.PathPrefix(config.Get().Web.Path).PathPrefix("/media/").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 		fsMedia := http.FileServer(http.Dir(config.Get().Storage.Media.File.Path)) | ||||
| 		indexLessRouter.PathPrefix(config.Get().Web.Path).PathPrefix("/media/").Handler(pathStripper( | ||||
| 			http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||||
| 				w.Header().Set("Content-Security-Policy", "default-src 'none'; style-src 'unsafe-inline'; sandbox") | ||||
| 				fsMedia.ServeHTTP(w, r) | ||||
| 		}) | ||||
| 			}), | ||||
| 			"media/", | ||||
| 			config.Get().Web.Path, | ||||
| 		)) | ||||
| 	} | ||||
|  | ||||
| 	staticRouter.PathPrefix(config.Get().Web.Path).PathPrefix("/if/help/").Handler(pathStripper( | ||||
|  | ||||
							
								
								
									
										8
									
								
								lifecycle/aws/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										8
									
								
								lifecycle/aws/package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -9,7 +9,7 @@ | ||||
|             "version": "0.0.0", | ||||
|             "license": "MIT", | ||||
|             "devDependencies": { | ||||
|                 "aws-cdk": "^2.1016.1", | ||||
|                 "aws-cdk": "^2.1017.1", | ||||
|                 "cross-env": "^7.0.3" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -17,9 +17,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/aws-cdk": { | ||||
|             "version": "2.1016.1", | ||||
|             "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1016.1.tgz", | ||||
|             "integrity": "sha512-248TBiluT8jHUjkpzvWJOHv2fS+An9fiII3eji8H7jwfTu5yMBk7on4B/AVNr9A1GXJk9I32qf9Q0A3rLWRYPQ==", | ||||
|             "version": "2.1017.1", | ||||
|             "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1017.1.tgz", | ||||
|             "integrity": "sha512-KtDdkMhfVjDeexjpMrVoSlz2mTYI5BE/KotvJ7iFbZy1G0nkpW1ImZ54TdBefeeFmZ+8DAjU3I6nUFtymyOI1A==", | ||||
|             "dev": true, | ||||
|             "license": "Apache-2.0", | ||||
|             "bin": { | ||||
|  | ||||
| @ -10,7 +10,7 @@ | ||||
|         "node": ">=20" | ||||
|     }, | ||||
|     "devDependencies": { | ||||
|         "aws-cdk": "^2.1016.1", | ||||
|         "aws-cdk": "^2.1017.1", | ||||
|         "cross-env": "^7.0.3" | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -26,7 +26,7 @@ Parameters: | ||||
|     Description: authentik Docker image | ||||
|   AuthentikVersion: | ||||
|     Type: String | ||||
|     Default: 2025.4.1 | ||||
|     Default: 2025.6.0 | ||||
|     Description: authentik Docker image tag | ||||
|   AuthentikServerCPU: | ||||
|     Type: Number | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -32,15 +32,17 @@ | ||||
| # datenschmutz, 2025 | ||||
| # 97cce0ae0cad2a2cc552d3165d04643e_de3d740, 2025 | ||||
| # Dominic Wagner <mail@dominic-wagner.de>, 2025 | ||||
| # Till-Frederik Riechard, 2025 | ||||
| # Alexander Mnich, 2025 | ||||
| #  | ||||
| #, fuzzy | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Dominic Wagner <mail@dominic-wagner.de>, 2025\n" | ||||
| "Last-Translator: Alexander Mnich, 2025\n" | ||||
| "Language-Team: German (https://app.transifex.com/authentik/teams/119923/de/)\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| @ -132,6 +134,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Vom Authentik-Core-Webserver verwendetes Zertifikat." | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "Marke" | ||||
| @ -405,7 +411,7 @@ msgstr "Eigenschaften" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "session data" | ||||
| msgstr "" | ||||
| msgstr "Sitzungsdaten" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Session" | ||||
| @ -533,7 +539,7 @@ msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "Number of passwords to check against." | ||||
| msgstr "" | ||||
| msgstr "Anzahl Passwörter, gegen die geprüft wird." | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| #: authentik/policies/password/models.py | ||||
| @ -543,18 +549,20 @@ msgstr "Passwort nicht im Kontext festgelegt" | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "This password has been used previously. Please choose a different one." | ||||
| msgstr "" | ||||
| "Dieses Passwort wurde in Vergangenheit bereits verwendet. Bitte nutzen Sie " | ||||
| "ein anderes." | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "Password Uniqueness Policy" | ||||
| msgstr "" | ||||
| msgstr "Passwort-Einzigartigkeits-Richtlinie" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "Password Uniqueness Policies" | ||||
| msgstr "" | ||||
| msgstr "Passwort-Einzigartigkeits-Richtlinien" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "User Password History" | ||||
| msgstr "" | ||||
| msgstr "Nutzer-Passwort-Historie" | ||||
|  | ||||
| #: authentik/enterprise/policy.py | ||||
| msgid "Enterprise required to access this feature." | ||||
| @ -693,6 +701,33 @@ msgstr "Endgeräte" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "Verifiziere deinen Browser..." | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -988,7 +1023,7 @@ msgstr "" | ||||
|  | ||||
| #: authentik/flows/models.py | ||||
| msgid "Evaluate policies when the Stage is presented to the user." | ||||
| msgstr "" | ||||
| msgstr "Richtlinien auswerten, wenn die Phase dem Benutzer angezeigt wird." | ||||
|  | ||||
| #: authentik/flows/models.py | ||||
| msgid "" | ||||
| @ -1043,9 +1078,12 @@ msgid "Starting full provider sync" | ||||
| msgstr "Starte komplette Provider Synchronisation." | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgstr "Synchonisiere Benutzer Seite {page}" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| @ -1593,11 +1631,11 @@ msgstr "ES256 (Asymmetrische Verschlüsselung)" | ||||
|  | ||||
| #: authentik/providers/oauth2/models.py | ||||
| msgid "ES384 (Asymmetric Encryption)" | ||||
| msgstr "" | ||||
| msgstr "ES384 (Asymmetrische Verschlüsselung)" | ||||
|  | ||||
| #: authentik/providers/oauth2/models.py | ||||
| msgid "ES512 (Asymmetric Encryption)" | ||||
| msgstr "" | ||||
| msgstr "ES5122 (Asymmetrische Verschlüsselung)" | ||||
|  | ||||
| #: authentik/providers/oauth2/models.py | ||||
| msgid "Scope used by the client" | ||||
| @ -2183,11 +2221,11 @@ msgstr "Standard" | ||||
|  | ||||
| #: authentik/providers/scim/models.py | ||||
| msgid "AWS" | ||||
| msgstr "" | ||||
| msgstr "AWS" | ||||
|  | ||||
| #: authentik/providers/scim/models.py | ||||
| msgid "Slack" | ||||
| msgstr "" | ||||
| msgstr "Slack" | ||||
|  | ||||
| #: authentik/providers/scim/models.py | ||||
| msgid "Base URL to SCIM requests, usually ends in /v2" | ||||
| @ -2199,7 +2237,7 @@ msgstr "Authentifizierungstoken" | ||||
|  | ||||
| #: authentik/providers/scim/models.py | ||||
| msgid "SCIM Compatibility Mode" | ||||
| msgstr "" | ||||
| msgstr "SCIM Kompatibilitätsmodus" | ||||
|  | ||||
| #: authentik/providers/scim/models.py | ||||
| msgid "Alter authentik behavior for vendor-specific SCIM implementations." | ||||
| @ -2231,7 +2269,7 @@ msgstr "Rollen" | ||||
|  | ||||
| #: authentik/rbac/models.py | ||||
| msgid "Initial Permissions" | ||||
| msgstr "" | ||||
| msgstr "Initiale Berechtigungen" | ||||
|  | ||||
| #: authentik/rbac/models.py | ||||
| msgid "System permission" | ||||
| @ -2487,6 +2525,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "LDAP Quelle" | ||||
| @ -2504,20 +2548,25 @@ msgid "LDAP Source Property Mappings" | ||||
| msgstr "LDAP Quelle Eigenschafts-Zuordnungen" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "Benutzer LDAP-Quellverbindung" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connections" | ||||
| msgstr "" | ||||
| msgstr "Benutzer LDAP-Quellverbindungen" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "Group LDAP Source Connection" | ||||
| msgstr "" | ||||
| msgstr "LDAP Gruppen Quellverbindung" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "Group LDAP Source Connections" | ||||
| msgstr "" | ||||
| msgstr "LDAP Gruppen Quellverbindungen" | ||||
|  | ||||
| #: authentik/sources/ldap/signals.py | ||||
| msgid "Password does not match Active Directory Complexity." | ||||
| @ -2530,7 +2579,7 @@ msgstr "Kein Token empfangen." | ||||
|  | ||||
| #: authentik/sources/oauth/models.py | ||||
| msgid "HTTP Basic Authentication" | ||||
| msgstr "" | ||||
| msgstr "HTTP Basic Authentifizierung" | ||||
|  | ||||
| #: authentik/sources/oauth/models.py | ||||
| msgid "Include the client ID and secret as request parameters" | ||||
| @ -2896,6 +2945,11 @@ msgstr "SAML Gruppen Quellverbindung" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "SAML Gruppen Quellverbindungen" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "SCIM Quelle" | ||||
| @ -2930,7 +2984,7 @@ msgstr "Duo Geräte" | ||||
|  | ||||
| #: authentik/stages/authenticator_email/models.py | ||||
| msgid "Email OTP" | ||||
| msgstr "" | ||||
| msgstr "E-Mail Einmalpasswort" | ||||
|  | ||||
| #: authentik/stages/authenticator_email/models.py | ||||
| #: authentik/stages/email/models.py | ||||
| @ -2963,11 +3017,11 @@ msgstr "Beim Rendern der E-Mail-Vorlage ist ein Fehler aufgetreten" | ||||
|  | ||||
| #: authentik/stages/authenticator_email/models.py | ||||
| msgid "Email Device" | ||||
| msgstr "" | ||||
| msgstr "E-Mail Gerät" | ||||
|  | ||||
| #: authentik/stages/authenticator_email/models.py | ||||
| msgid "Email Devices" | ||||
| msgstr "" | ||||
| msgstr "E-Mail Geräte" | ||||
|  | ||||
| #: authentik/stages/authenticator_email/stage.py | ||||
| #: authentik/stages/authenticator_sms/stage.py | ||||
| @ -2977,7 +3031,7 @@ msgstr "Code stimmt nicht überein" | ||||
|  | ||||
| #: authentik/stages/authenticator_email/stage.py | ||||
| msgid "Invalid email" | ||||
| msgstr "" | ||||
| msgstr "Ungültige E-Mail" | ||||
|  | ||||
| #: authentik/stages/authenticator_email/templates/email/email_otp.html | ||||
| #: authentik/stages/email/templates/email/password_reset.html | ||||
| @ -3273,6 +3327,10 @@ msgstr "Zustimmung der Benutzer" | ||||
| msgid "User Consents" | ||||
| msgstr "Zustimmungen der Benutzer" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Verweigerungsstufe" | ||||
| @ -3289,6 +3347,14 @@ msgstr "Dummy Stufe" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Dummy Stufen" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Passwort zurücksetzen" | ||||
| @ -3890,10 +3956,11 @@ msgstr "" | ||||
| #: authentik/tenants/models.py | ||||
| msgid "Reputation cannot decrease lower than this value. Zero or negative." | ||||
| msgstr "" | ||||
| "Reputation kann nicht niedriger als dieser Wert sein. Null oder negativ." | ||||
|  | ||||
| #: authentik/tenants/models.py | ||||
| msgid "Reputation cannot increase higher than this value. Zero or positive." | ||||
| msgstr "" | ||||
| msgstr "Reputation kann nicht höher als dieser Wert sein. Null oder positiv." | ||||
|  | ||||
| #: authentik/tenants/models.py | ||||
| msgid "The option configures the footer links on the flow executor pages." | ||||
|  | ||||
| @ -8,7 +8,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-05-20 00:10+0000\n" | ||||
| "POT-Creation-Date: 2025-06-04 00:12+0000\n" | ||||
| "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | ||||
| "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | ||||
| "Language-Team: LANGUAGE <LL@li.org>\n" | ||||
| @ -961,13 +961,16 @@ msgid "Starting full provider sync" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of groups" | ||||
| msgid "Syncing page {page} of {object_type}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| @ -2223,6 +2226,10 @@ msgstr "" | ||||
| msgid "Consider Objects matching this filter to be Users." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "Attribute which matches the value of `group_membership_field`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "Field which contains members of a group." | ||||
| msgstr "" | ||||
| @ -2252,6 +2259,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "" | ||||
| @ -2268,6 +2281,11 @@ msgstr "" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "" | ||||
| @ -2639,6 +2657,11 @@ msgstr "" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "" | ||||
| @ -2994,6 +3017,10 @@ msgstr "" | ||||
| msgid "User Consents" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "" | ||||
| @ -3010,6 +3037,14 @@ msgstr "" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "" | ||||
| @ -3462,10 +3497,6 @@ msgstr "" | ||||
| msgid "No Pending user to login." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/user_login/stage.py | ||||
| msgid "Successfully logged in!" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/user_logout/models.py | ||||
| msgid "User Logout Stage" | ||||
| msgstr "" | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -15,7 +15,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Jens L. <jens@goauthentik.io>, 2025\n" | ||||
| "Language-Team: Spanish (https://app.transifex.com/authentik/teams/119923/es/)\n" | ||||
| @ -109,6 +109,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Certificado Web usado por el servidor web Core de authentik" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "Marca" | ||||
| @ -671,6 +675,33 @@ msgstr "Dispositivos de Punto de Conexión" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "Verificando tu navegador..." | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -1009,9 +1040,12 @@ msgid "Starting full provider sync" | ||||
| msgstr "Iniciando sincronización completa de proveedor" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgstr "Sincronizando página {page} de usuarios" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| @ -2452,6 +2486,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "Fuente de LDAP" | ||||
| @ -2468,6 +2508,11 @@ msgstr "Asignación de Propiedades de Fuente de LDAP" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "Asignaciones de Propiedades de Fuente de LDAP" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "" | ||||
| @ -2859,6 +2904,11 @@ msgstr "Conexión de Fuente de SAML de Grupo" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "Conexiones de Fuente de SAML de Grupo" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "Fuente de SCIM" | ||||
| @ -3245,6 +3295,10 @@ msgstr "Consentimiento del usuario" | ||||
| msgid "User Consents" | ||||
| msgstr "Consentimientos del usuario" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Etapa de denegación" | ||||
| @ -3261,6 +3315,14 @@ msgstr "Escenario ficticio" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Etapas ficticias" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Restablecimiento de contraseña" | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -15,7 +15,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Ville Ranki, 2025\n" | ||||
| "Language-Team: Finnish (https://app.transifex.com/authentik/teams/119923/fi/)\n" | ||||
| @ -106,6 +106,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Web-sertifikaatti, jota authentik Core -verkkopalvelin käyttää." | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "Brändi" | ||||
| @ -658,6 +662,33 @@ msgstr "Päätelaitteet" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "Selaintasi varmennetaan..." | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -996,9 +1027,12 @@ msgid "Starting full provider sync" | ||||
| msgstr "Käynnistetään palveluntarjoajan täysi synkronisointi" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgstr "Synkronoidaan käyttäjien sivua {page}" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| @ -2429,6 +2463,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "LDAP-lähde" | ||||
| @ -2445,6 +2485,11 @@ msgstr "LDAP-lähteen ominaisuuskytkentä" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "LDAP-lähteen ominaisuuskytkennät" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "" | ||||
| @ -2837,6 +2882,11 @@ msgstr "Ryhmän SAML-lähteen yhteys" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "Ryhmän SAML-lähteen yhteydet" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "SCIM-lähde" | ||||
| @ -3216,6 +3266,10 @@ msgstr "Käyttäjän hyväksyntä" | ||||
| msgid "User Consents" | ||||
| msgstr "Käyttäjän hyväksynnät" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Kieltovaihe" | ||||
| @ -3232,6 +3286,14 @@ msgstr "Valevaihe" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Valevaiheet" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Salasanan nollaus" | ||||
|  | ||||
| @ -19,7 +19,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-05-20 00:10+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Marc Schmitt, 2025\n" | ||||
| "Language-Team: French (https://app.transifex.com/authentik/teams/119923/fr/)\n" | ||||
| @ -1056,9 +1056,12 @@ msgid "Starting full provider sync" | ||||
| msgstr "Démarrage d'une synchronisation complète du fournisseur" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgstr "Synchronisation de la page {page} d'utilisateurs" | ||||
| msgid "Syncing users" | ||||
| msgstr "Synchronisation des utilisateurs" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "Synchronisation des groupes" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| @ -2508,6 +2511,14 @@ msgstr "" | ||||
| "plutôt que sur un attribut de groupe. Cela permet la résolution des groupes " | ||||
| "imbriqués sur des systèmes tels que FreeIPA et Active Directory." | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
| "Supprimer les utilisateurs et les groupes authentik qui étaient auparavant " | ||||
| "fournis par cette source, mais qui en sont maintenant absents." | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "Source LDAP" | ||||
| @ -2524,6 +2535,13 @@ msgstr "Mappage de propriété source LDAP" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "Mappages de propriété source LDAP" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
| "ID unique utilisé pour vérifier si cet objet existe toujours dans le " | ||||
| "répertoire." | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "Connexion de l'utilisateur à la source LDAP" | ||||
| @ -2918,6 +2936,11 @@ msgstr "Connexion du groupe à la source SAML" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "Connexions du groupe à la source SAML" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "Continuer vers {source_name}" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "Source SCIM" | ||||
| @ -3308,6 +3331,10 @@ msgstr "Consentement Utilisateur" | ||||
| msgid "User Consents" | ||||
| msgstr "Consentements Utilisateur" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "Jeton de consentement invalide, réaffichage de l'invite" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Étape de Refus" | ||||
| @ -3324,6 +3351,14 @@ msgstr "Étape factice" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Étapes factices" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "Continuer pour confirmer cette adresse courriel." | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "Ce lien a déjà été utilisé, veuillez en demander un nouveau." | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Réinitialiser le Mot de Passe" | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -20,7 +20,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025\n" | ||||
| "Language-Team: Italian (https://app.transifex.com/authentik/teams/119923/it/)\n" | ||||
| @ -114,6 +114,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Certificato Web utilizzato dal server Web authentik Core." | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "Brand" | ||||
| @ -672,6 +676,33 @@ msgstr "Dispositivi di Accesso" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "Verifica del tuo browser..." | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -1018,9 +1049,12 @@ msgid "Starting full provider sync" | ||||
| msgstr "Avvio della sincronizzazione completa del provider" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgstr "Sincronizzando pagina {page} degli utenti" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| @ -2463,6 +2497,12 @@ msgstr "" | ||||
| "attributo di gruppo. Questo consente la risoluzione di gruppi nidificati su " | ||||
| "sistemi come FreeIPA e Active Directory." | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "Sorgente LDAP" | ||||
| @ -2479,6 +2519,11 @@ msgstr "Mappatura delle proprietà sorgente LDAP" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "Mappature delle proprietà della sorgente LDAP" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "Connessione Sorgente LDAP Utente" | ||||
| @ -2872,6 +2917,11 @@ msgstr "Connessione sorgente SAML di gruppo" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "Connessioni sorgente SAML di gruppo" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "Sorgente SCIM" | ||||
| @ -3269,6 +3319,10 @@ msgstr "Consenso utente" | ||||
| msgid "User Consents" | ||||
| msgstr "Consensi utente" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Fase di negazione" | ||||
| @ -3285,6 +3339,14 @@ msgstr "Fase fittizia" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Fasi fittizie" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Ripristino password" | ||||
|  | ||||
| @ -12,7 +12,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: NavyStack, 2023\n" | ||||
| "Language-Team: Korean (https://app.transifex.com/authentik/teams/119923/ko/)\n" | ||||
| @ -99,6 +99,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Authentik Core 웹서버에서 사용하는 웹 인증서." | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "" | ||||
| @ -625,6 +629,33 @@ msgstr "" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -946,8 +977,11 @@ msgid "Starting full provider sync" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| @ -2263,6 +2297,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "LDAP 소스" | ||||
| @ -2279,6 +2319,11 @@ msgstr "" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "" | ||||
| @ -2657,6 +2702,11 @@ msgstr "" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "" | ||||
| @ -3017,6 +3067,10 @@ msgstr "사용자 동의" | ||||
| msgid "User Consents" | ||||
| msgstr "사용자 동의" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "거부 스테이지" | ||||
| @ -3033,6 +3087,14 @@ msgstr "더미 스테이지" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "더미 스테이지" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "비밀번호 초기화" | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -19,7 +19,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-11 00:10+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Dany Sluijk, 2025\n" | ||||
| "Language-Team: Dutch (https://app.transifex.com/authentik/teams/119923/nl/)\n" | ||||
| @ -113,6 +113,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Webcertificaat gebruikt door de authentik Core-webserver." | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "Merk" | ||||
| @ -191,6 +195,7 @@ msgid "User's display name." | ||||
| msgstr "Weergavenaam van de gebruiker." | ||||
|  | ||||
| #: authentik/core/models.py authentik/providers/oauth2/models.py | ||||
| #: authentik/rbac/models.py | ||||
| msgid "User" | ||||
| msgstr "Gebruiker" | ||||
|  | ||||
| @ -379,6 +384,18 @@ msgstr "Eigenschapskoppeling" | ||||
| msgid "Property Mappings" | ||||
| msgstr "Eigenschapskoppelingen" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "session data" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Session" | ||||
| msgstr "Sessie" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Sessions" | ||||
| msgstr "Sessies" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Authenticated Session" | ||||
| msgstr "Geauthenticeerde Sessie" | ||||
| @ -486,6 +503,38 @@ msgstr "Licentie Gebruik" | ||||
| msgid "License Usage Records" | ||||
| msgstr "Licentie Gebruik Records" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| #: authentik/policies/password/models.py | ||||
| msgid "Field key to check, field keys defined in Prompt stages are available." | ||||
| msgstr "" | ||||
| "Veldsleutel om te controleren, veldsleutels gedefinieerd in Prompt-stadia " | ||||
| "zijn beschikbaar." | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "Number of passwords to check against." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| #: authentik/policies/password/models.py | ||||
| msgid "Password not set in context" | ||||
| msgstr "Wachtwoord niet ingesteld in context" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "This password has been used previously. Please choose a different one." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "Password Uniqueness Policy" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "Password Uniqueness Policies" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "User Password History" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/policy.py | ||||
| msgid "Enterprise required to access this feature." | ||||
| msgstr "Enterprise benodigd voor toegang tot deze functie." | ||||
| @ -622,6 +671,33 @@ msgstr "" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "Uw browser wordt geverifieerd..." | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -963,8 +1039,11 @@ msgid "Starting full provider sync" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| @ -1265,12 +1344,6 @@ msgstr "" | ||||
| msgid "Clear Policy's cache metrics" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/policies/password/models.py | ||||
| msgid "Field key to check, field keys defined in Prompt stages are available." | ||||
| msgstr "" | ||||
| "Veldsleutel om te controleren, veldsleutels gedefinieerd in Prompt-stadia " | ||||
| "zijn beschikbaar." | ||||
|  | ||||
| #: authentik/policies/password/models.py | ||||
| msgid "How many times the password hash is allowed to be on haveibeenpwned" | ||||
| msgstr "Hoe vaak het wachtwoordhash op haveibeenpwned mag voorkomen" | ||||
| @ -1282,10 +1355,6 @@ msgstr "" | ||||
| "Als de zxcvbn-score gelijk is aan of lager is dan deze waarde, zal het " | ||||
| "beleid falen." | ||||
|  | ||||
| #: authentik/policies/password/models.py | ||||
| msgid "Password not set in context" | ||||
| msgstr "Wachtwoord niet ingesteld in context" | ||||
|  | ||||
| #: authentik/policies/password/models.py | ||||
| msgid "Invalid password." | ||||
| msgstr "" | ||||
| @ -1327,20 +1396,6 @@ msgstr "Reputatie Score" | ||||
| msgid "Reputation Scores" | ||||
| msgstr "Reputatie Scores" | ||||
|  | ||||
| #: authentik/policies/templates/policies/buffer.html | ||||
| msgid "Waiting for authentication..." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/policies/templates/policies/buffer.html | ||||
| msgid "" | ||||
| "You're already authenticating in another tab. This page will refresh once " | ||||
| "authentication is completed." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/policies/templates/policies/buffer.html | ||||
| msgid "Authenticate in this tab" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/policies/templates/policies/denied.html | ||||
| msgid "Permission denied" | ||||
| msgstr "Toestemming geweigerd" | ||||
| @ -2160,6 +2215,10 @@ msgstr "" | ||||
| msgid "Roles" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/rbac/models.py | ||||
| msgid "Initial Permissions" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/rbac/models.py | ||||
| msgid "System permission" | ||||
| msgstr "" | ||||
| @ -2392,6 +2451,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "LDAP-bron" | ||||
| @ -2408,6 +2473,27 @@ msgstr "" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connections" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "Group LDAP Source Connection" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "Group LDAP Source Connections" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/signals.py | ||||
| msgid "Password does not match Active Directory Complexity." | ||||
| msgstr "" | ||||
| @ -2417,6 +2503,14 @@ msgstr "" | ||||
| msgid "No token received." | ||||
| msgstr "Geen token ontvangen." | ||||
|  | ||||
| #: authentik/sources/oauth/models.py | ||||
| msgid "HTTP Basic Authentication" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/oauth/models.py | ||||
| msgid "Include the client ID and secret as request parameters" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/oauth/models.py | ||||
| msgid "Request Token URL" | ||||
| msgstr "URL voor aanvragen van token" | ||||
| @ -2458,6 +2552,12 @@ msgstr "" | ||||
| msgid "Additional Scopes" | ||||
| msgstr "Aanvullende scopes" | ||||
|  | ||||
| #: authentik/sources/oauth/models.py | ||||
| msgid "" | ||||
| "How to perform authentication during an authorization_code token request " | ||||
| "flow" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/oauth/models.py | ||||
| msgid "OAuth Source" | ||||
| msgstr "OAuth-bron" | ||||
| @ -2769,6 +2869,11 @@ msgstr "" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "" | ||||
| @ -3142,6 +3247,10 @@ msgstr "Gebruikerstoestemming" | ||||
| msgid "User Consents" | ||||
| msgstr "Gebruikersinstemmingen" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Weigerfase" | ||||
| @ -3158,6 +3267,14 @@ msgstr "Dummystadium" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Dummystadia" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Wachtwoordherstel" | ||||
| @ -3357,6 +3474,12 @@ msgstr "" | ||||
| "Wanneer ingeschakeld, slaagt de stap en gaat verder wanneer ongeldige " | ||||
| "gebruikersgegevens zijn ingevoerd." | ||||
|  | ||||
| #: authentik/stages/identification/models.py | ||||
| msgid "" | ||||
| "Show the user the 'Remember me on this device' toggle, allowing repeat users" | ||||
| " to skip straight to entering their password." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/identification/models.py | ||||
| msgid "Optional enrollment flow, which is linked at the bottom of the page." | ||||
| msgstr "Optionele inschrijvingsflow, die onderaan de pagina is gekoppeld." | ||||
| @ -3742,6 +3865,14 @@ msgstr "" | ||||
| "Gebeurtenissen worden verwijderd na deze duur. (Indeling: " | ||||
| "weken=3;dagen=2;uren=3;seconden=2)." | ||||
|  | ||||
| #: authentik/tenants/models.py | ||||
| msgid "Reputation cannot decrease lower than this value. Zero or negative." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/tenants/models.py | ||||
| msgid "Reputation cannot increase higher than this value. Zero or positive." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/tenants/models.py | ||||
| msgid "The option configures the footer links on the flow executor pages." | ||||
| msgstr "De optie stelt de voettekst links in op de flow uitvoer pagina's." | ||||
|  | ||||
| @ -11,7 +11,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Hugo Bicho, 2025\n" | ||||
| "Language-Team: Portuguese (https://app.transifex.com/authentik/teams/119923/pt/)\n" | ||||
| @ -105,6 +105,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Certificado Web usado pelo servidor web authentik Core." | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "Marca" | ||||
| @ -662,6 +666,33 @@ msgstr "Dispositivos do ponto de ligação" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "A verificar o seu browser..." | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -1007,9 +1038,12 @@ msgid "Starting full provider sync" | ||||
| msgstr "Iniciando a sincronização completa com o provedor" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgstr "A sincronizar a página {page} dos utilizadores" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| @ -2456,6 +2490,12 @@ msgstr "" | ||||
| " um atributo do grupo. Isto permite a resolução de grupos hierárquicos em " | ||||
| "sistemas como o FreeIPA e Active Directory." | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "Fonte LDAP" | ||||
| @ -2472,6 +2512,11 @@ msgstr "Mapeamento de propriedades de fonte LDAP" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "Mapeamentos de propriedades de fonte LDAP" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "Ligação à fonte LDAP de Utilizador" | ||||
| @ -2865,6 +2910,11 @@ msgstr "Ligação à fonte SAML de Grupo" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "Ligações à fonte SAML de Grupo" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "Fonte SCIM" | ||||
| @ -3255,6 +3305,10 @@ msgstr "Consentimento do Utilizador" | ||||
| msgid "User Consents" | ||||
| msgstr "Consentimentos do Utilizador" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Etapa de negação" | ||||
| @ -3271,6 +3325,14 @@ msgstr "Etapa fictícia" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Etapas fictícias" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Redefinição de Palavra-Passe" | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -8,19 +8,19 @@ | ||||
| # Josenivaldo Benito Junior, 2023 | ||||
| # Caio Lima, 2023 | ||||
| # Hacklab, 2023 | ||||
| # Wagner Santos, 2024 | ||||
| # Rafael Mundel, 2024 | ||||
| # Anderson Silva Andrade <anderson.asa89@gmail.com>, 2025 | ||||
| # Gil Poiares-Oliveira, 2025 | ||||
| # Wagner Santos, 2025 | ||||
| #  | ||||
| #, fuzzy | ||||
| msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Gil Poiares-Oliveira, 2025\n" | ||||
| "Last-Translator: Wagner Santos, 2025\n" | ||||
| "Language-Team: Portuguese (Brazil) (https://app.transifex.com/authentik/teams/119923/pt_BR/)\n" | ||||
| "MIME-Version: 1.0\n" | ||||
| "Content-Type: text/plain; charset=UTF-8\n" | ||||
| @ -112,6 +112,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Certificado da Web usado pelo servidor da web authentik Core." | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "Brand" | ||||
| @ -271,11 +275,11 @@ msgstr "Aplicativos" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Application Entitlement" | ||||
| msgstr "" | ||||
| msgstr "Autorização de aplicação" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Application Entitlements" | ||||
| msgstr "" | ||||
| msgstr "Autorizações de aplicação" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Use the source-specific identifier" | ||||
| @ -379,15 +383,15 @@ msgstr "Mapeamentos de propriedades" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "session data" | ||||
| msgstr "" | ||||
| msgstr "dados de sessão" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Session" | ||||
| msgstr "" | ||||
| msgstr "Sessão" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Sessions" | ||||
| msgstr "" | ||||
| msgstr "Sessões" | ||||
|  | ||||
| #: authentik/core/models.py | ||||
| msgid "Authenticated Session" | ||||
| @ -505,7 +509,7 @@ msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "Number of passwords to check against." | ||||
| msgstr "" | ||||
| msgstr "Número de senhas para verificar." | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| #: authentik/policies/password/models.py | ||||
| @ -514,19 +518,19 @@ msgstr "Senha não definida no contexto" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "This password has been used previously. Please choose a different one." | ||||
| msgstr "" | ||||
| msgstr "A senha já foi utilizada antes. Por favor, escolha uma diferente." | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "Password Uniqueness Policy" | ||||
| msgstr "" | ||||
| msgstr "Política de exclusividade de senha" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "Password Uniqueness Policies" | ||||
| msgstr "" | ||||
| msgstr "Políticas de exclusividade de senha" | ||||
|  | ||||
| #: authentik/enterprise/policies/unique_password/models.py | ||||
| msgid "User Password History" | ||||
| msgstr "" | ||||
| msgstr "Histórico de senhas do usuário" | ||||
|  | ||||
| #: authentik/enterprise/policy.py | ||||
| msgid "Enterprise required to access this feature." | ||||
| @ -610,39 +614,39 @@ msgstr "Chave de Assinatura" | ||||
|  | ||||
| #: authentik/enterprise/providers/ssf/models.py | ||||
| msgid "Key used to sign the SSF Events." | ||||
| msgstr "" | ||||
| msgstr "Chave utilizada para assinar os eventos SSF." | ||||
|  | ||||
| #: authentik/enterprise/providers/ssf/models.py | ||||
| msgid "Shared Signals Framework Provider" | ||||
| msgstr "" | ||||
| msgstr "Provedor de Shared Signals Framework" | ||||
|  | ||||
| #: authentik/enterprise/providers/ssf/models.py | ||||
| msgid "Shared Signals Framework Providers" | ||||
| msgstr "" | ||||
| msgstr "Provedores de Shared Signals Framework" | ||||
|  | ||||
| #: authentik/enterprise/providers/ssf/models.py | ||||
| msgid "Add stream to SSF provider" | ||||
| msgstr "" | ||||
| msgstr "Adicionar stream ao fornecedor SSF" | ||||
|  | ||||
| #: authentik/enterprise/providers/ssf/models.py | ||||
| msgid "SSF Stream" | ||||
| msgstr "" | ||||
| msgstr "Stream SSF" | ||||
|  | ||||
| #: authentik/enterprise/providers/ssf/models.py | ||||
| msgid "SSF Streams" | ||||
| msgstr "" | ||||
| msgstr "Streams SSF" | ||||
|  | ||||
| #: authentik/enterprise/providers/ssf/models.py | ||||
| msgid "SSF Stream Event" | ||||
| msgstr "" | ||||
| msgstr "Evento de stream SSF" | ||||
|  | ||||
| #: authentik/enterprise/providers/ssf/models.py | ||||
| msgid "SSF Stream Events" | ||||
| msgstr "" | ||||
| msgstr "Eventos de stream SSF" | ||||
|  | ||||
| #: authentik/enterprise/providers/ssf/tasks.py | ||||
| msgid "Failed to send request" | ||||
| msgstr "" | ||||
| msgstr "Falha ao enviar requisição" | ||||
|  | ||||
| #: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py | ||||
| msgid "Endpoint Authenticator Google Device Trust Connector Stage" | ||||
| @ -664,6 +668,33 @@ msgstr "" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -681,7 +712,7 @@ msgstr "" | ||||
| #: authentik/events/api/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Successfully started task {name}." | ||||
| msgstr "" | ||||
| msgstr "Tarefa {name} iniciada com sucesso." | ||||
|  | ||||
| #: authentik/events/models.py | ||||
| msgid "Event" | ||||
| @ -713,12 +744,16 @@ msgid "" | ||||
| "Customize the body of the request. Mapping should return data that is JSON-" | ||||
| "serializable." | ||||
| msgstr "" | ||||
| "Personalize o corpo do pedido. O mapeamento deve retornar dados que sejam " | ||||
| "serializáveis em JSON." | ||||
|  | ||||
| #: authentik/events/models.py | ||||
| msgid "" | ||||
| "Configure additional headers to be sent. Mapping should return a dictionary " | ||||
| "of key-value pairs" | ||||
| msgstr "" | ||||
| "Configurar cabeçalhos adicionais a serem enviados. O mapeamento deve " | ||||
| "retornar um dicionário de pares chave-valor" | ||||
|  | ||||
| #: authentik/events/models.py | ||||
| msgid "" | ||||
| @ -998,8 +1033,11 @@ msgid "Starting full provider sync" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| @ -1314,7 +1352,7 @@ msgstr "" | ||||
| #: authentik/policies/password/models.py | ||||
| #, python-brace-format | ||||
| msgid "Password exists on {count} online lists." | ||||
| msgstr "" | ||||
| msgstr "A senha está presente em {count}  listas de senhas vulneráveis." | ||||
|  | ||||
| #: authentik/policies/password/models.py | ||||
| msgid "Password is too weak." | ||||
| @ -2396,6 +2434,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "Fonte LDAP" | ||||
| @ -2412,6 +2456,11 @@ msgstr "" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "" | ||||
| @ -2802,6 +2851,11 @@ msgstr "" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "" | ||||
| @ -3174,6 +3228,10 @@ msgstr "Consentimento do usuário" | ||||
| msgid "User Consents" | ||||
| msgstr "Consentimentos do usuário" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Negar Estágio" | ||||
| @ -3190,6 +3248,14 @@ msgstr "Palco fictício" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Fases fictícias" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Redefinição de senha" | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -18,7 +18,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Marc Schmitt, 2025\n" | ||||
| "Language-Team: Russian (https://app.transifex.com/authentik/teams/119923/ru/)\n" | ||||
| @ -111,6 +111,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Web Certificate используемый для authentik Core webserver." | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "Бренд" | ||||
| @ -669,6 +673,33 @@ msgstr "Конечные устройства" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "Проверка вашего браузера..." | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -1009,8 +1040,11 @@ msgid "Starting full provider sync" | ||||
| msgstr "Запуск полной синхронизации провайдера" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| @ -2430,6 +2464,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "Источник LDAP" | ||||
| @ -2446,6 +2486,11 @@ msgstr "Сопоставление свойства LDAP источника" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "Сопоставление свойств LDAP источника" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "" | ||||
| @ -2842,6 +2887,11 @@ msgstr "Групповое подключение к источнику SAML" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "Групповые подключения к источнику SAML" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "Источник SCIM" | ||||
| @ -3219,6 +3269,10 @@ msgstr "Согласие пользователя" | ||||
| msgid "User Consents" | ||||
| msgstr "Согласия пользователя" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Этап отказа" | ||||
| @ -3235,6 +3289,14 @@ msgstr "Фиктивный этап" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Фиктивные этапы" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Сброс пароля" | ||||
|  | ||||
| @ -13,7 +13,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: Jens L. <jens@goauthentik.io>, 2025\n" | ||||
| "Language-Team: Turkish (https://app.transifex.com/authentik/teams/119923/tr/)\n" | ||||
| @ -107,6 +107,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "Authentik Core web sunucusu tarafından kullanılan Web Sertifikası." | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "Marka" | ||||
| @ -659,6 +663,33 @@ msgstr "Uç Nokta Cihazları" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "Tarayıcınız doğrulanıyor..." | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -1000,8 +1031,11 @@ msgid "Starting full provider sync" | ||||
| msgstr "Tam sağlayıcı senkronizasyonunu başlatma" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| @ -2430,6 +2464,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "LDAP Kaynağı" | ||||
| @ -2446,6 +2486,11 @@ msgstr "LDAP Kaynak Özellik Eşlemesi" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "LDAP Kaynak Özellik Eşlemeleri" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "" | ||||
| @ -2837,6 +2882,11 @@ msgstr "Grup SAML Kaynak Bağlantısı" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "Grup SAML Kaynak Bağlantıları" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "SCIM Kaynak" | ||||
| @ -3211,6 +3261,10 @@ msgstr "Kullanıcı Onayı" | ||||
| msgid "User Consents" | ||||
| msgstr "Kullanıcı Onayları" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "Aşama Alanını Reddet" | ||||
| @ -3227,6 +3281,14 @@ msgstr "Kukla Aşaması" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "Kukla Aşamaları" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "Parola Sıfırlama" | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -15,7 +15,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-05-20 00:10+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: deluxghost, 2025\n" | ||||
| "Language-Team: Chinese Simplified (https://app.transifex.com/authentik/teams/119923/zh-Hans/)\n" | ||||
| @ -975,9 +975,12 @@ msgid "Starting full provider sync" | ||||
| msgstr "开始全量提供程序同步" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgstr "正在同步用户页面 {page}" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| @ -2285,6 +2288,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "基于用户属性而非组属性查询组成员身份。这允许在 FreeIPA 或 Active Directory 等系统上支持嵌套组决策" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "LDAP 源" | ||||
| @ -2301,6 +2310,11 @@ msgstr "LDAP 源属性映射" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "LDAP 源属性映射" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "用户 LDAP 源连接" | ||||
| @ -2678,6 +2692,11 @@ msgstr "组 SAML 源连接" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "组 SAML 源连接" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "SCIM 源" | ||||
| @ -3044,6 +3063,10 @@ msgstr "用户同意授权" | ||||
| msgid "User Consents" | ||||
| msgstr "用户同意授权" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "拒绝阶段" | ||||
| @ -3060,6 +3083,14 @@ msgstr "虚拟阶段" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "虚拟阶段" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "密码重置" | ||||
|  | ||||
										
											Binary file not shown.
										
									
								
							| @ -14,7 +14,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-05-20 00:10+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: deluxghost, 2025\n" | ||||
| "Language-Team: Chinese (China) (https://app.transifex.com/authentik/teams/119923/zh_CN/)\n" | ||||
| @ -974,9 +974,12 @@ msgid "Starting full provider sync" | ||||
| msgstr "开始全量提供程序同步" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgstr "正在同步用户页面 {page}" | ||||
| msgid "Syncing users" | ||||
| msgstr "正在同步用户" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "正在同步组" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| @ -2284,6 +2287,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "基于用户属性而非组属性查询组成员身份。这允许在 FreeIPA 或 Active Directory 等系统上支持嵌套组决策" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "删除之前由此源提供,但现已缺失的用户和组。" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "LDAP 源" | ||||
| @ -2300,6 +2309,11 @@ msgstr "LDAP 源属性映射" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "LDAP 源属性映射" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "检查此对象是否仍在目录中时使用的唯一 ID。" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "用户 LDAP 源连接" | ||||
| @ -2677,6 +2691,11 @@ msgstr "组 SAML 源连接" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "组 SAML 源连接" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "继续前往 {source_name}" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "SCIM 源" | ||||
| @ -3043,6 +3062,10 @@ msgstr "用户同意授权" | ||||
| msgid "User Consents" | ||||
| msgstr "用户同意授权" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "无效的同意令牌,将重新显示输入" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "拒绝阶段" | ||||
| @ -3059,6 +3082,14 @@ msgstr "虚拟阶段" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "虚拟阶段" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "继续以确认电子邮件地址。" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "链接已被使用,请申请一个新链接。" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "密码重置" | ||||
|  | ||||
| @ -14,7 +14,7 @@ msgid "" | ||||
| msgstr "" | ||||
| "Project-Id-Version: PACKAGE VERSION\n" | ||||
| "Report-Msgid-Bugs-To: \n" | ||||
| "POT-Creation-Date: 2025-04-23 09:00+0000\n" | ||||
| "POT-Creation-Date: 2025-05-28 11:25+0000\n" | ||||
| "PO-Revision-Date: 2022-09-26 16:47+0000\n" | ||||
| "Last-Translator: 刘松, 2025\n" | ||||
| "Language-Team: Chinese (Taiwan) (https://app.transifex.com/authentik/teams/119923/zh_TW/)\n" | ||||
| @ -101,6 +101,10 @@ msgstr "" | ||||
| msgid "Web Certificate used by the authentik Core webserver." | ||||
| msgstr "用於 authentik Core 網頁伺服器的網頁憑證。" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Certificates used for client authentication." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/brands/models.py | ||||
| msgid "Brand" | ||||
| msgstr "品牌" | ||||
| @ -625,6 +629,33 @@ msgstr "" | ||||
| msgid "Verifying your browser..." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "" | ||||
| "Configure certificate authorities to validate the certificate against. This " | ||||
| "option has a higher priority than the `client_certificate` option on " | ||||
| "`Brand`." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stage" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Mutual TLS Stages" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/models.py | ||||
| msgid "Permissions to pass Certificates for outposts." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "Certificate required but no certificate was given." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/mtls/stage.py | ||||
| msgid "No user found for certificate." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/enterprise/stages/source/models.py | ||||
| msgid "" | ||||
| "Amount of time a user can take to return from the source to continue the " | ||||
| @ -943,8 +974,11 @@ msgid "Starting full provider sync" | ||||
| msgstr "開始同步所有提供程式" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| #, python-brace-format | ||||
| msgid "Syncing page {page} of users" | ||||
| msgid "Syncing users" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| msgid "Syncing groups" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/lib/sync/outgoing/tasks.py | ||||
| @ -2249,6 +2283,12 @@ msgid "" | ||||
| "Active Directory" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Delete authentik users and groups which were previously supplied by this " | ||||
| "source, but are now missing from it." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "LDAP Source" | ||||
| msgstr "LDAP 來源" | ||||
| @ -2265,6 +2305,11 @@ msgstr "" | ||||
| msgid "LDAP Source Property Mappings" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "" | ||||
| "Unique ID used while checking if this object still exists in the directory." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/ldap/models.py | ||||
| msgid "User LDAP Source Connection" | ||||
| msgstr "" | ||||
| @ -2642,6 +2687,11 @@ msgstr "" | ||||
| msgid "Group SAML Source Connections" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/saml/views.py | ||||
| #, python-brace-format | ||||
| msgid "Continue to {source_name}" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/sources/scim/models.py | ||||
| msgid "SCIM Source" | ||||
| msgstr "SCIM 來源" | ||||
| @ -2998,6 +3048,10 @@ msgstr "使用者同意" | ||||
| msgid "User Consents" | ||||
| msgstr "使用者同意" | ||||
|  | ||||
| #: authentik/stages/consent/stage.py | ||||
| msgid "Invalid consent token, re-showing prompt" | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/deny/models.py | ||||
| msgid "Deny Stage" | ||||
| msgstr "拒絕階段" | ||||
| @ -3014,6 +3068,14 @@ msgstr "假階段" | ||||
| msgid "Dummy Stages" | ||||
| msgstr "假階段" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Continue to confirm this email address." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/flow.py | ||||
| msgid "Link was already used, please request a new link." | ||||
| msgstr "" | ||||
|  | ||||
| #: authentik/stages/email/models.py | ||||
| msgid "Password Reset" | ||||
| msgstr "重設密碼" | ||||
|  | ||||
							
								
								
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										4
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,12 +1,12 @@ | ||||
| { | ||||
|     "name": "@goauthentik/authentik", | ||||
|     "version": "2025.4.1", | ||||
|     "version": "2025.6.0", | ||||
|     "lockfileVersion": 3, | ||||
|     "requires": true, | ||||
|     "packages": { | ||||
|         "": { | ||||
|             "name": "@goauthentik/authentik", | ||||
|             "version": "2025.4.1", | ||||
|             "version": "2025.6.0", | ||||
|             "devDependencies": { | ||||
|                 "@trivago/prettier-plugin-sort-imports": "^5.2.2", | ||||
|                 "prettier": "^3.3.3", | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
|     "name": "@goauthentik/authentik", | ||||
|     "version": "2025.4.1", | ||||
|     "version": "2025.6.0", | ||||
|     "private": true, | ||||
|     "type": "module", | ||||
|     "devDependencies": { | ||||
|  | ||||
							
								
								
									
										160
									
								
								packages/eslint-config/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										160
									
								
								packages/eslint-config/package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -274,9 +274,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@eslint/js": { | ||||
|             "version": "9.27.0", | ||||
|             "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.27.0.tgz", | ||||
|             "integrity": "sha512-G5JD9Tu5HJEu4z2Uo4aHY2sLV64B7CDMXxFzqzjl3NKd6RVzSXNoE80jk7Y0lJkTTkjiIhBAqmlYwjuBY3tvpA==", | ||||
|             "version": "9.28.0", | ||||
|             "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.28.0.tgz", | ||||
|             "integrity": "sha512-fnqSjGWd/CoIp4EXIxWVK/sHA6DOHN4+8Ix2cX5ycOY7LG0UY8nHCU5pIp2eaE1Mc7Qd8kHspYNzYXT2ojPLzg==", | ||||
|             "license": "MIT", | ||||
|             "engines": { | ||||
|                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||||
| @ -576,17 +576,17 @@ | ||||
|             "license": "MIT" | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/eslint-plugin": { | ||||
|             "version": "8.32.1", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz", | ||||
|             "integrity": "sha512-6u6Plg9nP/J1GRpe/vcjjabo6Uc5YQPAMxsgQyGC/I0RuukiG1wIe3+Vtg3IrSCVJDmqK3j8adrtzXSENRtFgg==", | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.0.tgz", | ||||
|             "integrity": "sha512-CACyQuqSHt7ma3Ns601xykeBK/rDeZa3w6IS6UtMQbixO5DWy+8TilKkviGDH6jtWCo8FGRKEK5cLLkPvEammQ==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@eslint-community/regexpp": "^4.10.0", | ||||
|                 "@typescript-eslint/scope-manager": "8.32.1", | ||||
|                 "@typescript-eslint/type-utils": "8.32.1", | ||||
|                 "@typescript-eslint/utils": "8.32.1", | ||||
|                 "@typescript-eslint/visitor-keys": "8.32.1", | ||||
|                 "@typescript-eslint/scope-manager": "8.33.0", | ||||
|                 "@typescript-eslint/type-utils": "8.33.0", | ||||
|                 "@typescript-eslint/utils": "8.33.0", | ||||
|                 "@typescript-eslint/visitor-keys": "8.33.0", | ||||
|                 "graphemer": "^1.4.0", | ||||
|                 "ignore": "^7.0.0", | ||||
|                 "natural-compare": "^1.4.0", | ||||
| @ -600,15 +600,15 @@ | ||||
|                 "url": "https://opencollective.com/typescript-eslint" | ||||
|             }, | ||||
|             "peerDependencies": { | ||||
|                 "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", | ||||
|                 "@typescript-eslint/parser": "^8.33.0", | ||||
|                 "eslint": "^8.57.0 || ^9.0.0", | ||||
|                 "typescript": ">=4.8.4 <5.9.0" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { | ||||
|             "version": "7.0.4", | ||||
|             "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.4.tgz", | ||||
|             "integrity": "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A==", | ||||
|             "version": "7.0.5", | ||||
|             "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", | ||||
|             "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "engines": { | ||||
| @ -616,16 +616,16 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/parser": { | ||||
|             "version": "8.32.1", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.32.1.tgz", | ||||
|             "integrity": "sha512-LKMrmwCPoLhM45Z00O1ulb6jwyVr2kr3XJp+G+tSEZcbauNnScewcQwtJqXDhXeYPDEjZ8C1SjXm015CirEmGg==", | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.0.tgz", | ||||
|             "integrity": "sha512-JaehZvf6m0yqYp34+RVnihBAChkqeH+tqqhS0GuX1qgPpwLvmTPheKEs6OeCK6hVJgXZHJ2vbjnC9j119auStQ==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/scope-manager": "8.32.1", | ||||
|                 "@typescript-eslint/types": "8.32.1", | ||||
|                 "@typescript-eslint/typescript-estree": "8.32.1", | ||||
|                 "@typescript-eslint/visitor-keys": "8.32.1", | ||||
|                 "@typescript-eslint/scope-manager": "8.33.0", | ||||
|                 "@typescript-eslint/types": "8.33.0", | ||||
|                 "@typescript-eslint/typescript-estree": "8.33.0", | ||||
|                 "@typescript-eslint/visitor-keys": "8.33.0", | ||||
|                 "debug": "^4.3.4" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -640,15 +640,16 @@ | ||||
|                 "typescript": ">=4.8.4 <5.9.0" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/scope-manager": { | ||||
|             "version": "8.32.1", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.32.1.tgz", | ||||
|             "integrity": "sha512-7IsIaIDeZn7kffk7qXC3o6Z4UblZJKV3UBpkvRNpr5NSyLji7tvTcvmnMNYuYLyh26mN8W723xpo3i4MlD33vA==", | ||||
|         "node_modules/@typescript-eslint/project-service": { | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.0.tgz", | ||||
|             "integrity": "sha512-d1hz0u9l6N+u/gcrk6s6gYdl7/+pp8yHheRTqP6X5hVDKALEaTn8WfGiit7G511yueBEL3OpOEpD+3/MBdoN+A==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/types": "8.32.1", | ||||
|                 "@typescript-eslint/visitor-keys": "8.32.1" | ||||
|                 "@typescript-eslint/tsconfig-utils": "^8.33.0", | ||||
|                 "@typescript-eslint/types": "^8.33.0", | ||||
|                 "debug": "^4.3.4" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||||
| @ -658,15 +659,50 @@ | ||||
|                 "url": "https://opencollective.com/typescript-eslint" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/type-utils": { | ||||
|             "version": "8.32.1", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.32.1.tgz", | ||||
|             "integrity": "sha512-mv9YpQGA8iIsl5KyUPi+FGLm7+bA4fgXaeRcFKRDRwDMu4iwrSHeDPipwueNXhdIIZltwCJv+NkxftECbIZWfA==", | ||||
|         "node_modules/@typescript-eslint/scope-manager": { | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.0.tgz", | ||||
|             "integrity": "sha512-LMi/oqrzpqxyO72ltP+dBSP6V0xiUb4saY7WLtxSfiNEBI8m321LLVFU9/QDJxjDQG9/tjSqKz/E3380TEqSTw==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/typescript-estree": "8.32.1", | ||||
|                 "@typescript-eslint/utils": "8.32.1", | ||||
|                 "@typescript-eslint/types": "8.33.0", | ||||
|                 "@typescript-eslint/visitor-keys": "8.33.0" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||||
|             }, | ||||
|             "funding": { | ||||
|                 "type": "opencollective", | ||||
|                 "url": "https://opencollective.com/typescript-eslint" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/tsconfig-utils": { | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.0.tgz", | ||||
|             "integrity": "sha512-sTkETlbqhEoiFmGr1gsdq5HyVbSOF0145SYDJ/EQmXHtKViCaGvnyLqWFFHtEXoS0J1yU8Wyou2UGmgW88fEug==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "engines": { | ||||
|                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||||
|             }, | ||||
|             "funding": { | ||||
|                 "type": "opencollective", | ||||
|                 "url": "https://opencollective.com/typescript-eslint" | ||||
|             }, | ||||
|             "peerDependencies": { | ||||
|                 "typescript": ">=4.8.4 <5.9.0" | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/type-utils": { | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.0.tgz", | ||||
|             "integrity": "sha512-lScnHNCBqL1QayuSrWeqAL5GmqNdVUQAAMTaCwdYEdWfIrSrOGzyLGRCHXcCixa5NK6i5l0AfSO2oBSjCjf4XQ==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/typescript-estree": "8.33.0", | ||||
|                 "@typescript-eslint/utils": "8.33.0", | ||||
|                 "debug": "^4.3.4", | ||||
|                 "ts-api-utils": "^2.1.0" | ||||
|             }, | ||||
| @ -683,9 +719,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/types": { | ||||
|             "version": "8.32.1", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.32.1.tgz", | ||||
|             "integrity": "sha512-YmybwXUJcgGqgAp6bEsgpPXEg6dcCyPyCSr0CAAueacR/CCBi25G3V8gGQ2kRzQRBNol7VQknxMs9HvVa9Rvfg==", | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.0.tgz", | ||||
|             "integrity": "sha512-DKuXOKpM5IDT1FA2g9x9x1Ug81YuKrzf4mYX8FAVSNu5Wo/LELHWQyM1pQaDkI42bX15PWl0vNPt1uGiIFUOpg==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "engines": { | ||||
| @ -697,14 +733,16 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/typescript-estree": { | ||||
|             "version": "8.32.1", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.32.1.tgz", | ||||
|             "integrity": "sha512-Y3AP9EIfYwBb4kWGb+simvPaqQoT5oJuzzj9m0i6FCY6SPvlomY2Ei4UEMm7+FXtlNJbor80ximyslzaQF6xhg==", | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.0.tgz", | ||||
|             "integrity": "sha512-vegY4FQoB6jL97Tu/lWRsAiUUp8qJTqzAmENH2k59SJhw0Th1oszb9Idq/FyyONLuNqT1OADJPXfyUNOR8SzAQ==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/types": "8.32.1", | ||||
|                 "@typescript-eslint/visitor-keys": "8.32.1", | ||||
|                 "@typescript-eslint/project-service": "8.33.0", | ||||
|                 "@typescript-eslint/tsconfig-utils": "8.33.0", | ||||
|                 "@typescript-eslint/types": "8.33.0", | ||||
|                 "@typescript-eslint/visitor-keys": "8.33.0", | ||||
|                 "debug": "^4.3.4", | ||||
|                 "fast-glob": "^3.3.2", | ||||
|                 "is-glob": "^4.0.3", | ||||
| @ -763,16 +801,16 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/utils": { | ||||
|             "version": "8.32.1", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.32.1.tgz", | ||||
|             "integrity": "sha512-DsSFNIgLSrc89gpq1LJB7Hm1YpuhK086DRDJSNrewcGvYloWW1vZLHBTIvarKZDcAORIy/uWNx8Gad+4oMpkSA==", | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.0.tgz", | ||||
|             "integrity": "sha512-lPFuQaLA9aSNa7D5u2EpRiqdAUhzShwGg/nhpBlc4GR6kcTABttCuyjFs8BcEZ8VWrjCBof/bePhP3Q3fS+Yrw==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@eslint-community/eslint-utils": "^4.7.0", | ||||
|                 "@typescript-eslint/scope-manager": "8.32.1", | ||||
|                 "@typescript-eslint/types": "8.32.1", | ||||
|                 "@typescript-eslint/typescript-estree": "8.32.1" | ||||
|                 "@typescript-eslint/scope-manager": "8.33.0", | ||||
|                 "@typescript-eslint/types": "8.33.0", | ||||
|                 "@typescript-eslint/typescript-estree": "8.33.0" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||||
| @ -787,13 +825,13 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/@typescript-eslint/visitor-keys": { | ||||
|             "version": "8.32.1", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.32.1.tgz", | ||||
|             "integrity": "sha512-ar0tjQfObzhSaW3C3QNmTc5ofj0hDoNQ5XWrCy6zDyabdr0TWhCkClp+rywGNj/odAFBVzzJrK4tEq5M4Hmu4w==", | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.0.tgz", | ||||
|             "integrity": "sha512-7RW7CMYoskiz5OOGAWjJFxgb7c5UNjTG292gYhWeOAcFmYCtVCSqjqSBj5zMhxbXo2JOW95YYrUWJfU0zrpaGQ==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/types": "8.32.1", | ||||
|                 "@typescript-eslint/types": "8.33.0", | ||||
|                 "eslint-visitor-keys": "^4.2.0" | ||||
|             }, | ||||
|             "engines": { | ||||
| @ -1513,9 +1551,9 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/eslint": { | ||||
|             "version": "9.27.0", | ||||
|             "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.27.0.tgz", | ||||
|             "integrity": "sha512-ixRawFQuMB9DZ7fjU3iGGganFDp3+45bPOdaRurcFHSXO1e/sYwUX/FtQZpLZJR6SjMoJH8hR2pPEAfDyCoU2Q==", | ||||
|             "version": "9.28.0", | ||||
|             "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.28.0.tgz", | ||||
|             "integrity": "sha512-ocgh41VhRlf9+fVpe7QKzwLj9c92fDiqOj8Y3Sd4/ZmVA4Btx4PlUYPq4pp9JDyupkf1upbEXecxL2mwNV7jPQ==", | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@eslint-community/eslint-utils": "^4.2.0", | ||||
| @ -1524,7 +1562,7 @@ | ||||
|                 "@eslint/config-helpers": "^0.2.1", | ||||
|                 "@eslint/core": "^0.14.0", | ||||
|                 "@eslint/eslintrc": "^3.3.1", | ||||
|                 "@eslint/js": "9.27.0", | ||||
|                 "@eslint/js": "9.28.0", | ||||
|                 "@eslint/plugin-kit": "^0.3.1", | ||||
|                 "@humanfs/node": "^0.16.6", | ||||
|                 "@humanwhocodes/module-importer": "^1.0.1", | ||||
| @ -3994,15 +4032,15 @@ | ||||
|             } | ||||
|         }, | ||||
|         "node_modules/typescript-eslint": { | ||||
|             "version": "8.32.1", | ||||
|             "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.32.1.tgz", | ||||
|             "integrity": "sha512-D7el+eaDHAmXvrZBy1zpzSNIRqnCOrkwTgZxTu3MUqRWk8k0q9m9Ho4+vPf7iHtgUfrK/o8IZaEApsxPlHTFCg==", | ||||
|             "version": "8.33.0", | ||||
|             "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.33.0.tgz", | ||||
|             "integrity": "sha512-5YmNhF24ylCsvdNW2oJwMzTbaeO4bg90KeGtMjUw0AGtHksgEPLRTUil+coHwCfiu4QjVJFnjp94DmU6zV7DhQ==", | ||||
|             "dev": true, | ||||
|             "license": "MIT", | ||||
|             "dependencies": { | ||||
|                 "@typescript-eslint/eslint-plugin": "8.32.1", | ||||
|                 "@typescript-eslint/parser": "8.32.1", | ||||
|                 "@typescript-eslint/utils": "8.32.1" | ||||
|                 "@typescript-eslint/eslint-plugin": "8.33.0", | ||||
|                 "@typescript-eslint/parser": "8.33.0", | ||||
|                 "@typescript-eslint/utils": "8.33.0" | ||||
|             }, | ||||
|             "engines": { | ||||
|                 "node": "^18.18.0 || ^20.9.0 || >=21.1.0" | ||||
|  | ||||
| @ -1,12 +1,12 @@ | ||||
| [project] | ||||
| name = "authentik" | ||||
| version = "2025.4.1" | ||||
| version = "2025.6.0" | ||||
| description = "" | ||||
| authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }] | ||||
| requires-python = "==3.13.*" | ||||
| dependencies = [ | ||||
|     "argon2-cffi==23.1.0", | ||||
|     "celery==5.5.2", | ||||
|     "argon2-cffi==25.1.0", | ||||
|     "celery==5.5.3", | ||||
|     "channels==4.2.2", | ||||
|     "channels-redis==4.2.1", | ||||
|     "cryptography==45.0.3", | ||||
| @ -35,7 +35,7 @@ dependencies = [ | ||||
|     "flower==2.0.1", | ||||
|     "geoip2==5.1.0", | ||||
|     "geopy==2.4.1", | ||||
|     "google-api-python-client==2.170.0", | ||||
|     "google-api-python-client==2.171.0", | ||||
|     "gssapi==1.9.0", | ||||
|     "gunicorn==23.0.0", | ||||
|     "jsonpatch==1.33", | ||||
| @ -43,7 +43,7 @@ dependencies = [ | ||||
|     "kubernetes==32.0.1", | ||||
|     "ldap3==2.9.1", | ||||
|     "lxml==5.4.0", | ||||
|     "msgraph-sdk==1.30.0", | ||||
|     "msgraph-sdk==1.32.0", | ||||
|     "opencontainers==0.0.14", | ||||
|     "packaging==25.0", | ||||
|     "paramiko==3.5.1", | ||||
| @ -59,14 +59,14 @@ dependencies = [ | ||||
|     "sentry-sdk==2.29.1", | ||||
|     "service-identity==24.2.0", | ||||
|     "setproctitle==1.3.6", | ||||
|     "structlog==25.3.0", | ||||
|     "structlog==25.4.0", | ||||
|     "swagger-spec-validator==3.0.4", | ||||
|     "tenant-schemas-celery==4.0.1", | ||||
|     "twilio==9.6.1", | ||||
|     "twilio==9.6.2", | ||||
|     "ua-parser==1.0.1", | ||||
|     "unidecode==1.4.0", | ||||
|     "urllib3<3", | ||||
|     "uvicorn[standard]==0.34.2", | ||||
|     "uvicorn[standard]==0.34.3", | ||||
|     "watchdog==6.0.0", | ||||
|     "webauthn==2.5.2", | ||||
|     "wsproto==1.2.0", | ||||
|  | ||||
							
								
								
									
										33
									
								
								schema.yml
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								schema.yml
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | ||||
| openapi: 3.0.3 | ||||
| info: | ||||
|   title: authentik | ||||
|   version: 2025.4.1 | ||||
|   version: 2025.6.0 | ||||
|   description: Making authentication simple. | ||||
|   contact: | ||||
|     email: hello@goauthentik.io | ||||
| @ -28473,6 +28473,10 @@ paths: | ||||
|         schema: | ||||
|           type: string | ||||
|           format: uuid | ||||
|       - in: query | ||||
|         name: delete_not_found_objects | ||||
|         schema: | ||||
|           type: boolean | ||||
|       - in: query | ||||
|         name: enabled | ||||
|         schema: | ||||
| @ -28577,6 +28581,10 @@ paths: | ||||
|         name: sync_users_password | ||||
|         schema: | ||||
|           type: boolean | ||||
|       - in: query | ||||
|         name: user_membership_attribute | ||||
|         schema: | ||||
|           type: string | ||||
|       - in: query | ||||
|         name: user_object_filter | ||||
|         schema: | ||||
| @ -47889,6 +47897,9 @@ components: | ||||
|         group_membership_field: | ||||
|           type: string | ||||
|           description: Field which contains members of a group. | ||||
|         user_membership_attribute: | ||||
|           type: string | ||||
|           description: Attribute which matches the value of `group_membership_field`. | ||||
|         object_uniqueness_field: | ||||
|           type: string | ||||
|           description: Field which contains a unique Identifier. | ||||
| @ -47922,6 +47933,10 @@ components: | ||||
|           description: Lookup group membership based on a user attribute instead of | ||||
|             a group attribute. This allows nested group resolution on systems like | ||||
|             FreeIPA and Active Directory | ||||
|         delete_not_found_objects: | ||||
|           type: boolean | ||||
|           description: Delete authentik users and groups which were previously supplied | ||||
|             by this source, but are now missing from it. | ||||
|       required: | ||||
|       - base_dn | ||||
|       - component | ||||
| @ -48098,6 +48113,10 @@ components: | ||||
|           type: string | ||||
|           minLength: 1 | ||||
|           description: Field which contains members of a group. | ||||
|         user_membership_attribute: | ||||
|           type: string | ||||
|           minLength: 1 | ||||
|           description: Attribute which matches the value of `group_membership_field`. | ||||
|         object_uniqueness_field: | ||||
|           type: string | ||||
|           minLength: 1 | ||||
| @ -48123,6 +48142,10 @@ components: | ||||
|           description: Lookup group membership based on a user attribute instead of | ||||
|             a group attribute. This allows nested group resolution on systems like | ||||
|             FreeIPA and Active Directory | ||||
|         delete_not_found_objects: | ||||
|           type: boolean | ||||
|           description: Delete authentik users and groups which were previously supplied | ||||
|             by this source, but are now missing from it. | ||||
|       required: | ||||
|       - base_dn | ||||
|       - name | ||||
| @ -53431,6 +53454,10 @@ components: | ||||
|           type: string | ||||
|           minLength: 1 | ||||
|           description: Field which contains members of a group. | ||||
|         user_membership_attribute: | ||||
|           type: string | ||||
|           minLength: 1 | ||||
|           description: Attribute which matches the value of `group_membership_field`. | ||||
|         object_uniqueness_field: | ||||
|           type: string | ||||
|           minLength: 1 | ||||
| @ -53456,6 +53483,10 @@ components: | ||||
|           description: Lookup group membership based on a user attribute instead of | ||||
|             a group attribute. This allows nested group resolution on systems like | ||||
|             FreeIPA and Active Directory | ||||
|         delete_not_found_objects: | ||||
|           type: boolean | ||||
|           description: Delete authentik users and groups which were previously supplied | ||||
|             by this source, but are now missing from it. | ||||
|     PatchedLicenseRequest: | ||||
|       type: object | ||||
|       description: License Serializer | ||||
|  | ||||
							
								
								
									
										7
									
								
								scripts/api-ts-templates/tsconfig.esm.mustache
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								scripts/api-ts-templates/tsconfig.esm.mustache
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,7 @@ | ||||
| { | ||||
|     "$schema": "https://json.schemastore.org/tsconfig", | ||||
|     "extends": "./tsconfig.json", | ||||
|     "compilerOptions": { | ||||
|         "outDir": "dist/esm", | ||||
|     }, | ||||
| } | ||||
							
								
								
									
										23
									
								
								scripts/api-ts-templates/tsconfig.mustache
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								scripts/api-ts-templates/tsconfig.mustache
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| { | ||||
|     "$schema": "https://json.schemastore.org/tsconfig", | ||||
|     "compilerOptions": { | ||||
|         "composite": true, | ||||
|         "isolatedModules": true, | ||||
|         "incremental": true, | ||||
|         "baseUrl": ".", | ||||
|         "rootDir": "src", | ||||
|         "strict": true, | ||||
|         "newLine": "lf", | ||||
|         "target": "ESNext", | ||||
|         "module": "ESNext", | ||||
|         "moduleResolution": "bundler", | ||||
|         "outDir": "dist", | ||||
|         "skipDefaultLibCheck": true, | ||||
|         "skipLibCheck": true, | ||||
|         "sourceMap": true, | ||||
|         "declaration": true, | ||||
|         "declarationMap": true, | ||||
|         "lib": ["DOM", "DOM.Iterable", "ESNext"], | ||||
|     }, | ||||
|     "exclude": ["node_modules", "./out/**/*", "./dist/**/*"], | ||||
| } | ||||
| @ -1,5 +1,6 @@ | ||||
| services: | ||||
|   chrome: | ||||
|     platform: linux/x86_64 | ||||
|     image: docker.io/selenium/standalone-chrome:136.0 | ||||
|     volumes: | ||||
|       - /dev/shm:/dev/shm | ||||
|  | ||||
| @ -10,6 +10,7 @@ from authentik.blueprints.tests import apply_blueprint | ||||
| from authentik.core.models import User | ||||
| from authentik.flows.models import Flow | ||||
| from authentik.lib.config import CONFIG | ||||
| from authentik.lib.generators import generate_id | ||||
| from authentik.stages.identification.models import IdentificationStage | ||||
| from tests.e2e.utils import SeleniumTestCase, retry | ||||
|  | ||||
| @ -17,6 +18,10 @@ from tests.e2e.utils import SeleniumTestCase, retry | ||||
| class TestFlowsEnroll(SeleniumTestCase): | ||||
|     """Test Enroll flow""" | ||||
|  | ||||
|     def setUp(self): | ||||
|         super().setUp() | ||||
|         self.username = generate_id() | ||||
|  | ||||
|     @retry() | ||||
|     @apply_blueprint( | ||||
|         "default/flow-default-authentication-flow.yaml", | ||||
| @ -39,8 +44,8 @@ class TestFlowsEnroll(SeleniumTestCase): | ||||
|         self.initial_stages() | ||||
|         sleep(2) | ||||
|  | ||||
|         user = User.objects.get(username="foo") | ||||
|         self.assertEqual(user.username, "foo") | ||||
|         user = User.objects.get(username=self.username) | ||||
|         self.assertEqual(user.username, self.username) | ||||
|         self.assertEqual(user.name, "some name") | ||||
|         self.assertEqual(user.email, "foo@bar.baz") | ||||
|  | ||||
| @ -87,7 +92,16 @@ class TestFlowsEnroll(SeleniumTestCase): | ||||
|  | ||||
|         sleep(2) | ||||
|  | ||||
|         self.assert_user(User.objects.get(username="foo")) | ||||
|         flow_executor = self.get_shadow_root("ak-flow-executor") | ||||
|         consent_stage = self.get_shadow_root("ak-stage-consent", flow_executor) | ||||
|         consent_stage.find_element( | ||||
|             By.CSS_SELECTOR, | ||||
|             "[type=submit]", | ||||
|         ).click() | ||||
|  | ||||
|         self.wait_for_url(self.if_user_url()) | ||||
|  | ||||
|         self.assert_user(User.objects.get(username=self.username)) | ||||
|  | ||||
|     def initial_stages(self): | ||||
|         """Fill out initial stages""" | ||||
| @ -105,7 +119,7 @@ class TestFlowsEnroll(SeleniumTestCase): | ||||
|         wait = WebDriverWait(prompt_stage, self.wait_timeout) | ||||
|  | ||||
|         wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "input[name=username]"))) | ||||
|         prompt_stage.find_element(By.CSS_SELECTOR, "input[name=username]").send_keys("foo") | ||||
|         prompt_stage.find_element(By.CSS_SELECTOR, "input[name=username]").send_keys(self.username) | ||||
|         prompt_stage.find_element(By.CSS_SELECTOR, "input[name=password]").send_keys( | ||||
|             self.user.username | ||||
|         ) | ||||
| @ -124,3 +138,82 @@ class TestFlowsEnroll(SeleniumTestCase): | ||||
|         prompt_stage.find_element(By.CSS_SELECTOR, "input[name=name]").send_keys("some name") | ||||
|         prompt_stage.find_element(By.CSS_SELECTOR, "input[name=email]").send_keys("foo@bar.baz") | ||||
|         prompt_stage.find_element(By.CSS_SELECTOR, ".pf-c-button").click() | ||||
|  | ||||
|     @retry() | ||||
|     @apply_blueprint( | ||||
|         "default/flow-default-authentication-flow.yaml", | ||||
|         "default/flow-default-invalidation-flow.yaml", | ||||
|     ) | ||||
|     @apply_blueprint( | ||||
|         "example/flows-enrollment-email-verification.yaml", | ||||
|     ) | ||||
|     @CONFIG.patch("email.port", 1025) | ||||
|     def test_enroll_email_pretend_email_scanner(self): | ||||
|         """Test enroll with Email verification. Open the email link twice to pretend we have an | ||||
|         email scanner that clicks on links""" | ||||
|         # Attach enrollment flow to identification stage | ||||
|         ident_stage: IdentificationStage = IdentificationStage.objects.get( | ||||
|             name="default-authentication-identification" | ||||
|         ) | ||||
|         ident_stage.enrollment_flow = Flow.objects.get(slug="default-enrollment-flow") | ||||
|         ident_stage.save() | ||||
|  | ||||
|         self.driver.get(self.live_server_url) | ||||
|         self.initial_stages() | ||||
|  | ||||
|         # Email stage | ||||
|         flow_executor = self.get_shadow_root("ak-flow-executor") | ||||
|         email_stage = self.get_shadow_root("ak-stage-email", flow_executor) | ||||
|  | ||||
|         wait = WebDriverWait(email_stage, self.wait_timeout) | ||||
|  | ||||
|         # Wait for the success message so we know the email is sent | ||||
|         wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, ".pf-c-form p"))) | ||||
|  | ||||
|         # Open Mailpit | ||||
|         self.driver.get("http://localhost:8025") | ||||
|  | ||||
|         # Click on first message | ||||
|         self.wait.until(ec.presence_of_element_located((By.CLASS_NAME, "message"))) | ||||
|         self.driver.find_element(By.CLASS_NAME, "message").click() | ||||
|         self.driver.switch_to.frame(self.driver.find_element(By.ID, "preview-html")) | ||||
|         confirmation_link = self.driver.find_element(By.ID, "confirm").get_attribute("href") | ||||
|  | ||||
|         main_tab = self.driver.current_window_handle | ||||
|  | ||||
|         self.driver.switch_to.new_window("tab") | ||||
|         confirm_tab = self.driver.current_window_handle | ||||
|  | ||||
|         # On the new tab, check that we have the confirmation screen | ||||
|         self.driver.get(confirmation_link) | ||||
|         self.wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "ak-flow-executor"))) | ||||
|  | ||||
|         flow_executor = self.get_shadow_root("ak-flow-executor") | ||||
|         consent_stage = self.get_shadow_root("ak-stage-consent", flow_executor) | ||||
|  | ||||
|         self.assertEqual( | ||||
|             "Continue to confirm this email address.", | ||||
|             consent_stage.find_element(By.CSS_SELECTOR, "#header-text").text, | ||||
|         ) | ||||
|  | ||||
|         # Back on the main tab, confirm | ||||
|         self.driver.switch_to.window(main_tab) | ||||
|         self.driver.get(confirmation_link) | ||||
|  | ||||
|         flow_executor = self.get_shadow_root("ak-flow-executor") | ||||
|         consent_stage = self.get_shadow_root("ak-stage-consent", flow_executor) | ||||
|         consent_stage.find_element( | ||||
|             By.CSS_SELECTOR, | ||||
|             "[type=submit]", | ||||
|         ).click() | ||||
|  | ||||
|         self.wait_for_url(self.if_user_url()) | ||||
|         sleep(2) | ||||
|  | ||||
|         self.assert_user(User.objects.get(username=self.username)) | ||||
|  | ||||
|         self.driver.switch_to.window(confirm_tab) | ||||
|         self.driver.refresh() | ||||
|         flow_executor = self.get_shadow_root("ak-flow-executor") | ||||
|         wait = WebDriverWait(flow_executor, self.wait_timeout) | ||||
|         wait.until(ec.presence_of_element_located((By.CSS_SELECTOR, "ak-stage-access-denied"))) | ||||
|  | ||||
| @ -84,6 +84,14 @@ class TestFlowsRecovery(SeleniumTestCase): | ||||
|         self.driver.switch_to.window(self.driver.window_handles[0]) | ||||
|  | ||||
|         sleep(2) | ||||
|  | ||||
|         flow_executor = self.get_shadow_root("ak-flow-executor") | ||||
|         consent_stage = self.get_shadow_root("ak-stage-consent", flow_executor) | ||||
|         consent_stage.find_element( | ||||
|             By.CSS_SELECTOR, | ||||
|             "[type=submit]", | ||||
|         ).click() | ||||
|  | ||||
|         # We can now enter the new password | ||||
|         flow_executor = self.get_shadow_root("ak-flow-executor") | ||||
|         prompt_stage = self.get_shadow_root("ak-stage-prompt", flow_executor) | ||||
|  | ||||
| @ -166,30 +166,35 @@ class SeleniumTestCase(DockerTestCase, StaticLiveServerTestCase): | ||||
|             print("::group::authentik Logs", file=stderr) | ||||
|         apps.get_app_config("authentik_tenants").ready() | ||||
|         self.wait_timeout = 60 | ||||
|         self.logger = get_logger() | ||||
|         self.driver = self._get_driver() | ||||
|         self.driver.implicitly_wait(30) | ||||
|         self.wait = WebDriverWait(self.driver, self.wait_timeout) | ||||
|         self.logger = get_logger() | ||||
|         self.user = create_test_admin_user() | ||||
|         super().setUp() | ||||
|  | ||||
|     def _get_driver(self) -> WebDriver: | ||||
|         count = 0 | ||||
|         try: | ||||
|         opts = webdriver.ChromeOptions() | ||||
|         opts.add_argument("--disable-search-engine-choice-screen") | ||||
|             return webdriver.Chrome(options=opts) | ||||
|         except WebDriverException: | ||||
|             pass | ||||
|         # This breaks selenium when running remotely...? | ||||
|         # opts.set_capability("goog:loggingPrefs", {"browser": "ALL"}) | ||||
|         opts.add_experimental_option( | ||||
|             "prefs", | ||||
|             { | ||||
|                 "profile.password_manager_leak_detection": False, | ||||
|             }, | ||||
|         ) | ||||
|         while count < RETRIES: | ||||
|             try: | ||||
|                 driver = webdriver.Remote( | ||||
|                     command_executor="http://localhost:4444/wd/hub", | ||||
|                     options=webdriver.ChromeOptions(), | ||||
|                     options=opts, | ||||
|                 ) | ||||
|                 driver.maximize_window() | ||||
|                 return driver | ||||
|             except WebDriverException: | ||||
|             except WebDriverException as exc: | ||||
|                 self.logger.warning("Failed to setup webdriver", exc=exc) | ||||
|                 count += 1 | ||||
|         raise ValueError(f"Webdriver failed after {RETRIES}.") | ||||
|  | ||||
|  | ||||
							
								
								
									
										502
									
								
								uv.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										502
									
								
								uv.lock
									
									
									
										generated
									
									
									
								
							| @ -13,7 +13,7 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "aiohttp" | ||||
| version = "3.11.18" | ||||
| version = "3.12.8" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "aiohappyeyeballs" }, | ||||
| @ -24,24 +24,25 @@ dependencies = [ | ||||
|     { name = "propcache" }, | ||||
|     { name = "yarl" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/63/e7/fa1a8c00e2c54b05dc8cb5d1439f627f7c267874e3f7bb047146116020f9/aiohttp-3.11.18.tar.gz", hash = "sha256:ae856e1138612b7e412db63b7708735cff4d38d0399f6a5435d3dac2669f558a", size = 7678653, upload-time = "2025-04-21T09:43:09.191Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/52/14/591553163be65a45d5b9329ae2d95d491d77cded4e1c8213d9537b78c478/aiohttp-3.12.8.tar.gz", hash = "sha256:3c0d2ca376b7cea6c1dfa1fc2479b02b3f482a249fc7020c69063b321080140a", size = 7809245, upload-time = "2025-06-04T10:06:18.411Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/0a/18/be8b5dd6b9cf1b2172301dbed28e8e5e878ee687c21947a6c81d6ceaa15d/aiohttp-3.11.18-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:474215ec618974054cf5dc465497ae9708543cbfc312c65212325d4212525811", size = 699833, upload-time = "2025-04-21T09:42:00.298Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/0d/84/ecdc68e293110e6f6f6d7b57786a77555a85f70edd2b180fb1fafaff361a/aiohttp-3.11.18-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ced70adf03920d4e67c373fd692123e34d3ac81dfa1c27e45904a628567d804", size = 462774, upload-time = "2025-04-21T09:42:02.015Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d7/85/f07718cca55884dad83cc2433746384d267ee970e91f0dcc75c6d5544079/aiohttp-3.11.18-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2d9f6c0152f8d71361905aaf9ed979259537981f47ad099c8b3d81e0319814bd", size = 454429, upload-time = "2025-04-21T09:42:03.728Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/82/02/7f669c3d4d39810db8842c4e572ce4fe3b3a9b82945fdd64affea4c6947e/aiohttp-3.11.18-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a35197013ed929c0aed5c9096de1fc5a9d336914d73ab3f9df14741668c0616c", size = 1670283, upload-time = "2025-04-21T09:42:06.053Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ec/79/b82a12f67009b377b6c07a26bdd1b81dab7409fc2902d669dbfa79e5ac02/aiohttp-3.11.18-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:540b8a1f3a424f1af63e0af2d2853a759242a1769f9f1ab053996a392bd70118", size = 1717231, upload-time = "2025-04-21T09:42:07.953Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a6/38/d5a1f28c3904a840642b9a12c286ff41fc66dfa28b87e204b1f242dbd5e6/aiohttp-3.11.18-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9e6710ebebfce2ba21cee6d91e7452d1125100f41b906fb5af3da8c78b764c1", size = 1769621, upload-time = "2025-04-21T09:42:09.855Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/53/2d/deb3749ba293e716b5714dda06e257f123c5b8679072346b1eb28b766a0b/aiohttp-3.11.18-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8af2ef3b4b652ff109f98087242e2ab974b2b2b496304063585e3d78de0b000", size = 1678667, upload-time = "2025-04-21T09:42:11.741Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b8/a8/04b6e11683a54e104b984bd19a9790eb1ae5f50968b601bb202d0406f0ff/aiohttp-3.11.18-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:28c3f975e5ae3dbcbe95b7e3dcd30e51da561a0a0f2cfbcdea30fc1308d72137", size = 1601592, upload-time = "2025-04-21T09:42:14.137Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/5e/9d/c33305ae8370b789423623f0e073d09ac775cd9c831ac0f11338b81c16e0/aiohttp-3.11.18-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c28875e316c7b4c3e745172d882d8a5c835b11018e33432d281211af35794a93", size = 1621679, upload-time = "2025-04-21T09:42:16.056Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/56/45/8e9a27fff0538173d47ba60362823358f7a5f1653c6c30c613469f94150e/aiohttp-3.11.18-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:13cd38515568ae230e1ef6919e2e33da5d0f46862943fcda74e7e915096815f3", size = 1656878, upload-time = "2025-04-21T09:42:18.368Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/84/5b/8c5378f10d7a5a46b10cb9161a3aac3eeae6dba54ec0f627fc4ddc4f2e72/aiohttp-3.11.18-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0e2a92101efb9f4c2942252c69c63ddb26d20f46f540c239ccfa5af865197bb8", size = 1620509, upload-time = "2025-04-21T09:42:20.141Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9e/2f/99dee7bd91c62c5ff0aa3c55f4ae7e1bc99c6affef780d7777c60c5b3735/aiohttp-3.11.18-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e6d3e32b8753c8d45ac550b11a1090dd66d110d4ef805ffe60fa61495360b3b2", size = 1680263, upload-time = "2025-04-21T09:42:21.993Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/03/0a/378745e4ff88acb83e2d5c884a4fe993a6e9f04600a4560ce0e9b19936e3/aiohttp-3.11.18-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ea4cf2488156e0f281f93cc2fd365025efcba3e2d217cbe3df2840f8c73db261", size = 1715014, upload-time = "2025-04-21T09:42:23.87Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f6/0b/b5524b3bb4b01e91bc4323aad0c2fcaebdf2f1b4d2eb22743948ba364958/aiohttp-3.11.18-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d4df95ad522c53f2b9ebc07f12ccd2cb15550941e11a5bbc5ddca2ca56316d7", size = 1666614, upload-time = "2025-04-21T09:42:25.764Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/c7/b7/3d7b036d5a4ed5a4c704e0754afe2eef24a824dfab08e6efbffb0f6dd36a/aiohttp-3.11.18-cp313-cp313-win32.whl", hash = "sha256:cdd1bbaf1e61f0d94aced116d6e95fe25942f7a5f42382195fd9501089db5d78", size = 411358, upload-time = "2025-04-21T09:42:27.558Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/1e/3c/143831b32cd23b5263a995b2a1794e10aa42f8a895aae5074c20fda36c07/aiohttp-3.11.18-cp313-cp313-win_amd64.whl", hash = "sha256:bdd619c27e44382cf642223f11cfd4d795161362a5a1fc1fa3940397bc89db01", size = 437658, upload-time = "2025-04-21T09:42:29.209Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/83/2d/f1661c5069c94e5236ebc94aedf3071dcdbdf3e826d768f563a79dd677bf/aiohttp-3.12.8-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:0cfe91b12a86f1a1f292f46201f8801263f1df3b843c1f9020b98e6007838918", size = 693300, upload-time = "2025-06-04T10:04:57.001Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/4f/53/c63430c4aaaf00407a2a3889182b66c9888386ae7737b11d76336f0a21d7/aiohttp-3.12.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:326396e1c174e775ac1bd49d41689128a28434d86af2d5dd9adfb211686f16c8", size = 470964, upload-time = "2025-06-04T10:04:59.007Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/8c/87/ae2ec08f33742c3cc71bcf2bdd50e2d08e0e886a13a16579243c4105abf6/aiohttp-3.12.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e0e7de9631c3163997a34d8ed55a2165e2df2ec6082dc4bd16eea92d00145c4c", size = 463265, upload-time = "2025-06-04T10:05:00.937Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/c7/35/b17b894e129176639fcfdef2d859c6602e206e032ad8b41d050899296190/aiohttp-3.12.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0759cbdca820a6a5a8562606052792ef9acb79633c3e79e6733a3c1c133d4c7d", size = 1702083, upload-time = "2025-06-04T10:05:02.988Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/58/57/c0ec6bf62c390956e6c66369abb23e3369cf5f9472744ecdbedf2c884886/aiohttp-3.12.8-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:311060ebd0832074968dd7d1b204a3b155203f7f9159c5b0908b76c5430be50f", size = 1683349, upload-time = "2025-06-04T10:05:04.978Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/45/07/288839d84b64a525e332e8e71b38de67549887aaaf7352896ab4ef7ab42e/aiohttp-3.12.8-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:268a7c20eb404e9154b77fa521f832bbfd876cf5ff7b3e0dcb744d5b46738149", size = 1735419, upload-time = "2025-06-04T10:05:06.986Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/81/1f/2db47efa2325b05869ed4eb0935ac3adee9c82689e8c43824f84979343b2/aiohttp-3.12.8-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0725406d0c512d589be41141391d11d56b447f4b56eee9bd9a17424b0e3e1d78", size = 1784790, upload-time = "2025-06-04T10:05:09.617Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/23/26/e667da558e29b30a1d758b7f0719a3be0c44bd14fb326bf3d988596075af/aiohttp-3.12.8-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a8edf6c68eb4397136591d66ce4bda8cdb47ca585948223bc98e8492d37c71f", size = 1707122, upload-time = "2025-06-04T10:05:12.113Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b0/4a/621345bcc17c7045b97b5e4374cc30e343e03f1434f710aa4c573d25d676/aiohttp-3.12.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25aa7f26286769210938a159db2f2f65d05bcc06190e34fca03eeb643f20dfc7", size = 1620825, upload-time = "2025-06-04T10:05:14.32Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/6f/08/dd7d243b2f44914d647614503c5616d1393930fef5acf74ea6da1fe0e181/aiohttp-3.12.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:952d2fa762ba6a946f3498a3a62c19dadb066539f5ac0dfa20dfe58bb8f733b5", size = 1673847, upload-time = "2025-06-04T10:05:16.357Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/2a/04/c58e5347960a385bc360678e1fee3ea021db99b0c7b83adaedf98b54e6b1/aiohttp-3.12.8-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:c2b7f82193482c7778d2de25d67dcc29a65895f5281ef177609ed4ebfb015d68", size = 1705511, upload-time = "2025-06-04T10:05:22.63Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/48/88/dd5866d495dd07ca76d97b8a90373310b3ae9d9da845a8621038a36d289b/aiohttp-3.12.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:0a99972b368e370882994a72bd2e7b2d89a886288f0ff0ea09793452865b97a3", size = 1648108, upload-time = "2025-06-04T10:05:24.775Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ed/81/151c62ec0fdeca4952ea716a197c54b36272b0dd23d202321a01e4b76997/aiohttp-3.12.8-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:ae8c65d708a473fcfa5b972a1dc6bf31257d58a07f4e4c93d0327384deab5cae", size = 1724241, upload-time = "2025-06-04T10:05:26.825Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f5/4e/578938d73e73187d835623a2902979d775b25600320244724f7fb47677ad/aiohttp-3.12.8-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:a9e0be4d239794c065e1ba439d19de7e4773b4b4b3b9849af2c3c233f3e5b3eb", size = 1757713, upload-time = "2025-06-04T10:05:29.368Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/47/c0/02c94b8d4dcc790976ef047737faa995aff1b3eaebd506d781ca43371d9c/aiohttp-3.12.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ad754910e7acce5bd52326b308ca58d404e8ba1a5bcd5a0c8607ce3dee4a1d65", size = 1706603, upload-time = "2025-06-04T10:05:31.682Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/fe/2d/6303861ebd2ac90753f0f789892c3ff841df0fcee7527cbd8e5be82c354f/aiohttp-3.12.8-cp313-cp313-win32.whl", hash = "sha256:3ca646524940dd62a96658ccc1e64dc548c633dd0468a0bf8525dd3163e2c60c", size = 419100, upload-time = "2025-06-04T10:05:34.303Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/2e/44/3ba175afa2d6d6db7cfe27136dfcd0f3c0e4c9d48dd2f3c58f955b61597f/aiohttp-3.12.8-cp313-cp313-win_amd64.whl", hash = "sha256:2f7e553bd4ff72d7e3b06ff60fc2d29457865ddb8cb7d7dc9287991c660151c5", size = 445038, upload-time = "2025-06-04T10:05:36.371Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -104,14 +105,14 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "argon2-cffi" | ||||
| version = "23.1.0" | ||||
| version = "25.1.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "argon2-cffi-bindings" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798, upload-time = "2023-08-15T14:13:12.711Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706, upload-time = "2025-06-03T06:55:32.073Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124, upload-time = "2023-08-15T14:13:10.752Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657, upload-time = "2025-06-03T06:55:30.804Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -164,7 +165,7 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "authentik" | ||||
| version = "2025.4.1" | ||||
| version = "2025.6.0" | ||||
| source = { editable = "." } | ||||
| dependencies = [ | ||||
|     { name = "argon2-cffi" }, | ||||
| @ -265,8 +266,8 @@ dev = [ | ||||
|  | ||||
| [package.metadata] | ||||
| requires-dist = [ | ||||
|     { name = "argon2-cffi", specifier = "==23.1.0" }, | ||||
|     { name = "celery", specifier = "==5.5.2" }, | ||||
|     { name = "argon2-cffi", specifier = "==25.1.0" }, | ||||
|     { name = "celery", specifier = "==5.5.3" }, | ||||
|     { name = "channels", specifier = "==4.2.2" }, | ||||
|     { name = "channels-redis", specifier = "==4.2.1" }, | ||||
|     { name = "cryptography", specifier = "==45.0.3" }, | ||||
| @ -295,7 +296,7 @@ requires-dist = [ | ||||
|     { name = "flower", specifier = "==2.0.1" }, | ||||
|     { name = "geoip2", specifier = "==5.1.0" }, | ||||
|     { name = "geopy", specifier = "==2.4.1" }, | ||||
|     { name = "google-api-python-client", specifier = "==2.170.0" }, | ||||
|     { name = "google-api-python-client", specifier = "==2.171.0" }, | ||||
|     { name = "gssapi", specifier = "==1.9.0" }, | ||||
|     { name = "gunicorn", specifier = "==23.0.0" }, | ||||
|     { name = "jsonpatch", specifier = "==1.33" }, | ||||
| @ -303,7 +304,7 @@ requires-dist = [ | ||||
|     { name = "kubernetes", specifier = "==32.0.1" }, | ||||
|     { name = "ldap3", specifier = "==2.9.1" }, | ||||
|     { name = "lxml", specifier = "==5.4.0" }, | ||||
|     { name = "msgraph-sdk", specifier = "==1.30.0" }, | ||||
|     { name = "msgraph-sdk", specifier = "==1.32.0" }, | ||||
|     { name = "opencontainers", git = "https://github.com/vsoch/oci-python?rev=ceb4fcc090851717a3069d78e85ceb1e86c2740c" }, | ||||
|     { name = "packaging", specifier = "==25.0" }, | ||||
|     { name = "paramiko", specifier = "==3.5.1" }, | ||||
| @ -319,14 +320,14 @@ requires-dist = [ | ||||
|     { name = "sentry-sdk", specifier = "==2.29.1" }, | ||||
|     { name = "service-identity", specifier = "==24.2.0" }, | ||||
|     { name = "setproctitle", specifier = "==1.3.6" }, | ||||
|     { name = "structlog", specifier = "==25.3.0" }, | ||||
|     { name = "structlog", specifier = "==25.4.0" }, | ||||
|     { name = "swagger-spec-validator", specifier = "==3.0.4" }, | ||||
|     { name = "tenant-schemas-celery", specifier = "==4.0.1" }, | ||||
|     { name = "twilio", specifier = "==9.6.1" }, | ||||
|     { name = "twilio", specifier = "==9.6.2" }, | ||||
|     { name = "ua-parser", specifier = "==1.0.1" }, | ||||
|     { name = "unidecode", specifier = "==1.4.0" }, | ||||
|     { name = "urllib3", specifier = "<3" }, | ||||
|     { name = "uvicorn", extras = ["standard"], specifier = "==0.34.2" }, | ||||
|     { name = "uvicorn", extras = ["standard"], specifier = "==0.34.3" }, | ||||
|     { name = "watchdog", specifier = "==6.0.0" }, | ||||
|     { name = "webauthn", specifier = "==2.5.2" }, | ||||
|     { name = "wsproto", specifier = "==1.2.0" }, | ||||
| @ -461,7 +462,7 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "azure-identity" | ||||
| version = "1.22.0" | ||||
| version = "1.23.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "azure-core" }, | ||||
| @ -470,9 +471,9 @@ dependencies = [ | ||||
|     { name = "msal-extensions" }, | ||||
|     { name = "typing-extensions" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/58/8e/1b5916f5e1696bf05b009cf7d41383cea54aa8536d4a4f6f88cca15eb6a4/azure_identity-1.22.0.tar.gz", hash = "sha256:c8f5ef23e5295c2fa300c984dd9f5e1fe43503fc25c121c37ff6a15e39b800b9", size = 263346, upload-time = "2025-05-06T20:22:24.13Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/41/52/458c1be17a5d3796570ae2ed3c6b7b55b134b22d5ef8132b4f97046a9051/azure_identity-1.23.0.tar.gz", hash = "sha256:d9cdcad39adb49d4bb2953a217f62aec1f65bbb3c63c9076da2be2a47e53dde4", size = 265280, upload-time = "2025-05-14T00:18:30.408Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/06/1a/6f13d7f95f68f37303c0e00e011d498e4524e70d354b2e11ef5ae89e0ce0/azure_identity-1.22.0-py3-none-any.whl", hash = "sha256:26d6c63f2ca453c77c3e74be8613941ad074e05d0c8be135247573752c249ad8", size = 185524, upload-time = "2025-05-06T20:22:25.991Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/07/16/a51d47780f41e4b87bb2d454df6aea90a44a346e918ac189d3700f3d728d/azure_identity-1.23.0-py3-none-any.whl", hash = "sha256:dbbeb64b8e5eaa81c44c565f264b519ff2de7ff0e02271c49f3cb492762a50b0", size = 186097, upload-time = "2025-05-14T00:18:32.734Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -571,30 +572,30 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "boto3" | ||||
| version = "1.38.13" | ||||
| version = "1.38.29" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "botocore" }, | ||||
|     { name = "jmespath" }, | ||||
|     { name = "s3transfer" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/c7/89/a47f62b3f81a2e3484d2a2b8dd4906c5b6e57da0af0bd59d36f99ba20baf/boto3-1.38.13.tar.gz", hash = "sha256:6633bce2b73284acce1453ca85834c7c5a59e0dbcce1170be461cc079bdcdfcf", size = 111812, upload-time = "2025-05-09T19:33:02.962Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/15/d2/e7286b4ffd3138eb13caaa0f611c2e291f7c6b14ae56bf087ce213c54dc4/boto3-1.38.29.tar.gz", hash = "sha256:0777a87e8d28ebae09a086017a53bcaf25ec7c094d8f7e4122b265aa48e273f5", size = 111867, upload-time = "2025-06-03T19:23:00.714Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/72/25/79e219648f10d060d152542fcf3be0093120471774b99c1a7f41ceaeca9b/boto3-1.38.13-py3-none-any.whl", hash = "sha256:668400d13889d2d2fcd66ce785cc0b0fc040681f58a9c7f67daa9149a52b6c63", size = 139934, upload-time = "2025-05-09T19:33:00.855Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/1b/2e/b96b9fbed3007e67bc624c42103b47e7bd10380ed46bbbd25a1755227f7c/boto3-1.38.29-py3-none-any.whl", hash = "sha256:90a9b1a08122b840216b0e33b7b0dbe4ef50f12d00a573bf7b030cddeda9c507", size = 139939, upload-time = "2025-06-03T19:22:57.33Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "botocore" | ||||
| version = "1.38.13" | ||||
| version = "1.38.29" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "jmespath" }, | ||||
|     { name = "python-dateutil" }, | ||||
|     { name = "urllib3" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/de/36/5b0faba074684744244e1e030e73fd5612bc2c38f557eec0a7f1a3d7ddd2/botocore-1.38.13.tar.gz", hash = "sha256:22feee15753cd3f9f7179d041604078a1024701497d27b22be7c6707e8d13ccb", size = 13882010, upload-time = "2025-05-09T19:32:51.172Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/32/9a/8c3ec27698910c1b94152f9e7a345d4c6c2f49dfc41d8336f82e32c32ed1/botocore-1.38.29.tar.gz", hash = "sha256:98c42b1bbb52f4086282e7db8aa724c9cb0f7278b7827d6736d872511c856e4f", size = 13929364, upload-time = "2025-06-03T19:22:48.425Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/94/df/a7a8097471d5a3bc7d408850222292d874ffc190aef7e1cacf9af770339e/botocore-1.38.13-py3-none-any.whl", hash = "sha256:de29fee43a1f02787fb5b3756ec09917d5661ed95b2b2d64797ab04196f69e14", size = 13544507, upload-time = "2025-05-09T19:32:37.727Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/14/7a/03482cd3c00008d9be646c8e1520611d6202ce447db725ac40b07f9b088a/botocore-1.38.29-py3-none-any.whl", hash = "sha256:4d623f54326eb66d1a633f0c1780992c80f3db317a91c9afe31d5c700290621e", size = 13588258, upload-time = "2025-06-03T19:22:45.14Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -645,7 +646,7 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "celery" | ||||
| version = "5.5.2" | ||||
| version = "5.5.3" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "billiard" }, | ||||
| @ -657,9 +658,9 @@ dependencies = [ | ||||
|     { name = "python-dateutil" }, | ||||
|     { name = "vine" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/bf/03/5d9c6c449248958f1a5870e633a29d7419ff3724c452a98ffd22688a1a6a/celery-5.5.2.tar.gz", hash = "sha256:4d6930f354f9d29295425d7a37261245c74a32807c45d764bedc286afd0e724e", size = 1666892, upload-time = "2025-04-25T20:10:04.695Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/bb/7d/6c289f407d219ba36d8b384b42489ebdd0c84ce9c413875a8aae0c85f35b/celery-5.5.3.tar.gz", hash = "sha256:6c972ae7968c2b5281227f01c3a3f984037d21c5129d07bf3550cc2afc6b10a5", size = 1667144, upload-time = "2025-06-01T11:08:12.563Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/04/94/8e825ac1cf59d45d20c4345d4461e6b5263ae475f708d047c3dad0ac6401/celery-5.5.2-py3-none-any.whl", hash = "sha256:54425a067afdc88b57cd8d94ed4af2ffaf13ab8c7680041ac2c4ac44357bdf4c", size = 438626, upload-time = "2025-04-25T20:10:01.383Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/c9/af/0dcccc7fdcdf170f9a1585e5e96b6fb0ba1749ef6be8c89a6202284759bd/celery-5.5.3-py3-none-any.whl", hash = "sha256:0b5761a07057acee94694464ca482416b959568904c9dfa41ce8413a7d65d525", size = 438775, upload-time = "2025-06-01T11:08:09.94Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -750,14 +751,14 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "click" | ||||
| version = "8.2.0" | ||||
| version = "8.2.1" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "colorama", marker = "sys_platform == 'win32'" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/cd/0f/62ca20172d4f87d93cf89665fbaedcd560ac48b465bd1d92bfc7ea6b0a41/click-8.2.0.tar.gz", hash = "sha256:f5452aeddd9988eefa20f90f05ab66f17fce1ee2a36907fd30b05bbb5953814d", size = 235857, upload-time = "2025-05-10T22:21:03.111Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/a2/58/1f37bf81e3c689cc74ffa42102fa8915b59085f54a6e4a80bc6265c0f6bf/click-8.2.0-py3-none-any.whl", hash = "sha256:6b303f0b2aa85f1cb4e5303078fadcbcd4e476f114fab9b5007005711839325c", size = 102156, upload-time = "2025-05-10T22:21:01.352Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -913,16 +914,16 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "daphne" | ||||
| version = "4.1.2" | ||||
| version = "4.2.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "asgiref" }, | ||||
|     { name = "autobahn" }, | ||||
|     { name = "twisted", extra = ["tls"] }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/1a/c1/aedf180beb12395835cba791ce7239b8880009d9d37564d72b7590cde605/daphne-4.1.2.tar.gz", hash = "sha256:fcbcace38eb86624ae247c7ffdc8ac12f155d7d19eafac4247381896d6f33761", size = 37882, upload-time = "2024-04-11T13:32:34.594Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/e9/fa/88208e036d1a000cc99eed11a5ddae2397a39d89c44ac22a3c35a58eb951/daphne-4.2.0.tar.gz", hash = "sha256:c055de9e685cab7aa369e25e16731baa9b310b9db1a76886dbdde0b4456fb056", size = 45302, upload-time = "2025-05-16T14:46:48.422Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/ab/d6/466f9219281472ecc269ab1d351c5b22a3cfca2d52f72881917949e414df/daphne-4.1.2-py3-none-any.whl", hash = "sha256:618d1322bb4d875342b99dd2a10da2d9aae7ee3645f765965fdc1e658ea5290a", size = 30940, upload-time = "2024-04-11T13:32:32.634Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/4a/ad/b00755d09a1ec080ad5fe0d5a6e609f9e4441755204a16c17cc7a07f80f6/daphne-4.2.0-py3-none-any.whl", hash = "sha256:ccc7a476c498272237e27758a02aff11c76ab777c4e20b9b6c141729db599d5d", size = 28493, upload-time = "2025-05-16T14:46:46.859Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -965,18 +966,6 @@ wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "deprecated" | ||||
| version = "1.2.18" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "wrapt" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/98/97/06afe62762c9a8a86af0cfb7bfdab22a43ad17138b07af5b1a58442690a2/deprecated-1.2.18.tar.gz", hash = "sha256:422b6f6d859da6f2ef57857761bfb392480502a64c3028ca9bbe86085d72115d", size = 2928744, upload-time = "2025-01-27T10:46:25.7Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec", size = 9998, upload-time = "2025-01-27T10:46:09.186Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "django" | ||||
| version = "5.1.9" | ||||
| @ -1241,11 +1230,11 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "durationpy" | ||||
| version = "0.9" | ||||
| version = "0.10" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/31/e9/f49c4e7fccb77fa5c43c2480e09a857a78b41e7331a75e128ed5df45c56b/durationpy-0.9.tar.gz", hash = "sha256:fd3feb0a69a0057d582ef643c355c40d2fa1c942191f914d12203b1a01ac722a", size = 3186, upload-time = "2024-10-02T17:59:00.873Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/9d/a4/e44218c2b394e31a6dd0d6b095c4e1f32d0be54c2a4b250032d717647bab/durationpy-0.10.tar.gz", hash = "sha256:1fa6893409a6e739c9c72334fc65cca1f355dbdd93405d30f726deb5bde42fba", size = 3335, upload-time = "2025-05-17T13:52:37.26Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/4c/a3/ac312faeceffd2d8f86bc6dcb5c401188ba5a01bc88e69bed97578a0dfcd/durationpy-0.9-py3-none-any.whl", hash = "sha256:e65359a7af5cedad07fb77a2dd3f390f8eb0b74cb845589fa6c057086834dd38", size = 3461, upload-time = "2024-10-02T17:58:59.349Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b0/0d/9feae160378a3553fa9a339b0e9c1a048e147a4127210e286ef18b730f03/durationpy-0.10-py3-none-any.whl", hash = "sha256:3b41e1b601234296b4fb368338fdcd3e13e0b4fb5b67345948f4f2bf9868b286", size = 3922, upload-time = "2025-05-17T13:52:36.463Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -1303,45 +1292,45 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "frozenlist" | ||||
| version = "1.6.0" | ||||
| version = "1.6.2" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/ee/f4/d744cba2da59b5c1d88823cf9e8a6c74e4659e2b27604ed973be2a0bf5ab/frozenlist-1.6.0.tar.gz", hash = "sha256:b99655c32c1c8e06d111e7f41c06c29a5318cb1835df23a45518e02a47c63b68", size = 42831, upload-time = "2025-04-17T22:38:53.099Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/5b/bf/a812e2fe6cb3f6c6cfc8d0303bf1742f2286004e5ec41ac8c89cf68cdb54/frozenlist-1.6.2.tar.gz", hash = "sha256:effc641518696471cf4962e8e32050133bc1f7b2851ae8fd0cb8797dd70dc202", size = 43108, upload-time = "2025-06-03T21:48:04.467Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/6f/e5/04c7090c514d96ca00887932417f04343ab94904a56ab7f57861bf63652d/frozenlist-1.6.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1d7fb014fe0fbfee3efd6a94fc635aeaa68e5e1720fe9e57357f2e2c6e1a647e", size = 158182, upload-time = "2025-04-17T22:37:16.837Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e9/8f/60d0555c61eec855783a6356268314d204137f5e0c53b59ae2fc28938c99/frozenlist-1.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01bcaa305a0fdad12745502bfd16a1c75b14558dabae226852f9159364573117", size = 122838, upload-time = "2025-04-17T22:37:18.352Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/5a/a7/d0ec890e3665b4b3b7c05dc80e477ed8dc2e2e77719368e78e2cd9fec9c8/frozenlist-1.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8b314faa3051a6d45da196a2c495e922f987dc848e967d8cfeaee8a0328b1cd4", size = 120980, upload-time = "2025-04-17T22:37:19.857Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/cc/19/9b355a5e7a8eba903a008579964192c3e427444752f20b2144b10bb336df/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da62fecac21a3ee10463d153549d8db87549a5e77eefb8c91ac84bb42bb1e4e3", size = 305463, upload-time = "2025-04-17T22:37:21.328Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9c/8d/5b4c758c2550131d66935ef2fa700ada2461c08866aef4229ae1554b93ca/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1eb89bf3454e2132e046f9599fbcf0a4483ed43b40f545551a39316d0201cd1", size = 297985, upload-time = "2025-04-17T22:37:23.55Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/48/2c/537ec09e032b5865715726b2d1d9813e6589b571d34d01550c7aeaad7e53/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18689b40cb3936acd971f663ccb8e2589c45db5e2c5f07e0ec6207664029a9c", size = 311188, upload-time = "2025-04-17T22:37:25.221Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/31/2f/1aa74b33f74d54817055de9a4961eff798f066cdc6f67591905d4fc82a84/frozenlist-1.6.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e67ddb0749ed066b1a03fba812e2dcae791dd50e5da03be50b6a14d0c1a9ee45", size = 311874, upload-time = "2025-04-17T22:37:26.791Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/bf/f0/cfec18838f13ebf4b37cfebc8649db5ea71a1b25dacd691444a10729776c/frozenlist-1.6.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc5e64626e6682638d6e44398c9baf1d6ce6bc236d40b4b57255c9d3f9761f1f", size = 291897, upload-time = "2025-04-17T22:37:28.958Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ea/a5/deb39325cbbea6cd0a46db8ccd76150ae2fcbe60d63243d9df4a0b8c3205/frozenlist-1.6.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:437cfd39564744ae32ad5929e55b18ebd88817f9180e4cc05e7d53b75f79ce85", size = 305799, upload-time = "2025-04-17T22:37:30.889Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/78/22/6ddec55c5243a59f605e4280f10cee8c95a449f81e40117163383829c241/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:62dd7df78e74d924952e2feb7357d826af8d2f307557a779d14ddf94d7311be8", size = 302804, upload-time = "2025-04-17T22:37:32.489Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/5d/b7/d9ca9bab87f28855063c4d202936800219e39db9e46f9fb004d521152623/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a66781d7e4cddcbbcfd64de3d41a61d6bdde370fc2e38623f30b2bd539e84a9f", size = 316404, upload-time = "2025-04-17T22:37:34.59Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a6/3a/1255305db7874d0b9eddb4fe4a27469e1fb63720f1fc6d325a5118492d18/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:482fe06e9a3fffbcd41950f9d890034b4a54395c60b5e61fae875d37a699813f", size = 295572, upload-time = "2025-04-17T22:37:36.337Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/2a/f2/8d38eeee39a0e3a91b75867cc102159ecccf441deb6ddf67be96d3410b84/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e4f9373c500dfc02feea39f7a56e4f543e670212102cc2eeb51d3a99c7ffbde6", size = 307601, upload-time = "2025-04-17T22:37:37.923Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/38/04/80ec8e6b92f61ef085422d7b196822820404f940950dde5b2e367bede8bc/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e69bb81de06827147b7bfbaeb284d85219fa92d9f097e32cc73675f279d70188", size = 314232, upload-time = "2025-04-17T22:37:39.669Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/3a/58/93b41fb23e75f38f453ae92a2f987274c64637c450285577bd81c599b715/frozenlist-1.6.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7613d9977d2ab4a9141dde4a149f4357e4065949674c5649f920fec86ecb393e", size = 308187, upload-time = "2025-04-17T22:37:41.662Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/6a/a2/e64df5c5aa36ab3dee5a40d254f3e471bb0603c225f81664267281c46a2d/frozenlist-1.6.0-cp313-cp313-win32.whl", hash = "sha256:4def87ef6d90429f777c9d9de3961679abf938cb6b7b63d4a7eb8a268babfce4", size = 114772, upload-time = "2025-04-17T22:37:43.132Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a0/77/fead27441e749b2d574bb73d693530d59d520d4b9e9679b8e3cb779d37f2/frozenlist-1.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:37a8a52c3dfff01515e9bbbee0e6063181362f9de3db2ccf9bc96189b557cbfd", size = 119847, upload-time = "2025-04-17T22:37:45.118Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/df/bd/cc6d934991c1e5d9cafda83dfdc52f987c7b28343686aef2e58a9cf89f20/frozenlist-1.6.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:46138f5a0773d064ff663d273b309b696293d7a7c00a0994c5c13a5078134b64", size = 174937, upload-time = "2025-04-17T22:37:46.635Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f2/a2/daf945f335abdbfdd5993e9dc348ef4507436936ab3c26d7cfe72f4843bf/frozenlist-1.6.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:f88bc0a2b9c2a835cb888b32246c27cdab5740059fb3688852bf91e915399b91", size = 136029, upload-time = "2025-04-17T22:37:48.192Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/51/65/4c3145f237a31247c3429e1c94c384d053f69b52110a0d04bfc8afc55fb2/frozenlist-1.6.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:777704c1d7655b802c7850255639672e90e81ad6fa42b99ce5ed3fbf45e338dd", size = 134831, upload-time = "2025-04-17T22:37:50.485Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/77/38/03d316507d8dea84dfb99bdd515ea245628af964b2bf57759e3c9205cc5e/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85ef8d41764c7de0dcdaf64f733a27352248493a85a80661f3c678acd27e31f2", size = 392981, upload-time = "2025-04-17T22:37:52.558Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/37/02/46285ef9828f318ba400a51d5bb616ded38db8466836a9cfa39f3903260b/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:da5cb36623f2b846fb25009d9d9215322318ff1c63403075f812b3b2876c8506", size = 371999, upload-time = "2025-04-17T22:37:54.092Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/0d/64/1212fea37a112c3c5c05bfb5f0a81af4836ce349e69be75af93f99644da9/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cbb56587a16cf0fb8acd19e90ff9924979ac1431baea8681712716a8337577b0", size = 392200, upload-time = "2025-04-17T22:37:55.951Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/81/ce/9a6ea1763e3366e44a5208f76bf37c76c5da570772375e4d0be85180e588/frozenlist-1.6.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6154c3ba59cda3f954c6333025369e42c3acd0c6e8b6ce31eb5c5b8116c07e0", size = 390134, upload-time = "2025-04-17T22:37:57.633Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/bc/36/939738b0b495b2c6d0c39ba51563e453232813042a8d908b8f9544296c29/frozenlist-1.6.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e8246877afa3f1ae5c979fe85f567d220f86a50dc6c493b9b7d8191181ae01e", size = 365208, upload-time = "2025-04-17T22:37:59.742Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b4/8b/939e62e93c63409949c25220d1ba8e88e3960f8ef6a8d9ede8f94b459d27/frozenlist-1.6.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b0f6cce16306d2e117cf9db71ab3a9e8878a28176aeaf0dbe35248d97b28d0c", size = 385548, upload-time = "2025-04-17T22:38:01.416Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/62/38/22d2873c90102e06a7c5a3a5b82ca47e393c6079413e8a75c72bff067fa8/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:1b8e8cd8032ba266f91136d7105706ad57770f3522eac4a111d77ac126a25a9b", size = 391123, upload-time = "2025-04-17T22:38:03.049Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/44/78/63aaaf533ee0701549500f6d819be092c6065cb5c577edb70c09df74d5d0/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:e2ada1d8515d3ea5378c018a5f6d14b4994d4036591a52ceaf1a1549dec8e1ad", size = 394199, upload-time = "2025-04-17T22:38:04.776Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/54/45/71a6b48981d429e8fbcc08454dc99c4c2639865a646d549812883e9c9dd3/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:cdb2c7f071e4026c19a3e32b93a09e59b12000751fc9b0b7758da899e657d215", size = 373854, upload-time = "2025-04-17T22:38:06.576Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/3f/f3/dbf2a5e11736ea81a66e37288bf9f881143a7822b288a992579ba1b4204d/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:03572933a1969a6d6ab509d509e5af82ef80d4a5d4e1e9f2e1cdd22c77a3f4d2", size = 395412, upload-time = "2025-04-17T22:38:08.197Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b3/f1/c63166806b331f05104d8ea385c4acd511598568b1f3e4e8297ca54f2676/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:77effc978947548b676c54bbd6a08992759ea6f410d4987d69feea9cd0919911", size = 394936, upload-time = "2025-04-17T22:38:10.056Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ef/ea/4f3e69e179a430473eaa1a75ff986526571215fefc6b9281cdc1f09a4eb8/frozenlist-1.6.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a2bda8be77660ad4089caf2223fdbd6db1858462c4b85b67fbfa22102021e497", size = 391459, upload-time = "2025-04-17T22:38:11.826Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d3/c3/0fc2c97dea550df9afd072a37c1e95421652e3206bbeaa02378b24c2b480/frozenlist-1.6.0-cp313-cp313t-win32.whl", hash = "sha256:a4d96dc5bcdbd834ec6b0f91027817214216b5b30316494d2b1aebffb87c534f", size = 128797, upload-time = "2025-04-17T22:38:14.013Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ae/f5/79c9320c5656b1965634fe4be9c82b12a3305bdbc58ad9cb941131107b20/frozenlist-1.6.0-cp313-cp313t-win_amd64.whl", hash = "sha256:e18036cb4caa17ea151fd5f3d70be9d354c99eb8cf817a3ccde8a7873b074348", size = 134709, upload-time = "2025-04-17T22:38:15.551Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/71/3e/b04a0adda73bd52b390d730071c0d577073d3d26740ee1bad25c3ad0f37b/frozenlist-1.6.0-py3-none-any.whl", hash = "sha256:535eec9987adb04701266b92745d6cdcef2e77669299359c3009c3404dd5d191", size = 12404, upload-time = "2025-04-17T22:38:51.668Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b8/f6/973abfcb8b68f2e8b58071a04ec72f5e1f0acd19dae0d3b7a8abc3d9ab07/frozenlist-1.6.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2ad8851ae1f6695d735f8646bf1e68675871789756f7f7e8dc8224a74eabb9d0", size = 85517, upload-time = "2025-06-03T21:46:42.124Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/c8/d0/ac45f2dcf0afd5f7d57204af8b7516ecbc3599ea681e06f4b25d3845bea8/frozenlist-1.6.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:cd2d5abc0ccd99a2a5b437987f3b1e9c265c1044d2855a09ac68f09bbb8082ca", size = 49916, upload-time = "2025-06-03T21:46:43.93Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/50/cc/99c3f31823630b7411f7c1e83399e91d6b56a5661a5b724935ef5b51f5f5/frozenlist-1.6.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:15c33f665faa9b8f8e525b987eeaae6641816e0f6873e8a9c4d224338cebbb55", size = 48107, upload-time = "2025-06-03T21:46:45.188Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/85/4e/38643ce3ee80d222892b694d02c15ea476c4d564493a6fe530347163744e/frozenlist-1.6.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3e6c0681783723bb472b6b8304e61ecfcb4c2b11cf7f243d923813c21ae5d2a", size = 255771, upload-time = "2025-06-03T21:46:46.53Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ca/e6/ceed85a7d5c0f666485384fc393e32353f8088e154a1109e5ef60165d366/frozenlist-1.6.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:61bae4d345a26550d0ed9f2c9910ea060f89dbfc642b7b96e9510a95c3a33b3c", size = 252519, upload-time = "2025-06-03T21:46:48.101Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/29/99/9f2e2b90cf918465e3b6ca4eea79e6be53d24fba33937e37d86c3764bbf9/frozenlist-1.6.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90e5a84016d0d2fb828f770ede085b5d89155fcb9629b8a3237c960c41c120c3", size = 263348, upload-time = "2025-06-03T21:46:49.64Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/4e/ac/59f3ec4c1b4897186efb4757379915734a48bb16bbc15a9fe0bf0857b679/frozenlist-1.6.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55dc289a064c04819d669e6e8a85a1c0416e6c601782093bdc749ae14a2f39da", size = 257858, upload-time = "2025-06-03T21:46:51.189Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/48/4a/19c97510d0c2be1ebaae68383d1b5a256a12a660ca17b0c427b1024d9b92/frozenlist-1.6.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b79bcf97ca03c95b044532a4fef6e5ae106a2dd863875b75fde64c553e3f4820", size = 238248, upload-time = "2025-06-03T21:46:52.649Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ef/64/641aa2b0944fa3d881323948e0d8d6fee746dae03d9023eb510bb80bc46a/frozenlist-1.6.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e5e7564d232a782baa3089b25a0d979e2e4d6572d3c7231fcceacc5c22bf0f7", size = 255932, upload-time = "2025-06-03T21:46:54.175Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/6c/f8/5b68d5658fac7332e5d26542a4af0ffc2edca8da8f854f6274882889ee1e/frozenlist-1.6.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6fcd8d56880dccdd376afb18f483ab55a0e24036adc9a83c914d4b7bb5729d4e", size = 253329, upload-time = "2025-06-03T21:46:55.69Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e9/20/379d7a27eb82748b41319bf376bf2c034e7ee11dda94f12b331edcc261ff/frozenlist-1.6.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4fbce985c7fe7bafb4d9bf647c835dbe415b465a897b0c79d1bdf0f3fae5fe50", size = 266164, upload-time = "2025-06-03T21:46:57.19Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/13/bd/d7dbf94220020850392cb661bedfdf786398bafae85d1045dd108971d261/frozenlist-1.6.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3bd12d727cd616387d50fe283abebb2db93300c98f8ff1084b68460acd551926", size = 241641, upload-time = "2025-06-03T21:46:59.769Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a4/70/916fef6284d294077265cd69ad05f228e44f7ed88d9acb690df5a1174049/frozenlist-1.6.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:38544cae535ed697960891131731b33bb865b7d197ad62dc380d2dbb1bceff48", size = 261215, upload-time = "2025-06-03T21:47:01.752Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/8f/98/1326a7189fa519692698cddf598f56766b0fea6ac71cddaf64760a055397/frozenlist-1.6.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:47396898f98fae5c9b9bb409c3d2cf6106e409730f35a0926aad09dd7acf1ef5", size = 262597, upload-time = "2025-06-03T21:47:03.495Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f4/d6/0a95ab9289c72e86c37c9b8afe82576556456b6f66a35d242526634130f2/frozenlist-1.6.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d10d835f8ce8571fd555db42d3aef325af903535dad7e6faa7b9c8abe191bffc", size = 258766, upload-time = "2025-06-03T21:47:05.411Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/1b/d0/9e946aabd89ebfcb71ec1371327f0e25d4868cd4439471a6fcb6eaf7b366/frozenlist-1.6.2-cp313-cp313-win32.whl", hash = "sha256:a400fe775a41b6d7a3fef00d88f10cbae4f0074c9804e282013d7797671ba58d", size = 40961, upload-time = "2025-06-03T21:47:06.89Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/43/e9/d714f5eb0fde1413344ded982ae9638307b59651d5c04263af42eb81a315/frozenlist-1.6.2-cp313-cp313-win_amd64.whl", hash = "sha256:cc8b25b321863ed46992558a29bb09b766c41e25f31461666d501be0f893bada", size = 46204, upload-time = "2025-06-03T21:47:08.2Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f5/7a/8f6dde73862499e60eb390778a1e46b87c1fe3c5722622d731ccda7a173c/frozenlist-1.6.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:56de277a0e0ad26a1dcdc99802b4f5becd7fd890807b68e3ecff8ced01d58132", size = 91326, upload-time = "2025-06-03T21:47:09.566Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/79/60/dcdc75edbcf8241e7cb15fced68b3be63f67ff3faaf559c540a7eb63233b/frozenlist-1.6.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:9cb386dd69ae91be586aa15cb6f39a19b5f79ffc1511371eca8ff162721c4867", size = 52426, upload-time = "2025-06-03T21:47:10.828Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/64/e6/df2a43ccb2c4f1ea3692aae9a89cfc5dd932a90b7898f98f13ed9e2680a9/frozenlist-1.6.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:53835d8a6929c2f16e02616f8b727bd140ce8bf0aeddeafdb290a67c136ca8ad", size = 51460, upload-time = "2025-06-03T21:47:12.089Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/fd/b3/c4f2f7fca9487b25c39bf64535f029316e184072a82f3660ce72defc5421/frozenlist-1.6.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc49f2277e8173abf028d744f8b7d69fe8cc26bffc2de97d47a3b529599fbf50", size = 310270, upload-time = "2025-06-03T21:47:13.495Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/2b/5b/046eb34d8d0fee1a8c9dc91a9ba581283c67a1ace20bcc01c86a53595105/frozenlist-1.6.2-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:65eb9e8a973161bdac5fa06ea6bd261057947adc4f47a7a6ef3d6db30c78c5b4", size = 289062, upload-time = "2025-06-03T21:47:14.92Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/48/7b/80991efaa0aa25e867cf93033c28e9d1310f34f90421eb59eb1f2073d937/frozenlist-1.6.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:301eb2f898d863031f8c5a56c88a6c5d976ba11a4a08a1438b96ee3acb5aea80", size = 312202, upload-time = "2025-06-03T21:47:16.436Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/78/6b/6fe30bdababdf82c5b34f0093770c4be6211071e23570721b80b11c9d52a/frozenlist-1.6.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:207f717fd5e65fddb77d33361ab8fa939f6d89195f11307e073066886b33f2b8", size = 309557, upload-time = "2025-06-03T21:47:17.939Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9d/ef/b7bf48802fc7d084703ba2173e6a8d0590bea378dcd6a480051c41bddf47/frozenlist-1.6.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f83992722642ee0db0333b1dbf205b1a38f97d51a7382eb304ba414d8c3d1e05", size = 282135, upload-time = "2025-06-03T21:47:19.521Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/af/f8/6911a085bce8d0d0df3dfc2560e3e0fb4d6c19ff101014bcf61aa32ba39a/frozenlist-1.6.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12af99e6023851b36578e5bcc60618b5b30f4650340e29e565cd1936326dbea7", size = 303392, upload-time = "2025-06-03T21:47:21.16Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9c/5d/b4e0cc6dbd6b9282926a470a919da7c6599ff324ab5268c7ecaff82cb858/frozenlist-1.6.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6f01620444a674eaad900a3263574418e99c49e2a5d6e5330753857363b5d59f", size = 309402, upload-time = "2025-06-03T21:47:22.705Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/0f/1b/bf777de3c810e68e8758337fcc97ee8c956376c87aecee9a61ba19a94123/frozenlist-1.6.2-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:82b94c8948341512306ca8ccc702771600b442c6abe5f8ee017e00e452a209e8", size = 312924, upload-time = "2025-06-03T21:47:24.251Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/0e/03/a69b890bc310790fcae61fd3b5be64876811b12db5d50b32e62f65e766bd/frozenlist-1.6.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:324a4cf4c220ddb3db1f46ade01e48432c63fa8c26812c710006e7f6cfba4a08", size = 291768, upload-time = "2025-06-03T21:47:25.874Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/70/cc/559386adf987b47c8977c929271d11a72efd92778a0a2f4cc97827a9a25b/frozenlist-1.6.2-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:695284e51458dabb89af7f7dc95c470aa51fd259207aba5378b187909297feef", size = 313305, upload-time = "2025-06-03T21:47:29.305Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e7/fa/eb0e21730ffccfb2d0d367d863cbaacf8367bdc277b44eabf72f7329ab91/frozenlist-1.6.2-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:9ccbeb1c8dda4f42d0678076aa5cbde941a232be71c67b9d8ca89fbaf395807c", size = 312228, upload-time = "2025-06-03T21:47:30.967Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d1/c1/8471b67172abc9478ad78c70a3f3a5c4fed6d4bcadc748e1b6dfa06ab2ae/frozenlist-1.6.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cbbdf62fcc1864912c592a1ec748fee94f294c6b23215d5e8e9569becb7723ee", size = 309905, upload-time = "2025-06-03T21:47:32.526Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/bb/2c/ee21987c3a175b49d0b827b1e45394a7a5d08c7de5b766ed6d0889d30568/frozenlist-1.6.2-cp313-cp313t-win32.whl", hash = "sha256:76857098ee17258df1a61f934f2bae052b8542c9ea6b187684a737b2e3383a65", size = 44644, upload-time = "2025-06-03T21:47:34.514Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/65/46/fce60f65b1fb17a90c4bf410a5c90cb3b40616cc229e75866f8be97c112c/frozenlist-1.6.2-cp313-cp313t-win_amd64.whl", hash = "sha256:c06a88daba7e891add42f9278cdf7506a49bc04df9b1648be54da1bf1c79b4c6", size = 50607, upload-time = "2025-06-03T21:47:36.227Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/13/be/0ebbb283f2d91b72beaee2d07760b2c47dab875c49c286f5591d3d157198/frozenlist-1.6.2-py3-none-any.whl", hash = "sha256:947abfcc8c42a329bbda6df97a4b9c9cdb4e12c85153b3b57b9d2f02aa5877dc", size = 12582, upload-time = "2025-06-03T21:48:03.201Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -1381,7 +1370,7 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "google-api-core" | ||||
| version = "2.24.2" | ||||
| version = "2.25.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "google-auth" }, | ||||
| @ -1390,14 +1379,14 @@ dependencies = [ | ||||
|     { name = "protobuf" }, | ||||
|     { name = "requests" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/09/5c/085bcb872556934bb119e5e09de54daa07873f6866b8f0303c49e72287f7/google_api_core-2.24.2.tar.gz", hash = "sha256:81718493daf06d96d6bc76a91c23874dbf2fac0adbbf542831b805ee6e974696", size = 163516, upload-time = "2025-03-10T15:55:26.201Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/98/a2/8176b416ca08106b2ae30cd4a006c8176945f682c3a5b42f141c9173f505/google_api_core-2.25.0.tar.gz", hash = "sha256:9b548e688702f82a34ed8409fb8a6961166f0b7795032f0be8f48308dff4333a", size = 164914, upload-time = "2025-06-02T14:45:34.789Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/46/95/f472d85adab6e538da2025dfca9e976a0d125cc0af2301f190e77b76e51c/google_api_core-2.24.2-py3-none-any.whl", hash = "sha256:810a63ac95f3c441b7c0e43d344e372887f62ce9071ba972eacf32672e072de9", size = 160061, upload-time = "2025-03-10T15:55:24.386Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ac/ca/149e41a277bb0855e8ded85fd7579d7747c1223e253d82c5c0f1be236875/google_api_core-2.25.0-py3-none-any.whl", hash = "sha256:1db79d1281dcf9f3d10023283299ba38f3dc9f639ec41085968fd23e5bcf512e", size = 160668, upload-time = "2025-06-02T14:45:33.272Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "google-api-python-client" | ||||
| version = "2.170.0" | ||||
| version = "2.171.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "google-api-core" }, | ||||
| @ -1406,23 +1395,20 @@ dependencies = [ | ||||
|     { name = "httplib2" }, | ||||
|     { name = "uritemplate" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/db/86/1bd09aea2664a46bc65713cb7876381ec8949a4b1e71be97dfc359c79781/google_api_python_client-2.170.0.tar.gz", hash = "sha256:75f3a1856f11418ea3723214e0abc59d9b217fd7ed43dcf743aab7f06ab9e2b1", size = 12971933, upload-time = "2025-05-22T20:39:52.802Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/ca/ab/928fb4551ce9c791de96b0681924d46de9a5b50931394fd19850383a08a1/google_api_python_client-2.170.0-py3-none-any.whl", hash = "sha256:7bf518a0527ad23322f070fa69f4f24053170d5c766821dc970ff0571ec22748", size = 13490660, upload-time = "2025-05-22T20:39:49.834Z" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/35/99/237cd2510aecca9fabb54007e58553274cc43cb3c18512ee1ea574d11b87/google_api_python_client-2.171.0.tar.gz", hash = "sha256:057a5c08d28463c6b9eb89746355de5f14b7ed27a65c11fdbf1d06c66bb66b23", size = 13028937, upload-time = "2025-06-03T18:57:38.732Z" } | ||||
|  | ||||
| [[package]] | ||||
| name = "google-auth" | ||||
| version = "2.40.1" | ||||
| version = "2.40.2" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "cachetools" }, | ||||
|     { name = "pyasn1-modules" }, | ||||
|     { name = "rsa" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/94/a5/38c21d0e731bb716cffcf987bd9a3555cb95877ab4b616cfb96939933f20/google_auth-2.40.1.tar.gz", hash = "sha256:58f0e8416a9814c1d86c9b7f6acf6816b51aba167b2c76821965271bac275540", size = 280975, upload-time = "2025-05-07T01:04:55.3Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/66/84/f67f53c505a6b2c5da05c988e2a5483f5ba9eee4b1841d2e3ff22f547cd5/google_auth-2.40.2.tar.gz", hash = "sha256:a33cde547a2134273226fa4b853883559947ebe9207521f7afc707efbf690f58", size = 280990, upload-time = "2025-05-21T18:04:59.816Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/a1/b1/1272c6e80847ba5349f5ccb7574596393d1e222543f5003cb810865c3575/google_auth-2.40.1-py2.py3-none-any.whl", hash = "sha256:ed4cae4f5c46b41bae1d19c036e06f6c371926e97b19e816fc854eff811974ee", size = 216101, upload-time = "2025-05-07T01:04:53.612Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/6a/c7/e2d82e6702e2a9e2311c138f8e1100f21d08aed0231290872b229ae57a86/google_auth-2.40.2-py2.py3-none-any.whl", hash = "sha256:f7e568d42eedfded58734f6a60c58321896a621f7c116c411550a4b4a13da90b", size = 216102, upload-time = "2025-05-21T18:04:57.547Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -1720,7 +1706,7 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "jsonschema" | ||||
| version = "4.23.0" | ||||
| version = "4.24.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "attrs" }, | ||||
| @ -1728,9 +1714,9 @@ dependencies = [ | ||||
|     { name = "referencing" }, | ||||
|     { name = "rpds-py" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778, upload-time = "2024-07-08T18:40:05.546Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/bf/d3/1cf5326b923a53515d8f3a2cd442e6d7e94fcc444716e879ea70a0ce3177/jsonschema-4.24.0.tar.gz", hash = "sha256:0b4e8069eb12aedfa881333004bccaec24ecef5a8a6a4b6df142b2cc9599d196", size = 353480, upload-time = "2025-05-26T18:48:10.459Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462, upload-time = "2024-07-08T18:40:00.165Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a2/3d/023389198f69c722d039351050738d6755376c8fd343e91dc493ea485905/jsonschema-4.24.0-py3-none-any.whl", hash = "sha256:a462455f19f5faf404a7902952b6f0e3ce868f3ee09a359b05eca6673bd8412d", size = 88709, upload-time = "2025-05-26T18:48:08.417Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -2051,7 +2037,7 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "msgraph-core" | ||||
| version = "1.3.3" | ||||
| version = "1.3.4" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "httpx", extra = ["http2"] }, | ||||
| @ -2059,14 +2045,14 @@ dependencies = [ | ||||
|     { name = "microsoft-kiota-authentication-azure" }, | ||||
|     { name = "microsoft-kiota-http" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/d7/9a/f078f7d0ea8f55ba5c85fa53487bd6ffec2403542c117bf5b2a8b86f11a5/msgraph_core-1.3.3.tar.gz", hash = "sha256:a3226b08b4cf9b6dbb16b868be21d5f82d8ee514ae8e46d9f0cad896159ef8d3", size = 26198, upload-time = "2025-03-24T13:02:15.889Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/e7/d4/913feb5b182037ef92adda32e56bf591256d87b53adebdd678058b2cbcfd/msgraph_core-1.3.4.tar.gz", hash = "sha256:27e0d95344d29b6f05cf6ceb24a28bac363f19f18d6efaed7af6457e9fe4d6a9", size = 26212, upload-time = "2025-06-02T14:52:14.75Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/3c/9a/506335cbad42698b2c05e1da0b3e4c19f9cd04d379abc9758e822115ab12/msgraph_core-1.3.3-py3-none-any.whl", hash = "sha256:9dbbc0c88e174c1d5da1c17d286965d6b26ebaf24996c7af64a39e2069006cf6", size = 35050, upload-time = "2025-03-24T13:02:14.987Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9c/89/5cdc20dd414243464014afbc24362f9857dc6d6326babdd831e21d46a1e0/msgraph_core-1.3.4-py3-none-any.whl", hash = "sha256:bce306ce193f8f96b3dd32af8b6ffd28eaaaf0db7560bfac8a334158e616c821", size = 35064, upload-time = "2025-06-02T14:52:13.766Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "msgraph-sdk" | ||||
| version = "1.30.0" | ||||
| version = "1.32.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "azure-identity" }, | ||||
| @ -2076,52 +2062,52 @@ dependencies = [ | ||||
|     { name = "microsoft-kiota-serialization-text" }, | ||||
|     { name = "msgraph-core" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/e9/4a/4ff19671f6ea06f98fb2405f73a90350e4719ccc692e85e9e0c2fa066826/msgraph_sdk-1.30.0.tar.gz", hash = "sha256:59e30af6d7244c9009146d620c331e169701b651317746b16f561e2e2452e73f", size = 6608744, upload-time = "2025-05-13T13:09:12.594Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/e0/2a/a5d67f631f8a0a9daa9059eed0f6703002efdf75f1d7575a289e23aceb5e/msgraph_sdk-1.32.0.tar.gz", hash = "sha256:485b25420ec4b3bf9c9d7abea166f9c51da99d9aad1bd57c191f84569af35143", size = 6628831, upload-time = "2025-06-03T18:22:21.526Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/70/95/451ec4db8a924274a1f7260809ea03fe9c2b446d84dc5238e92e49a1b522/msgraph_sdk-1.30.0-py3-none-any.whl", hash = "sha256:6748f5cdb5ddbcff9e4f3fb073dd0a604cb00e1cf285dd0fea6969c93ba8282f", size = 27140767, upload-time = "2025-05-13T13:09:07.718Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b9/59/7e0f170611eb1a213940816703522ecca47ddffc149ef8e001e4789ddf13/msgraph_sdk-1.32.0-py3-none-any.whl", hash = "sha256:d1256f1669706c2703963ef0103470ce7a1b8a06f555506fc6b5f1069847877b", size = 27190465, upload-time = "2025-06-03T18:22:18.944Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "multidict" | ||||
| version = "6.4.3" | ||||
| version = "6.4.4" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/da/2c/e367dfb4c6538614a0c9453e510d75d66099edf1c4e69da1b5ce691a1931/multidict-6.4.3.tar.gz", hash = "sha256:3ada0b058c9f213c5f95ba301f922d402ac234f1111a7d8fd70f1b99f3c281ec", size = 89372, upload-time = "2025-04-10T22:20:17.956Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/91/2f/a3470242707058fe856fe59241eee5635d79087100b7042a867368863a27/multidict-6.4.4.tar.gz", hash = "sha256:69ee9e6ba214b5245031b76233dd95408a0fd57fdb019ddcc1ead4790932a8e8", size = 90183, upload-time = "2025-05-19T14:16:37.381Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/6c/4b/86fd786d03915c6f49998cf10cd5fe6b6ac9e9a071cb40885d2e080fb90d/multidict-6.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a76534263d03ae0cfa721fea40fd2b5b9d17a6f85e98025931d41dc49504474", size = 63831, upload-time = "2025-04-10T22:18:48.748Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/45/05/9b51fdf7aef2563340a93be0a663acba2c428c4daeaf3960d92d53a4a930/multidict-6.4.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:805031c2f599eee62ac579843555ed1ce389ae00c7e9f74c2a1b45e0564a88dd", size = 37888, upload-time = "2025-04-10T22:18:50.021Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/0b/43/53fc25394386c911822419b522181227ca450cf57fea76e6188772a1bd91/multidict-6.4.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c56c179839d5dcf51d565132185409d1d5dd8e614ba501eb79023a6cab25576b", size = 36852, upload-time = "2025-04-10T22:18:51.246Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/8a/68/7b99c751e822467c94a235b810a2fd4047d4ecb91caef6b5c60116991c4b/multidict-6.4.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c64f4ddb3886dd8ab71b68a7431ad4aa01a8fa5be5b11543b29674f29ca0ba3", size = 223644, upload-time = "2025-04-10T22:18:52.965Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/80/1b/d458d791e4dd0f7e92596667784fbf99e5c8ba040affe1ca04f06b93ae92/multidict-6.4.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3002a856367c0b41cad6784f5b8d3ab008eda194ed7864aaa58f65312e2abcac", size = 230446, upload-time = "2025-04-10T22:18:54.509Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e2/46/9793378d988905491a7806d8987862dc5a0bae8a622dd896c4008c7b226b/multidict-6.4.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3d75e621e7d887d539d6e1d789f0c64271c250276c333480a9e1de089611f790", size = 231070, upload-time = "2025-04-10T22:18:56.019Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a7/b8/b127d3e1f8dd2a5bf286b47b24567ae6363017292dc6dec44656e6246498/multidict-6.4.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:995015cf4a3c0d72cbf453b10a999b92c5629eaf3a0c3e1efb4b5c1f602253bb", size = 229956, upload-time = "2025-04-10T22:18:59.146Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/0c/93/f70a4c35b103fcfe1443059a2bb7f66e5c35f2aea7804105ff214f566009/multidict-6.4.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b0fabae7939d09d7d16a711468c385272fa1b9b7fb0d37e51143585d8e72e0", size = 222599, upload-time = "2025-04-10T22:19:00.657Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/63/8c/e28e0eb2fe34921d6aa32bfc4ac75b09570b4d6818cc95d25499fe08dc1d/multidict-6.4.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:61ed4d82f8a1e67eb9eb04f8587970d78fe7cddb4e4d6230b77eda23d27938f9", size = 216136, upload-time = "2025-04-10T22:19:02.244Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/72/f5/fbc81f866585b05f89f99d108be5d6ad170e3b6c4d0723d1a2f6ba5fa918/multidict-6.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:062428944a8dc69df9fdc5d5fc6279421e5f9c75a9ee3f586f274ba7b05ab3c8", size = 228139, upload-time = "2025-04-10T22:19:04.151Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/bb/ba/7d196bad6b85af2307d81f6979c36ed9665f49626f66d883d6c64d156f78/multidict-6.4.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:b90e27b4674e6c405ad6c64e515a505c6d113b832df52fdacb6b1ffd1fa9a1d1", size = 226251, upload-time = "2025-04-10T22:19:06.117Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/cc/e2/fae46a370dce79d08b672422a33df721ec8b80105e0ea8d87215ff6b090d/multidict-6.4.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7d50d4abf6729921e9613d98344b74241572b751c6b37feed75fb0c37bd5a817", size = 221868, upload-time = "2025-04-10T22:19:07.981Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/26/20/bbc9a3dec19d5492f54a167f08546656e7aef75d181d3d82541463450e88/multidict-6.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:43fe10524fb0a0514be3954be53258e61d87341008ce4914f8e8b92bee6f875d", size = 233106, upload-time = "2025-04-10T22:19:09.5Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ee/8d/f30ae8f5ff7a2461177f4d8eb0d8f69f27fb6cfe276b54ec4fd5a282d918/multidict-6.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:236966ca6c472ea4e2d3f02f6673ebfd36ba3f23159c323f5a496869bc8e47c9", size = 230163, upload-time = "2025-04-10T22:19:11Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/15/e9/2833f3c218d3c2179f3093f766940ded6b81a49d2e2f9c46ab240d23dfec/multidict-6.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:422a5ec315018e606473ba1f5431e064cf8b2a7468019233dcf8082fabad64c8", size = 225906, upload-time = "2025-04-10T22:19:12.875Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f1/31/6edab296ac369fd286b845fa5dd4c409e63bc4655ed8c9510fcb477e9ae9/multidict-6.4.3-cp313-cp313-win32.whl", hash = "sha256:f901a5aace8e8c25d78960dcc24c870c8d356660d3b49b93a78bf38eb682aac3", size = 35238, upload-time = "2025-04-10T22:19:14.41Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/23/57/2c0167a1bffa30d9a1383c3dab99d8caae985defc8636934b5668830d2ef/multidict-6.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:1c152c49e42277bc9a2f7b78bd5fa10b13e88d1b0328221e7aef89d5c60a99a5", size = 38799, upload-time = "2025-04-10T22:19:15.869Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/c9/13/2ead63b9ab0d2b3080819268acb297bd66e238070aa8d42af12b08cbee1c/multidict-6.4.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:be8751869e28b9c0d368d94f5afcb4234db66fe8496144547b4b6d6a0645cfc6", size = 68642, upload-time = "2025-04-10T22:19:17.527Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/85/45/f1a751e1eede30c23951e2ae274ce8fad738e8a3d5714be73e0a41b27b16/multidict-6.4.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d4b31f8a68dccbcd2c0ea04f0e014f1defc6b78f0eb8b35f2265e8716a6df0c", size = 40028, upload-time = "2025-04-10T22:19:19.465Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a7/29/fcc53e886a2cc5595cc4560df333cb9630257bda65003a7eb4e4e0d8f9c1/multidict-6.4.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:032efeab3049e37eef2ff91271884303becc9e54d740b492a93b7e7266e23756", size = 39424, upload-time = "2025-04-10T22:19:20.762Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f6/f0/056c81119d8b88703971f937b371795cab1407cd3c751482de5bfe1a04a9/multidict-6.4.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9e78006af1a7c8a8007e4f56629d7252668344442f66982368ac06522445e375", size = 226178, upload-time = "2025-04-10T22:19:22.17Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a3/79/3b7e5fea0aa80583d3a69c9d98b7913dfd4fbc341fb10bb2fb48d35a9c21/multidict-6.4.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:daeac9dd30cda8703c417e4fddccd7c4dc0c73421a0b54a7da2713be125846be", size = 222617, upload-time = "2025-04-10T22:19:23.773Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/06/db/3ed012b163e376fc461e1d6a67de69b408339bc31dc83d39ae9ec3bf9578/multidict-6.4.3-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f6f90700881438953eae443a9c6f8a509808bc3b185246992c4233ccee37fea", size = 227919, upload-time = "2025-04-10T22:19:25.35Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b1/db/0433c104bca380989bc04d3b841fc83e95ce0c89f680e9ea4251118b52b6/multidict-6.4.3-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f84627997008390dd15762128dcf73c3365f4ec0106739cde6c20a07ed198ec8", size = 226097, upload-time = "2025-04-10T22:19:27.183Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/c2/95/910db2618175724dd254b7ae635b6cd8d2947a8b76b0376de7b96d814dab/multidict-6.4.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3307b48cd156153b117c0ea54890a3bdbf858a5b296ddd40dc3852e5f16e9b02", size = 220706, upload-time = "2025-04-10T22:19:28.882Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d1/af/aa176c6f5f1d901aac957d5258d5e22897fe13948d1e69063ae3d5d0ca01/multidict-6.4.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ead46b0fa1dcf5af503a46e9f1c2e80b5d95c6011526352fa5f42ea201526124", size = 211728, upload-time = "2025-04-10T22:19:30.481Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e7/42/d51cc5fc1527c3717d7f85137d6c79bb7a93cd214c26f1fc57523774dbb5/multidict-6.4.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:1748cb2743bedc339d63eb1bca314061568793acd603a6e37b09a326334c9f44", size = 226276, upload-time = "2025-04-10T22:19:32.454Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/28/6b/d836dea45e0b8432343ba4acf9a8ecaa245da4c0960fb7ab45088a5e568a/multidict-6.4.3-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:acc9fa606f76fc111b4569348cc23a771cb52c61516dcc6bcef46d612edb483b", size = 212069, upload-time = "2025-04-10T22:19:34.17Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/55/34/0ee1a7adb3560e18ee9289c6e5f7db54edc312b13e5c8263e88ea373d12c/multidict-6.4.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:31469d5832b5885adeb70982e531ce86f8c992334edd2f2254a10fa3182ac504", size = 217858, upload-time = "2025-04-10T22:19:35.879Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/04/08/586d652c2f5acefe0cf4e658eedb4d71d4ba6dfd4f189bd81b400fc1bc6b/multidict-6.4.3-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:ba46b51b6e51b4ef7bfb84b82f5db0dc5e300fb222a8a13b8cd4111898a869cf", size = 226988, upload-time = "2025-04-10T22:19:37.434Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/82/e3/cc59c7e2bc49d7f906fb4ffb6d9c3a3cf21b9f2dd9c96d05bef89c2b1fd1/multidict-6.4.3-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:389cfefb599edf3fcfd5f64c0410da686f90f5f5e2c4d84e14f6797a5a337af4", size = 220435, upload-time = "2025-04-10T22:19:39.005Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e0/32/5c3a556118aca9981d883f38c4b1bfae646f3627157f70f4068e5a648955/multidict-6.4.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:64bc2bbc5fba7b9db5c2c8d750824f41c6994e3882e6d73c903c2afa78d091e4", size = 221494, upload-time = "2025-04-10T22:19:41.447Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b9/3b/1599631f59024b75c4d6e3069f4502409970a336647502aaf6b62fb7ac98/multidict-6.4.3-cp313-cp313t-win32.whl", hash = "sha256:0ecdc12ea44bab2807d6b4a7e5eef25109ab1c82a8240d86d3c1fc9f3b72efd5", size = 41775, upload-time = "2025-04-10T22:19:43.707Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e8/4e/09301668d675d02ca8e8e1a3e6be046619e30403f5ada2ed5b080ae28d02/multidict-6.4.3-cp313-cp313t-win_amd64.whl", hash = "sha256:7146a8742ea71b5d7d955bffcef58a9e6e04efba704b52a460134fefd10a8208", size = 45946, upload-time = "2025-04-10T22:19:45.071Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/96/10/7d526c8974f017f1e7ca584c71ee62a638e9334d8d33f27d7cdfc9ae79e4/multidict-6.4.3-py3-none-any.whl", hash = "sha256:59fe01ee8e2a1e8ceb3f6dbb216b09c8d9f4ef1c22c4fc825d045a147fa2ebc9", size = 10400, upload-time = "2025-04-10T22:20:16.445Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/df/2a/e166d2ffbf4b10131b2d5b0e458f7cee7d986661caceae0de8753042d4b2/multidict-6.4.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:82ffabefc8d84c2742ad19c37f02cde5ec2a1ee172d19944d380f920a340e4b9", size = 64123, upload-time = "2025-05-19T14:15:11.044Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/8c/96/e200e379ae5b6f95cbae472e0199ea98913f03d8c9a709f42612a432932c/multidict-6.4.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6a2f58a66fe2c22615ad26156354005391e26a2f3721c3621504cd87c1ea87bf", size = 38049, upload-time = "2025-05-19T14:15:12.902Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/75/fb/47afd17b83f6a8c7fa863c6d23ac5ba6a0e6145ed8a6bcc8da20b2b2c1d2/multidict-6.4.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5883d6ee0fd9d8a48e9174df47540b7545909841ac82354c7ae4cbe9952603bd", size = 37078, upload-time = "2025-05-19T14:15:14.282Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/fa/70/1af3143000eddfb19fd5ca5e78393985ed988ac493bb859800fe0914041f/multidict-6.4.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9abcf56a9511653fa1d052bfc55fbe53dbee8f34e68bd6a5a038731b0ca42d15", size = 224097, upload-time = "2025-05-19T14:15:15.566Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b1/39/d570c62b53d4fba844e0378ffbcd02ac25ca423d3235047013ba2f6f60f8/multidict-6.4.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:6ed5ae5605d4ad5a049fad2a28bb7193400700ce2f4ae484ab702d1e3749c3f9", size = 230768, upload-time = "2025-05-19T14:15:17.308Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/fd/f8/ed88f2c4d06f752b015933055eb291d9bc184936903752c66f68fb3c95a7/multidict-6.4.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbfcb60396f9bcfa63e017a180c3105b8c123a63e9d1428a36544e7d37ca9e20", size = 231331, upload-time = "2025-05-19T14:15:18.73Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9c/6f/8e07cffa32f483ab887b0d56bbd8747ac2c1acd00dc0af6fcf265f4a121e/multidict-6.4.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0f1987787f5f1e2076b59692352ab29a955b09ccc433c1f6b8e8e18666f608b", size = 230169, upload-time = "2025-05-19T14:15:20.179Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e6/2b/5dcf173be15e42f330110875a2668ddfc208afc4229097312212dc9c1236/multidict-6.4.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d0121ccce8c812047d8d43d691a1ad7641f72c4f730474878a5aeae1b8ead8c", size = 222947, upload-time = "2025-05-19T14:15:21.714Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/39/75/4ddcbcebe5ebcd6faa770b629260d15840a5fc07ce8ad295a32e14993726/multidict-6.4.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83ec4967114295b8afd120a8eec579920c882831a3e4c3331d591a8e5bfbbc0f", size = 215761, upload-time = "2025-05-19T14:15:23.242Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/6a/c9/55e998ae45ff15c5608e384206aa71a11e1b7f48b64d166db400b14a3433/multidict-6.4.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:995f985e2e268deaf17867801b859a282e0448633f1310e3704b30616d269d69", size = 227605, upload-time = "2025-05-19T14:15:24.763Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/04/49/c2404eac74497503c77071bd2e6f88c7e94092b8a07601536b8dbe99be50/multidict-6.4.4-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d832c608f94b9f92a0ec8b7e949be7792a642b6e535fcf32f3e28fab69eeb046", size = 226144, upload-time = "2025-05-19T14:15:26.249Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/62/c5/0cd0c3c6f18864c40846aa2252cd69d308699cb163e1c0d989ca301684da/multidict-6.4.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d21c1212171cf7da703c5b0b7a0e85be23b720818aef502ad187d627316d5645", size = 221100, upload-time = "2025-05-19T14:15:28.303Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/71/7b/f2f3887bea71739a046d601ef10e689528d4f911d84da873b6be9194ffea/multidict-6.4.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:cbebaa076aaecad3d4bb4c008ecc73b09274c952cf6a1b78ccfd689e51f5a5b0", size = 232731, upload-time = "2025-05-19T14:15:30.263Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e5/b3/d9de808349df97fa75ec1372758701b5800ebad3c46ae377ad63058fbcc6/multidict-6.4.4-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:c93a6fb06cc8e5d3628b2b5fda215a5db01e8f08fc15fadd65662d9b857acbe4", size = 229637, upload-time = "2025-05-19T14:15:33.337Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/5e/57/13207c16b615eb4f1745b44806a96026ef8e1b694008a58226c2d8f5f0a5/multidict-6.4.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8cd8f81f1310182362fb0c7898145ea9c9b08a71081c5963b40ee3e3cac589b1", size = 225594, upload-time = "2025-05-19T14:15:34.832Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/3a/e4/d23bec2f70221604f5565000632c305fc8f25ba953e8ce2d8a18842b9841/multidict-6.4.4-cp313-cp313-win32.whl", hash = "sha256:3e9f1cd61a0ab857154205fb0b1f3d3ace88d27ebd1409ab7af5096e409614cd", size = 35359, upload-time = "2025-05-19T14:15:36.246Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a7/7a/cfe1a47632be861b627f46f642c1d031704cc1c0f5c0efbde2ad44aa34bd/multidict-6.4.4-cp313-cp313-win_amd64.whl", hash = "sha256:8ffb40b74400e4455785c2fa37eba434269149ec525fc8329858c862e4b35373", size = 38903, upload-time = "2025-05-19T14:15:37.507Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/68/7b/15c259b0ab49938a0a1c8f3188572802704a779ddb294edc1b2a72252e7c/multidict-6.4.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:6a602151dbf177be2450ef38966f4be3467d41a86c6a845070d12e17c858a156", size = 68895, upload-time = "2025-05-19T14:15:38.856Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f1/7d/168b5b822bccd88142e0a3ce985858fea612404edd228698f5af691020c9/multidict-6.4.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0d2b9712211b860d123815a80b859075d86a4d54787e247d7fbee9db6832cf1c", size = 40183, upload-time = "2025-05-19T14:15:40.197Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e0/b7/d4b8d98eb850ef28a4922ba508c31d90715fd9b9da3801a30cea2967130b/multidict-6.4.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d2fa86af59f8fc1972e121ade052145f6da22758f6996a197d69bb52f8204e7e", size = 39592, upload-time = "2025-05-19T14:15:41.508Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/18/28/a554678898a19583548e742080cf55d169733baf57efc48c2f0273a08583/multidict-6.4.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50855d03e9e4d66eab6947ba688ffb714616f985838077bc4b490e769e48da51", size = 226071, upload-time = "2025-05-19T14:15:42.877Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ee/dc/7ba6c789d05c310e294f85329efac1bf5b450338d2542498db1491a264df/multidict-6.4.4-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:5bce06b83be23225be1905dcdb6b789064fae92499fbc458f59a8c0e68718601", size = 222597, upload-time = "2025-05-19T14:15:44.412Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/24/4f/34eadbbf401b03768dba439be0fb94b0d187facae9142821a3d5599ccb3b/multidict-6.4.4-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66ed0731f8e5dfd8369a883b6e564aca085fb9289aacabd9decd70568b9a30de", size = 228253, upload-time = "2025-05-19T14:15:46.474Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/c0/e6/493225a3cdb0d8d80d43a94503fc313536a07dae54a3f030d279e629a2bc/multidict-6.4.4-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:329ae97fc2f56f44d91bc47fe0972b1f52d21c4b7a2ac97040da02577e2daca2", size = 226146, upload-time = "2025-05-19T14:15:48.003Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/2f/70/e411a7254dc3bff6f7e6e004303b1b0591358e9f0b7c08639941e0de8bd6/multidict-6.4.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c27e5dcf520923d6474d98b96749e6805f7677e93aaaf62656005b8643f907ab", size = 220585, upload-time = "2025-05-19T14:15:49.546Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/08/8f/beb3ae7406a619100d2b1fb0022c3bb55a8225ab53c5663648ba50dfcd56/multidict-6.4.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:058cc59b9e9b143cc56715e59e22941a5d868c322242278d28123a5d09cdf6b0", size = 212080, upload-time = "2025-05-19T14:15:51.151Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9c/ec/355124e9d3d01cf8edb072fd14947220f357e1c5bc79c88dff89297e9342/multidict-6.4.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:69133376bc9a03f8c47343d33f91f74a99c339e8b58cea90433d8e24bb298031", size = 226558, upload-time = "2025-05-19T14:15:52.665Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/fd/22/d2b95cbebbc2ada3be3812ea9287dcc9712d7f1a012fad041770afddb2ad/multidict-6.4.4-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:d6b15c55721b1b115c5ba178c77104123745b1417527ad9641a4c5e2047450f0", size = 212168, upload-time = "2025-05-19T14:15:55.279Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/4d/c5/62bfc0b2f9ce88326dbe7179f9824a939c6c7775b23b95de777267b9725c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:a887b77f51d3d41e6e1a63cf3bc7ddf24de5939d9ff69441387dfefa58ac2e26", size = 217970, upload-time = "2025-05-19T14:15:56.806Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/79/74/977cea1aadc43ff1c75d23bd5bc4768a8fac98c14e5878d6ee8d6bab743c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:632a3bf8f1787f7ef7d3c2f68a7bde5be2f702906f8b5842ad6da9d974d0aab3", size = 226980, upload-time = "2025-05-19T14:15:58.313Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/48/fc/cc4a1a2049df2eb84006607dc428ff237af38e0fcecfdb8a29ca47b1566c/multidict-6.4.4-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:a145c550900deb7540973c5cdb183b0d24bed6b80bf7bddf33ed8f569082535e", size = 220641, upload-time = "2025-05-19T14:15:59.866Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/3b/6a/a7444d113ab918701988d4abdde373dbdfd2def7bd647207e2bf645c7eac/multidict-6.4.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc5d83c6619ca5c9672cb78b39ed8542f1975a803dee2cda114ff73cbb076edd", size = 221728, upload-time = "2025-05-19T14:16:01.535Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/2b/b0/fdf4c73ad1c55e0f4dbbf2aa59dd37037334091f9a4961646d2b7ac91a86/multidict-6.4.4-cp313-cp313t-win32.whl", hash = "sha256:3312f63261b9df49be9d57aaa6abf53a6ad96d93b24f9cc16cf979956355ce6e", size = 41913, upload-time = "2025-05-19T14:16:03.199Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/8e/92/27989ecca97e542c0d01d05a98a5ae12198a243a9ee12563a0313291511f/multidict-6.4.4-cp313-cp313t-win_amd64.whl", hash = "sha256:ba852168d814b2c73333073e1c7116d9395bea69575a01b0b3c89d2d5a87c8fb", size = 46112, upload-time = "2025-05-19T14:16:04.909Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/84/5d/e17845bb0fa76334477d5de38654d27946d5b5d3695443987a094a71b440/multidict-6.4.4-py3-none-any.whl", hash = "sha256:bd4557071b561a8b3b6075c3ce93cf9bfb6182cb241805c3d66ced3b75eff4ac", size = 10481, upload-time = "2025-05-19T14:16:36.024Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -2158,42 +2144,42 @@ source = { git = "https://github.com/vsoch/oci-python?rev=ceb4fcc090851717a3069d | ||||
|  | ||||
| [[package]] | ||||
| name = "opentelemetry-api" | ||||
| version = "1.33.0" | ||||
| version = "1.34.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "deprecated" }, | ||||
|     { name = "importlib-metadata" }, | ||||
|     { name = "typing-extensions" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/70/ca/920a73b4a11cd271ba1c62f34dba27d7783996a6a7ac0bac7c83b230736d/opentelemetry_api-1.33.0.tar.gz", hash = "sha256:cc4380fd2e6da7dcb52a828ea81844ed1f4f2eb638ca3c816775109d93d58ced", size = 65000, upload-time = "2025-05-09T14:56:00.967Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/4c/0b/4433d3f18301b541d98ea775fcbeab817fc7f962e980a75d17c967471b64/opentelemetry_api-1.34.0.tar.gz", hash = "sha256:48d167589134799093005b7f7f347c69cc67859c693b17787f334fbe8871279f", size = 64983, upload-time = "2025-06-04T13:31:26.107Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/e6/c4/26c7ec8e51c19632f42503dbabed286c261fb06f8f61ffd348690e36958a/opentelemetry_api-1.33.0-py3-none-any.whl", hash = "sha256:158df154f628e6615b65fdf6e59f99afabea7213e72c5809dd4adf06c0d997cd", size = 65772, upload-time = "2025-05-09T14:55:38.395Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/98/f9/d50ba0c92a97a6d0861357d0ecd67e850d319ac7e7be1895cc236b6ed2b5/opentelemetry_api-1.34.0-py3-none-any.whl", hash = "sha256:390b81984affe4453180820ca518de55e3be051111e70cc241bb3b0071ca3a2c", size = 65768, upload-time = "2025-06-04T13:31:02.706Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "opentelemetry-sdk" | ||||
| version = "1.33.0" | ||||
| version = "1.34.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "opentelemetry-api" }, | ||||
|     { name = "opentelemetry-semantic-conventions" }, | ||||
|     { name = "typing-extensions" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/37/0a/b7ae406175a2798a767e12db223e842911d9c398eea100c41c989afd2aa8/opentelemetry_sdk-1.33.0.tar.gz", hash = "sha256:a7fc56d1e07b218fcc316b24d21b59d3f1967b2ca22c217b05da3a26b797cc68", size = 161381, upload-time = "2025-05-09T14:56:12.347Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/52/07/8ca4b295322b5978e2cc4fab3f743ddabf72b82b5d2c50141471f573149d/opentelemetry_sdk-1.34.0.tar.gz", hash = "sha256:719559622afcd515c2aec462ccb749ba2e70075a01df45837623643814d33716", size = 159322, upload-time = "2025-06-04T13:31:36.333Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/b4/34/831f5d9ae9375c9ba2446cb3cc0be79d8d73b78f813c9567e1615c2624f6/opentelemetry_sdk-1.33.0-py3-none-any.whl", hash = "sha256:bed376b6d37fbf00688bb65edfee817dd01d48b8559212831437529a6066049a", size = 118861, upload-time = "2025-05-09T14:55:56.956Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/55/96/5b788eef90a65543a67988729f0e44fc46eac1da455505ae5091f418a9d9/opentelemetry_sdk-1.34.0-py3-none-any.whl", hash = "sha256:7850bcd5b5c95f9aae48603d6592bdad5c7bdef50c03e06393f8f457d891fe32", size = 118385, upload-time = "2025-06-04T13:31:21.372Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "opentelemetry-semantic-conventions" | ||||
| version = "0.54b0" | ||||
| version = "0.55b0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "deprecated" }, | ||||
|     { name = "opentelemetry-api" }, | ||||
|     { name = "typing-extensions" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/92/8c/bc970d1599ff40b7913c953a95195addf11c81a27cc85d5ed568e9f8c57f/opentelemetry_semantic_conventions-0.54b0.tar.gz", hash = "sha256:467b739977bdcb079af1af69f73632535cdb51099d5e3c5709a35d10fe02a9c9", size = 118646, upload-time = "2025-05-09T14:56:13.596Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/f1/64/b99165f7e205e103a83406fb5c3dde668c3a990b3fa0cbe358011095f4fa/opentelemetry_semantic_conventions-0.55b0.tar.gz", hash = "sha256:933d2e20c2dbc0f9b2f4f52138282875b4b14c66c491f5273bcdef1781368e9c", size = 119828, upload-time = "2025-06-04T13:31:37.118Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/c8/aa/f7c46c19aee189e0123ef7209eaafc417e242b2073485dfb40523d6d8612/opentelemetry_semantic_conventions-0.54b0-py3-none-any.whl", hash = "sha256:fad7c1cf8908fd449eb5cf9fbbeefb301acf4bc995101f85277899cec125d823", size = 194937, upload-time = "2025-05-09T14:55:58.562Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ca/b1/d7a2472f7da7e39f1a85f63951ad653c1126a632d6491c056ec6284a10a7/opentelemetry_semantic_conventions-0.55b0-py3-none-any.whl", hash = "sha256:63bb15b67377700e51c422d0d24092ca6ce9f3a4cb6f032375aa8af1fc2aab65", size = 196224, upload-time = "2025-06-04T13:31:22.451Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -2300,20 +2286,20 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "pluggy" | ||||
| version = "1.5.0" | ||||
| version = "1.6.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "prometheus-client" | ||||
| version = "0.21.1" | ||||
| version = "0.22.1" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/62/14/7d0f567991f3a9af8d1cd4f619040c93b68f09a02b6d0b6ab1b2d1ded5fe/prometheus_client-0.21.1.tar.gz", hash = "sha256:252505a722ac04b0456be05c05f75f45d760c2911ffc45f2a06bcaed9f3ae3fb", size = 78551, upload-time = "2024-12-03T14:59:12.164Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/5e/cf/40dde0a2be27cc1eb41e333d1a674a74ce8b8b0457269cc640fd42b07cf7/prometheus_client-0.22.1.tar.gz", hash = "sha256:190f1331e783cf21eb60bca559354e0a4d4378facecf78f5428c39b675d20d28", size = 69746, upload-time = "2025-06-02T14:29:01.152Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/ff/c2/ab7d37426c179ceb9aeb109a85cda8948bb269b7561a0be870cc656eefe4/prometheus_client-0.21.1-py3-none-any.whl", hash = "sha256:594b45c410d6f4f8888940fe80b5cc2521b305a1fafe1c58609ef715a001f301", size = 54682, upload-time = "2024-12-03T14:59:10.935Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/32/ae/ec06af4fe3ee72d16973474f122541746196aaa16cea6f66d18b963c6177/prometheus_client-0.22.1-py3-none-any.whl", hash = "sha256:cca895342e308174341b2cbf99a56bef291fbc0ef7b9e5412a0f26d653ba7094", size = 58694, upload-time = "2025-06-02T14:29:00.068Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -2383,16 +2369,16 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "protobuf" | ||||
| version = "6.30.2" | ||||
| version = "6.31.1" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/c8/8c/cf2ac658216eebe49eaedf1e06bc06cbf6a143469236294a1171a51357c3/protobuf-6.30.2.tar.gz", hash = "sha256:35c859ae076d8c56054c25b59e5e59638d86545ed6e2b6efac6be0b6ea3ba048", size = 429315, upload-time = "2025-03-26T19:12:57.394Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/52/f3/b9655a711b32c19720253f6f06326faf90580834e2e83f840472d752bc8b/protobuf-6.31.1.tar.gz", hash = "sha256:d8cac4c982f0b957a4dc73a80e2ea24fab08e679c0de9deb835f4a12d69aca9a", size = 441797, upload-time = "2025-05-28T19:25:54.947Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/be/85/cd53abe6a6cbf2e0029243d6ae5fb4335da2996f6c177bb2ce685068e43d/protobuf-6.30.2-cp310-abi3-win32.whl", hash = "sha256:b12ef7df7b9329886e66404bef5e9ce6a26b54069d7f7436a0853ccdeb91c103", size = 419148, upload-time = "2025-03-26T19:12:41.359Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/97/e9/7b9f1b259d509aef2b833c29a1f3c39185e2bf21c9c1be1cd11c22cb2149/protobuf-6.30.2-cp310-abi3-win_amd64.whl", hash = "sha256:7653c99774f73fe6b9301b87da52af0e69783a2e371e8b599b3e9cb4da4b12b9", size = 431003, upload-time = "2025-03-26T19:12:44.156Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/8e/66/7f3b121f59097c93267e7f497f10e52ced7161b38295137a12a266b6c149/protobuf-6.30.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:0eb523c550a66a09a0c20f86dd554afbf4d32b02af34ae53d93268c1f73bc65b", size = 417579, upload-time = "2025-03-26T19:12:45.447Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d0/89/bbb1bff09600e662ad5b384420ad92de61cab2ed0f12ace1fd081fd4c295/protobuf-6.30.2-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:50f32cc9fd9cb09c783ebc275611b4f19dfdfb68d1ee55d2f0c7fa040df96815", size = 317319, upload-time = "2025-03-26T19:12:46.999Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/28/50/1925de813499546bc8ab3ae857e3ec84efe7d2f19b34529d0c7c3d02d11d/protobuf-6.30.2-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4f6c687ae8efae6cf6093389a596548214467778146b7245e886f35e1485315d", size = 316212, upload-time = "2025-03-26T19:12:48.458Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e5/a1/93c2acf4ade3c5b557d02d500b06798f4ed2c176fa03e3c34973ca92df7f/protobuf-6.30.2-py3-none-any.whl", hash = "sha256:ae86b030e69a98e08c77beab574cbcb9fff6d031d57209f574a5aea1445f4b51", size = 167062, upload-time = "2025-03-26T19:12:55.892Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f3/6f/6ab8e4bf962fd5570d3deaa2d5c38f0a363f57b4501047b5ebeb83ab1125/protobuf-6.31.1-cp310-abi3-win32.whl", hash = "sha256:7fa17d5a29c2e04b7d90e5e32388b8bfd0e7107cd8e616feef7ed3fa6bdab5c9", size = 423603, upload-time = "2025-05-28T19:25:41.198Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/44/3a/b15c4347dd4bf3a1b0ee882f384623e2063bb5cf9fa9d57990a4f7df2fb6/protobuf-6.31.1-cp310-abi3-win_amd64.whl", hash = "sha256:426f59d2964864a1a366254fa703b8632dcec0790d8862d30034d8245e1cd447", size = 435283, upload-time = "2025-05-28T19:25:44.275Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/6a/c9/b9689a2a250264a84e66c46d8862ba788ee7a641cdca39bccf64f59284b7/protobuf-6.31.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:6f1227473dc43d44ed644425268eb7c2e488ae245d51c6866d19fe158e207402", size = 425604, upload-time = "2025-05-28T19:25:45.702Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/76/a1/7a5a94032c83375e4fe7e7f56e3976ea6ac90c5e85fac8576409e25c39c3/protobuf-6.31.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:a40fc12b84c154884d7d4c4ebd675d5b3b5283e155f324049ae396b95ddebc39", size = 322115, upload-time = "2025-05-28T19:25:47.128Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/fa/b1/b59d405d64d31999244643d88c45c8241c58f17cc887e73bcb90602327f8/protobuf-6.31.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:4ee898bf66f7a8b0bd21bce523814e6fbd8c6add948045ce958b73af7e8878c6", size = 321070, upload-time = "2025-05-28T19:25:50.036Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f7/af/ab3c51ab7507a7325e98ffe691d9495ee3d3aa5f589afad65ec920d39821/protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e", size = 168724, upload-time = "2025-05-28T19:25:53.926Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -2754,11 +2740,11 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "redis" | ||||
| version = "6.0.0" | ||||
| version = "6.2.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/79/12/dffaaa4374b8d5f3b7ff5c40025c9db387e06264302d5a9da6043cd84e1f/redis-6.0.0.tar.gz", hash = "sha256:5446780d2425b787ed89c91ddbfa1be6d32370a636c8fdb687f11b1c26c1fa88", size = 4620969, upload-time = "2025-04-30T19:09:30.798Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/ea/9a/0551e01ba52b944f97480721656578c8a7c46b51b99d66814f85fe3a4f3e/redis-6.2.0.tar.gz", hash = "sha256:e821f129b75dde6cb99dd35e5c76e8c49512a5a0d8dfdc560b2fbd44b85ca977", size = 4639129, upload-time = "2025-05-28T05:01:18.91Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/08/c8/68081c9d3531f7b2a4d663326b96a9dcbc2aef47df3c6b5c38dea90dff02/redis-6.0.0-py3-none-any.whl", hash = "sha256:a2e040aee2cdd947be1fa3a32e35a956cd839cc4c1dbbe4b2cdee5b9623fd27c", size = 268950, upload-time = "2025-04-30T19:09:28.432Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/13/67/e60968d3b0e077495a8fee89cf3f2373db98e528288a48f1ee44967f6e8c/redis-6.2.0-py3-none-any.whl", hash = "sha256:c8ddf316ee0aab65f04a11229e94a64b2618451dab7a67cb2f77eb799d872d5e", size = 278659, upload-time = "2025-05-28T05:01:16.955Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -2829,36 +2815,37 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "rpds-py" | ||||
| version = "0.24.0" | ||||
| version = "0.25.1" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/0b/b3/52b213298a0ba7097c7ea96bee95e1947aa84cc816d48cebb539770cdf41/rpds_py-0.24.0.tar.gz", hash = "sha256:772cc1b2cd963e7e17e6cc55fe0371fb9c704d63e44cacec7b9b7f523b78919e", size = 26863, upload-time = "2025-03-26T14:56:01.518Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/8c/a6/60184b7fc00dd3ca80ac635dd5b8577d444c57e8e8742cecabfacb829921/rpds_py-0.25.1.tar.gz", hash = "sha256:8960b6dac09b62dac26e75d7e2c4a22efb835d827a7278c34f72b2b84fa160e3", size = 27304, upload-time = "2025-05-21T12:46:12.502Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/9d/c3/3607abc770395bc6d5a00cb66385a5479fb8cd7416ddef90393b17ef4340/rpds_py-0.24.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:3d2d8e4508e15fc05b31285c4b00ddf2e0eb94259c2dc896771966a163122a0c", size = 367072, upload-time = "2025-03-26T14:53:48.686Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d8/35/8c7ee0fe465793e3af3298dc5a9f3013bd63e7a69df04ccfded8293a4982/rpds_py-0.24.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f00c16e089282ad68a3820fd0c831c35d3194b7cdc31d6e469511d9bffc535c", size = 351919, upload-time = "2025-03-26T14:53:50.229Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/91/d3/7e1b972501eb5466b9aca46a9c31bcbbdc3ea5a076e9ab33f4438c1d069d/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:951cc481c0c395c4a08639a469d53b7d4afa252529a085418b82a6b43c45c240", size = 390360, upload-time = "2025-03-26T14:53:51.909Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a2/a8/ccabb50d3c91c26ad01f9b09a6a3b03e4502ce51a33867c38446df9f896b/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c9ca89938dff18828a328af41ffdf3902405a19f4131c88e22e776a8e228c5a8", size = 400704, upload-time = "2025-03-26T14:53:53.47Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/53/ae/5fa5bf0f3bc6ce21b5ea88fc0ecd3a439e7cb09dd5f9ffb3dbe1b6894fc5/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0ef550042a8dbcd657dfb284a8ee00f0ba269d3f2286b0493b15a5694f9fe8", size = 450839, upload-time = "2025-03-26T14:53:55.005Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e3/ac/c4e18b36d9938247e2b54f6a03746f3183ca20e1edd7d3654796867f5100/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b2356688e5d958c4d5cb964af865bea84db29971d3e563fb78e46e20fe1848b", size = 441494, upload-time = "2025-03-26T14:53:57.047Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/bf/08/b543969c12a8f44db6c0f08ced009abf8f519191ca6985509e7c44102e3c/rpds_py-0.24.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78884d155fd15d9f64f5d6124b486f3d3f7fd7cd71a78e9670a0f6f6ca06fb2d", size = 393185, upload-time = "2025-03-26T14:53:59.032Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/da/7e/f6eb6a7042ce708f9dfc781832a86063cea8a125bbe451d663697b51944f/rpds_py-0.24.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6a4a535013aeeef13c5532f802708cecae8d66c282babb5cd916379b72110cf7", size = 426168, upload-time = "2025-03-26T14:54:00.661Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/38/b0/6cd2bb0509ac0b51af4bb138e145b7c4c902bb4b724d6fd143689d6e0383/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:84e0566f15cf4d769dade9b366b7b87c959be472c92dffb70462dd0844d7cbad", size = 567622, upload-time = "2025-03-26T14:54:02.312Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/64/b0/c401f4f077547d98e8b4c2ec6526a80e7cb04f519d416430ec1421ee9e0b/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:823e74ab6fbaa028ec89615ff6acb409e90ff45580c45920d4dfdddb069f2120", size = 595435, upload-time = "2025-03-26T14:54:04.388Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9f/ec/7993b6e803294c87b61c85bd63e11142ccfb2373cf88a61ec602abcbf9d6/rpds_py-0.24.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c61a2cb0085c8783906b2f8b1f16a7e65777823c7f4d0a6aaffe26dc0d358dd9", size = 563762, upload-time = "2025-03-26T14:54:06.422Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/1f/29/4508003204cb2f461dc2b83dd85f8aa2b915bc98fe6046b9d50d4aa05401/rpds_py-0.24.0-cp313-cp313-win32.whl", hash = "sha256:60d9b630c8025b9458a9d114e3af579a2c54bd32df601c4581bd054e85258143", size = 223510, upload-time = "2025-03-26T14:54:08.344Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f9/12/09e048d1814195e01f354155fb772fb0854bd3450b5f5a82224b3a319f0e/rpds_py-0.24.0-cp313-cp313-win_amd64.whl", hash = "sha256:6eea559077d29486c68218178ea946263b87f1c41ae7f996b1f30a983c476a5a", size = 239075, upload-time = "2025-03-26T14:54:09.992Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d2/03/5027cde39bb2408d61e4dd0cf81f815949bb629932a6c8df1701d0257fc4/rpds_py-0.24.0-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:d09dc82af2d3c17e7dd17120b202a79b578d79f2b5424bda209d9966efeed114", size = 362974, upload-time = "2025-03-26T14:54:11.484Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/bf/10/24d374a2131b1ffafb783e436e770e42dfdb74b69a2cd25eba8c8b29d861/rpds_py-0.24.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5fc13b44de6419d1e7a7e592a4885b323fbc2f46e1f22151e3a8ed3b8b920405", size = 348730, upload-time = "2025-03-26T14:54:13.145Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/7a/d1/1ef88d0516d46cd8df12e5916966dbf716d5ec79b265eda56ba1b173398c/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c347a20d79cedc0a7bd51c4d4b7dbc613ca4e65a756b5c3e57ec84bd43505b47", size = 387627, upload-time = "2025-03-26T14:54:14.711Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/4e/35/07339051b8b901ecefd449ebf8e5522e92bcb95e1078818cbfd9db8e573c/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20f2712bd1cc26a3cc16c5a1bfee9ed1abc33d4cdf1aabd297fe0eb724df4272", size = 394094, upload-time = "2025-03-26T14:54:16.961Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/dc/62/ee89ece19e0ba322b08734e95441952062391065c157bbd4f8802316b4f1/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aad911555286884be1e427ef0dc0ba3929e6821cbeca2194b13dc415a462c7fd", size = 449639, upload-time = "2025-03-26T14:54:19.047Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/15/24/b30e9f9e71baa0b9dada3a4ab43d567c6b04a36d1cb531045f7a8a0a7439/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0aeb3329c1721c43c58cae274d7d2ca85c1690d89485d9c63a006cb79a85771a", size = 438584, upload-time = "2025-03-26T14:54:20.722Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/28/d9/49f7b8f3b4147db13961e19d5e30077cd0854ccc08487026d2cb2142aa4a/rpds_py-0.24.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a0f156e9509cee987283abd2296ec816225145a13ed0391df8f71bf1d789e2d", size = 391047, upload-time = "2025-03-26T14:54:22.426Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/49/b0/e66918d0972c33a259ba3cd7b7ff10ed8bd91dbcfcbec6367b21f026db75/rpds_py-0.24.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa6800adc8204ce898c8a424303969b7aa6a5e4ad2789c13f8648739830323b7", size = 418085, upload-time = "2025-03-26T14:54:23.949Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e1/6b/99ed7ea0a94c7ae5520a21be77a82306aac9e4e715d4435076ead07d05c6/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a18fc371e900a21d7392517c6f60fe859e802547309e94313cd8181ad9db004d", size = 564498, upload-time = "2025-03-26T14:54:25.573Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/28/26/1cacfee6b800e6fb5f91acecc2e52f17dbf8b0796a7c984b4568b6d70e38/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9168764133fd919f8dcca2ead66de0105f4ef5659cbb4fa044f7014bed9a1797", size = 590202, upload-time = "2025-03-26T14:54:27.569Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a9/9e/57bd2f9fba04a37cef673f9a66b11ca8c43ccdd50d386c455cd4380fe461/rpds_py-0.24.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:5f6e3cec44ba05ee5cbdebe92d052f69b63ae792e7d05f1020ac5e964394080c", size = 561771, upload-time = "2025-03-26T14:54:29.615Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9f/cf/b719120f375ab970d1c297dbf8de1e3c9edd26fe92c0ed7178dd94b45992/rpds_py-0.24.0-cp313-cp313t-win32.whl", hash = "sha256:8ebc7e65ca4b111d928b669713865f021b7773350eeac4a31d3e70144297baba", size = 221195, upload-time = "2025-03-26T14:54:31.581Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/2d/e5/22865285789f3412ad0c3d7ec4dc0a3e86483b794be8a5d9ed5a19390900/rpds_py-0.24.0-cp313-cp313t-win_amd64.whl", hash = "sha256:675269d407a257b8c00a6b58205b72eec8231656506c56fd429d924ca00bb350", size = 237354, upload-time = "2025-03-26T14:54:33.199Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/2b/da/323848a2b62abe6a0fec16ebe199dc6889c5d0a332458da8985b2980dffe/rpds_py-0.25.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:659d87430a8c8c704d52d094f5ba6fa72ef13b4d385b7e542a08fc240cb4a559", size = 364498, upload-time = "2025-05-21T12:43:54.841Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/1f/b4/4d3820f731c80fd0cd823b3e95b9963fec681ae45ba35b5281a42382c67d/rpds_py-0.25.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:68f6f060f0bbdfb0245267da014d3a6da9be127fe3e8cc4a68c6f833f8a23bb1", size = 350083, upload-time = "2025-05-21T12:43:56.428Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d5/b1/3a8ee1c9d480e8493619a437dec685d005f706b69253286f50f498cbdbcf/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:083a9513a33e0b92cf6e7a6366036c6bb43ea595332c1ab5c8ae329e4bcc0a9c", size = 389023, upload-time = "2025-05-21T12:43:57.995Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/3b/31/17293edcfc934dc62c3bf74a0cb449ecd549531f956b72287203e6880b87/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:816568614ecb22b18a010c7a12559c19f6fe993526af88e95a76d5a60b8b75fb", size = 403283, upload-time = "2025-05-21T12:43:59.546Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d1/ca/e0f0bc1a75a8925024f343258c8ecbd8828f8997ea2ac71e02f67b6f5299/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c6564c0947a7f52e4792983f8e6cf9bac140438ebf81f527a21d944f2fd0a40", size = 524634, upload-time = "2025-05-21T12:44:01.087Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/3e/03/5d0be919037178fff33a6672ffc0afa04ea1cfcb61afd4119d1b5280ff0f/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c4a128527fe415d73cf1f70a9a688d06130d5810be69f3b553bf7b45e8acf79", size = 416233, upload-time = "2025-05-21T12:44:02.604Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/05/7c/8abb70f9017a231c6c961a8941403ed6557664c0913e1bf413cbdc039e75/rpds_py-0.25.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a49e1d7a4978ed554f095430b89ecc23f42014a50ac385eb0c4d163ce213c325", size = 390375, upload-time = "2025-05-21T12:44:04.162Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/7a/ac/a87f339f0e066b9535074a9f403b9313fd3892d4a164d5d5f5875ac9f29f/rpds_py-0.25.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d74ec9bc0e2feb81d3f16946b005748119c0f52a153f6db6a29e8cd68636f295", size = 424537, upload-time = "2025-05-21T12:44:06.175Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/1f/8f/8d5c1567eaf8c8afe98a838dd24de5013ce6e8f53a01bd47fe8bb06b5533/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3af5b4cc10fa41e5bc64e5c198a1b2d2864337f8fcbb9a67e747e34002ce812b", size = 566425, upload-time = "2025-05-21T12:44:08.242Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/95/33/03016a6be5663b389c8ab0bbbcca68d9e96af14faeff0a04affcb587e776/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79dc317a5f1c51fd9c6a0c4f48209c6b8526d0524a6904fc1076476e79b00f98", size = 595197, upload-time = "2025-05-21T12:44:10.449Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/33/8d/da9f4d3e208c82fda311bff0cf0a19579afceb77cf456e46c559a1c075ba/rpds_py-0.25.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1521031351865e0181bc585147624d66b3b00a84109b57fcb7a779c3ec3772cd", size = 561244, upload-time = "2025-05-21T12:44:12.387Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e2/b3/39d5dcf7c5f742ecd6dbc88f6f84ae54184b92f5f387a4053be2107b17f1/rpds_py-0.25.1-cp313-cp313-win32.whl", hash = "sha256:5d473be2b13600b93a5675d78f59e63b51b1ba2d0476893415dfbb5477e65b31", size = 222254, upload-time = "2025-05-21T12:44:14.261Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/5f/19/2d6772c8eeb8302c5f834e6d0dfd83935a884e7c5ce16340c7eaf89ce925/rpds_py-0.25.1-cp313-cp313-win_amd64.whl", hash = "sha256:a7b74e92a3b212390bdce1d93da9f6488c3878c1d434c5e751cbc202c5e09500", size = 234741, upload-time = "2025-05-21T12:44:16.236Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/5b/5a/145ada26cfaf86018d0eb304fe55eafdd4f0b6b84530246bb4a7c4fb5c4b/rpds_py-0.25.1-cp313-cp313-win_arm64.whl", hash = "sha256:dd326a81afe332ede08eb39ab75b301d5676802cdffd3a8f287a5f0b694dc3f5", size = 224830, upload-time = "2025-05-21T12:44:17.749Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/4b/ca/d435844829c384fd2c22754ff65889c5c556a675d2ed9eb0e148435c6690/rpds_py-0.25.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:a58d1ed49a94d4183483a3ce0af22f20318d4a1434acee255d683ad90bf78129", size = 359668, upload-time = "2025-05-21T12:44:19.322Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/1f/01/b056f21db3a09f89410d493d2f6614d87bb162499f98b649d1dbd2a81988/rpds_py-0.25.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f251bf23deb8332823aef1da169d5d89fa84c89f67bdfb566c49dea1fccfd50d", size = 345649, upload-time = "2025-05-21T12:44:20.962Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/e0/0f/e0d00dc991e3d40e03ca36383b44995126c36b3eafa0ccbbd19664709c88/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dbd586bfa270c1103ece2109314dd423df1fa3d9719928b5d09e4840cec0d72", size = 384776, upload-time = "2025-05-21T12:44:22.516Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9f/a2/59374837f105f2ca79bde3c3cd1065b2f8c01678900924949f6392eab66d/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6d273f136e912aa101a9274c3145dcbddbe4bac560e77e6d5b3c9f6e0ed06d34", size = 395131, upload-time = "2025-05-21T12:44:24.147Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/9c/dc/48e8d84887627a0fe0bac53f0b4631e90976fd5d35fff8be66b8e4f3916b/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:666fa7b1bd0a3810a7f18f6d3a25ccd8866291fbbc3c9b912b917a6715874bb9", size = 520942, upload-time = "2025-05-21T12:44:25.915Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/7c/f5/ee056966aeae401913d37befeeab57a4a43a4f00099e0a20297f17b8f00c/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:921954d7fbf3fccc7de8f717799304b14b6d9a45bbeec5a8d7408ccbf531faf5", size = 411330, upload-time = "2025-05-21T12:44:27.638Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ab/74/b2cffb46a097cefe5d17f94ede7a174184b9d158a0aeb195f39f2c0361e8/rpds_py-0.25.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3d86373ff19ca0441ebeb696ef64cb58b8b5cbacffcda5a0ec2f3911732a194", size = 387339, upload-time = "2025-05-21T12:44:29.292Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/7f/9a/0ff0b375dcb5161c2b7054e7d0b7575f1680127505945f5cabaac890bc07/rpds_py-0.25.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c8980cde3bb8575e7c956a530f2c217c1d6aac453474bf3ea0f9c89868b531b6", size = 418077, upload-time = "2025-05-21T12:44:30.877Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/0d/a1/fda629bf20d6b698ae84c7c840cfb0e9e4200f664fc96e1f456f00e4ad6e/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:8eb8c84ecea987a2523e057c0d950bcb3f789696c0499290b8d7b3107a719d78", size = 562441, upload-time = "2025-05-21T12:44:32.541Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/20/15/ce4b5257f654132f326f4acd87268e1006cc071e2c59794c5bdf4bebbb51/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:e43a005671a9ed5a650f3bc39e4dbccd6d4326b24fb5ea8be5f3a43a6f576c72", size = 590750, upload-time = "2025-05-21T12:44:34.557Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/fb/ab/e04bf58a8d375aeedb5268edcc835c6a660ebf79d4384d8e0889439448b0/rpds_py-0.25.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:58f77c60956501a4a627749a6dcb78dac522f249dd96b5c9f1c6af29bfacfb66", size = 558891, upload-time = "2025-05-21T12:44:37.358Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/90/82/cb8c6028a6ef6cd2b7991e2e4ced01c854b6236ecf51e81b64b569c43d73/rpds_py-0.25.1-cp313-cp313t-win32.whl", hash = "sha256:2cb9e5b5e26fc02c8a4345048cd9998c2aca7c2712bd1b36da0c72ee969a3523", size = 218718, upload-time = "2025-05-21T12:44:38.969Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/b6/97/5a4b59697111c89477d20ba8a44df9ca16b41e737fa569d5ae8bff99e650/rpds_py-0.25.1-cp313-cp313t-win_amd64.whl", hash = "sha256:401ca1c4a20cc0510d3435d89c069fe0a9ae2ee6495135ac46bdd49ec0495763", size = 232218, upload-time = "2025-05-21T12:44:40.512Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -2900,14 +2887,14 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "s3transfer" | ||||
| version = "0.12.0" | ||||
| version = "0.13.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "botocore" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/fc/9e/73b14aed38ee1f62cd30ab93cd0072dec7fb01f3033d116875ae3e7b8b44/s3transfer-0.12.0.tar.gz", hash = "sha256:8ac58bc1989a3fdb7c7f3ee0918a66b160d038a147c7b5db1500930a607e9a1c", size = 149178, upload-time = "2025-04-22T21:08:09.787Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/ed/5d/9dcc100abc6711e8247af5aa561fc07c4a046f72f659c3adea9a449e191a/s3transfer-0.13.0.tar.gz", hash = "sha256:f5e6db74eb7776a37208001113ea7aa97695368242b364d73e91c981ac522177", size = 150232, upload-time = "2025-05-22T19:24:50.245Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/89/64/d2b49620039b82688aeebd510bd62ff4cdcdb86cbf650cc72ae42c5254a3/s3transfer-0.12.0-py3-none-any.whl", hash = "sha256:35b314d7d82865756edab59f7baebc6b477189e6ab4c53050e28c1de4d9cce18", size = 84773, upload-time = "2025-04-22T21:08:08.265Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/18/17/22bf8155aa0ea2305eefa3a6402e040df7ebe512d1310165eda1e233c3f8/s3transfer-0.13.0-py3-none-any.whl", hash = "sha256:0148ef34d6dd964d0d8cf4311b2b21c474693e57c2e069ec708ce043d2b527be", size = 85152, upload-time = "2025-05-22T19:24:48.703Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -3001,11 +2988,11 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "setuptools" | ||||
| version = "80.4.0" | ||||
| version = "80.9.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/95/32/0cc40fe41fd2adb80a2f388987f4f8db3c866c69e33e0b4c8b093fdf700e/setuptools-80.4.0.tar.gz", hash = "sha256:5a78f61820bc088c8e4add52932ae6b8cf423da2aff268c23f813cfbb13b4006", size = 1315008, upload-time = "2025-05-09T20:42:27.972Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/18/5d/3bf57dcd21979b887f014ea83c24ae194cfcd12b9e0fda66b957c69d1fca/setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c", size = 1319958, upload-time = "2025-05-27T00:56:51.443Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/b1/93/dba5ed08c2e31ec7cdc2ce75705a484ef0be1a2fecac8a58272489349de8/setuptools-80.4.0-py3-none-any.whl", hash = "sha256:6cdc8cb9a7d590b237dbe4493614a9b75d0559b888047c1f67d49ba50fc3edb2", size = 1200812, upload-time = "2025-05-09T20:42:25.325Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a3/dc/17031897dae0efacfea57dfd3a82fdd2a2aeb58e0ff71b77b87e44edc772/setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922", size = 1201486, upload-time = "2025-05-27T00:56:49.664Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -3055,11 +3042,11 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "std-uritemplate" | ||||
| version = "2.0.3" | ||||
| version = "2.0.5" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/d8/dd/7b24308aa0a35d14d3f87a54d7c74307e0efbe08c9af092960bd25d83419/std_uritemplate-2.0.3.tar.gz", hash = "sha256:ad4cb1d671bcf4a3608b3598c687be4b0929867c53a2d69c105989da6a5a2d4c", size = 6016, upload-time = "2025-02-07T12:23:38.504Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/74/cc/f3d2e47d2fe828da95321ab0f4ac54e4a02294c86832469de33a048f6061/std_uritemplate-2.0.5.tar.gz", hash = "sha256:7703a886cce59d155c21b5acf1ad8d48db9f3322de98fa783a8396fbf35cbc06", size = 6015, upload-time = "2025-05-14T13:10:36.139Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/d3/18/43e8185dd1545b9cd019a2e3f4bfb6df29ebcbe4b7c5273d647226bc0616/std_uritemplate-2.0.3-py3-none-any.whl", hash = "sha256:434df26453bf68c6077879fed6609b2c39e2fc73080e74cd157269d5f8abdb3e", size = 6506, upload-time = "2025-02-07T12:23:36.096Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/7e/21/479d27b4597c6bf278e794ccceae40f721bc1cb0ff66a30ecb9bfb61ac9a/std_uritemplate-2.0.5-py3-none-any.whl", hash = "sha256:0f5184f8e6f315a01f92cfbed335f62f087e453e79cd586b67a724211e686c28", size = 6509, upload-time = "2025-05-14T13:10:34.983Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -3076,11 +3063,11 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "structlog" | ||||
| version = "25.3.0" | ||||
| version = "25.4.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/ff/6a/b0b6d440e429d2267076c4819300d9929563b1da959cf1f68afbcd69fe45/structlog-25.3.0.tar.gz", hash = "sha256:8dab497e6f6ca962abad0c283c46744185e0c9ba900db52a423cb6db99f7abeb", size = 1367514, upload-time = "2025-04-25T16:00:39.167Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/79/b9/6e672db4fec07349e7a8a8172c1a6ae235c58679ca29c3f86a61b5e59ff3/structlog-25.4.0.tar.gz", hash = "sha256:186cd1b0a8ae762e29417095664adf1d6a31702160a46dacb7796ea82f7409e4", size = 1369138, upload-time = "2025-06-02T08:21:12.971Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/f5/52/7a2c7a317b254af857464da3d60a0d3730c44f912f8c510c76a738a207fd/structlog-25.3.0-py3-none-any.whl", hash = "sha256:a341f5524004c158498c3127eecded091eb67d3a611e7a3093deca30db06e172", size = 68240, upload-time = "2025-04-25T16:00:37.295Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a0/4a/97ee6973e3a73c74c8120d59829c3861ea52210667ec3e7a16045c62b64d/structlog-25.4.0-py3-none-any.whl", hash = "sha256:fe809ff5c27e557d14e613f45ca441aabda051d119ee5a0102aaba6ce40eed2c", size = 68720, upload-time = "2025-06-02T08:21:11.43Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -3161,7 +3148,7 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "twilio" | ||||
| version = "9.6.1" | ||||
| version = "9.6.2" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "aiohttp" }, | ||||
| @ -3169,9 +3156,9 @@ dependencies = [ | ||||
|     { name = "pyjwt" }, | ||||
|     { name = "requests" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/95/78/453ff0d35442c53490c22d077f580684a2352846c721d3e01f4c6dfa85bd/twilio-9.6.1.tar.gz", hash = "sha256:bb80b31d4d9e55c33872efef7fb99373149ed4093f21c56cf582797da45862f5", size = 987002, upload-time = "2025-05-13T09:56:55.183Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/fa/c9/441a07f6552f2b504812501d56c41bd85b02afeef6c23ab8baf41ed6c70e/twilio-9.6.2.tar.gz", hash = "sha256:5da13bb497e39ece34cb9f2b3bc911f3288928612748f7688b3bda262c2767a1", size = 1041300, upload-time = "2025-05-29T12:25:04.59Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/02/f4/36fe2566a3ad7f71a89fd28ea2ebb6b2aa05c3a4d5a55b3ca6c358768c6b/twilio-9.6.1-py2.py3-none-any.whl", hash = "sha256:441fdab61b9a204eef770368380b962cbf08dc0fe9f757fe4b1d63ced37ddeed", size = 1859407, upload-time = "2025-05-13T09:56:53.094Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/67/91/382e83e5d205a7ae4325b66d40cd2fa6ce85526f2ed8fc553265e19abbe4/twilio-9.6.2-py2.py3-none-any.whl", hash = "sha256:8d4af6f42850734a921857df42940f7fed84e3e4a508d0d6bef5b9fb7dc08357", size = 1909253, upload-time = "2025-05-29T12:25:02.521Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -3219,23 +3206,23 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "typing-extensions" | ||||
| version = "4.13.2" | ||||
| version = "4.14.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/d1/bc/51647cd02527e87d05cb083ccc402f93e441606ff1f01739a62c8ad09ba5/typing_extensions-4.14.0.tar.gz", hash = "sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4", size = 107423, upload-time = "2025-06-02T14:52:11.399Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/69/e0/552843e0d356fbb5256d21449fa957fa4eff3bbc135a74a691ee70c7c5da/typing_extensions-4.14.0-py3-none-any.whl", hash = "sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af", size = 43839, upload-time = "2025-06-02T14:52:10.026Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "typing-inspection" | ||||
| version = "0.4.0" | ||||
| version = "0.4.1" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "typing-extensions" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222, upload-time = "2025-02-25T17:27:59.638Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125, upload-time = "2025-02-25T17:27:57.754Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -3278,11 +3265,11 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "uritemplate" | ||||
| version = "4.1.1" | ||||
| version = "4.2.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/d2/5a/4742fdba39cd02a56226815abfa72fe0aa81c33bed16ed045647d6000eba/uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0", size = 273898, upload-time = "2021-10-13T11:15:14.84Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/98/60/f174043244c5306c9988380d2cb10009f91563fc4b31293d27e17201af56/uritemplate-4.2.0.tar.gz", hash = "sha256:480c2ed180878955863323eea31b0ede668795de182617fef9c6ca09e6ec9d0e", size = 33267, upload-time = "2025-06-02T15:12:06.318Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/81/c0/7461b49cd25aeece13766f02ee576d1db528f1c37ce69aee300e075b485b/uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e", size = 10356, upload-time = "2021-10-13T11:15:12.316Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a9/99/3ae339466c9183ea5b8ae87b34c0b897eda475d2aec2307cae60e5cd4f29/uritemplate-4.2.0-py3-none-any.whl", hash = "sha256:962201ba1c4edcab02e60f9a0d3821e82dfc5d2d6662a21abd533879bdb8a686", size = 11488, upload-time = "2025-06-02T15:12:03.405Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| @ -3301,15 +3288,15 @@ socks = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "uvicorn" | ||||
| version = "0.34.2" | ||||
| version = "0.34.3" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| dependencies = [ | ||||
|     { name = "click" }, | ||||
|     { name = "h11" }, | ||||
| ] | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload-time = "2025-04-19T06:02:50.101Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631, upload-time = "2025-06-01T07:48:17.531Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload-time = "2025-04-19T06:02:48.42Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431, upload-time = "2025-06-01T07:48:15.664Z" }, | ||||
| ] | ||||
|  | ||||
| [package.optional-dependencies] | ||||
| @ -3443,37 +3430,6 @@ wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wrapt" | ||||
| version = "1.17.2" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/c3/fc/e91cc220803d7bc4db93fb02facd8461c37364151b8494762cc88b0fbcef/wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", size = 55531, upload-time = "2025-01-14T10:35:45.465Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/ce/b9/0ffd557a92f3b11d4c5d5e0c5e4ad057bd9eb8586615cdaf901409920b14/wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", size = 53800, upload-time = "2025-01-14T10:34:21.571Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/c0/ef/8be90a0b7e73c32e550c73cfb2fa09db62234227ece47b0e80a05073b375/wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", size = 38824, upload-time = "2025-01-14T10:34:22.999Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/36/89/0aae34c10fe524cce30fe5fc433210376bce94cf74d05b0d68344c8ba46e/wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", size = 38920, upload-time = "2025-01-14T10:34:25.386Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/3b/24/11c4510de906d77e0cfb5197f1b1445d4fec42c9a39ea853d482698ac681/wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", size = 88690, upload-time = "2025-01-14T10:34:28.058Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/71/d7/cfcf842291267bf455b3e266c0c29dcb675b5540ee8b50ba1699abf3af45/wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", size = 80861, upload-time = "2025-01-14T10:34:29.167Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/d5/66/5d973e9f3e7370fd686fb47a9af3319418ed925c27d72ce16b791231576d/wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", size = 89174, upload-time = "2025-01-14T10:34:31.702Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a7/d3/8e17bb70f6ae25dabc1aaf990f86824e4fd98ee9cadf197054e068500d27/wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", size = 86721, upload-time = "2025-01-14T10:34:32.91Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/6f/54/f170dfb278fe1c30d0ff864513cff526d624ab8de3254b20abb9cffedc24/wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", size = 79763, upload-time = "2025-01-14T10:34:34.903Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/4a/98/de07243751f1c4a9b15c76019250210dd3486ce098c3d80d5f729cba029c/wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", size = 87585, upload-time = "2025-01-14T10:34:36.13Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/f9/f0/13925f4bd6548013038cdeb11ee2cbd4e37c30f8bfd5db9e5a2a370d6e20/wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", size = 36676, upload-time = "2025-01-14T10:34:37.962Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/bf/ae/743f16ef8c2e3628df3ddfd652b7d4c555d12c84b53f3d8218498f4ade9b/wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", size = 38871, upload-time = "2025-01-14T10:34:39.13Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/3d/bc/30f903f891a82d402ffb5fda27ec1d621cc97cb74c16fea0b6141f1d4e87/wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", size = 56312, upload-time = "2025-01-14T10:34:40.604Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/8a/04/c97273eb491b5f1c918857cd26f314b74fc9b29224521f5b83f872253725/wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", size = 40062, upload-time = "2025-01-14T10:34:45.011Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/4e/ca/3b7afa1eae3a9e7fefe499db9b96813f41828b9fdb016ee836c4c379dadb/wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", size = 40155, upload-time = "2025-01-14T10:34:47.25Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/89/be/7c1baed43290775cb9030c774bc53c860db140397047cc49aedaf0a15477/wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", size = 113471, upload-time = "2025-01-14T10:34:50.934Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/32/98/4ed894cf012b6d6aae5f5cc974006bdeb92f0241775addad3f8cd6ab71c8/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", size = 101208, upload-time = "2025-01-14T10:34:52.297Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ea/fd/0c30f2301ca94e655e5e057012e83284ce8c545df7661a78d8bfca2fac7a/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", size = 109339, upload-time = "2025-01-14T10:34:53.489Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/75/56/05d000de894c4cfcb84bcd6b1df6214297b8089a7bd324c21a4765e49b14/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", size = 110232, upload-time = "2025-01-14T10:34:55.327Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/53/f8/c3f6b2cf9b9277fb0813418e1503e68414cd036b3b099c823379c9575e6d/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", size = 100476, upload-time = "2025-01-14T10:34:58.055Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/a7/b1/0bb11e29aa5139d90b770ebbfa167267b1fc548d2302c30c8f7572851738/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", size = 106377, upload-time = "2025-01-14T10:34:59.3Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/6a/e1/0122853035b40b3f333bbb25f1939fc1045e21dd518f7f0922b60c156f7c/wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", size = 37986, upload-time = "2025-01-14T10:35:00.498Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/09/5e/1655cf481e079c1f22d0cabdd4e51733679932718dc23bf2db175f329b76/wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", size = 40750, upload-time = "2025-01-14T10:35:03.378Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594, upload-time = "2025-01-14T10:35:44.018Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
| name = "wsproto" | ||||
| version = "1.2.0" | ||||
| @ -3550,11 +3506,11 @@ wheels = [ | ||||
|  | ||||
| [[package]] | ||||
| name = "zipp" | ||||
| version = "3.21.0" | ||||
| version = "3.22.0" | ||||
| source = { registry = "https://pypi.org/simple" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545, upload-time = "2024-11-10T15:05:20.202Z" } | ||||
| sdist = { url = "https://files.pythonhosted.org/packages/12/b6/7b3d16792fdf94f146bed92be90b4eb4563569eca91513c8609aebf0c167/zipp-3.22.0.tar.gz", hash = "sha256:dd2f28c3ce4bc67507bfd3781d21b7bb2be31103b51a4553ad7d90b84e57ace5", size = 25257, upload-time = "2025-05-26T14:46:32.217Z" } | ||||
| wheels = [ | ||||
|     { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630, upload-time = "2024-11-10T15:05:19.275Z" }, | ||||
|     { url = "https://files.pythonhosted.org/packages/ad/da/f64669af4cae46f17b90798a827519ce3737d31dbafad65d391e49643dc4/zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343", size = 9796, upload-time = "2025-05-26T14:46:30.775Z" }, | ||||
| ] | ||||
|  | ||||
| [[package]] | ||||
|  | ||||
							
								
								
									
										1823
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1823
									
								
								web/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -93,7 +93,7 @@ | ||||
|         "@floating-ui/dom": "^1.6.11", | ||||
|         "@formatjs/intl-listformat": "^7.7.11", | ||||
|         "@fortawesome/fontawesome-free": "^6.6.0", | ||||
|         "@goauthentik/api": "^2025.4.1-1747687715", | ||||
|         "@goauthentik/api": "^2025.6.0-1749054550", | ||||
|         "@lit/context": "^1.1.2", | ||||
|         "@lit/localize": "^0.12.2", | ||||
|         "@lit/reactive-element": "^2.0.4", | ||||
| @ -102,7 +102,7 @@ | ||||
|         "@open-wc/lit-helpers": "^0.7.0", | ||||
|         "@patternfly/elements": "^4.1.0", | ||||
|         "@patternfly/patternfly": "^4.224.2", | ||||
|         "@sentry/browser": "^9.22.0", | ||||
|         "@sentry/browser": "^9.24.0", | ||||
|         "@spotlightjs/spotlight": "^2.13.3", | ||||
|         "@webcomponents/webcomponentsjs": "^2.8.0", | ||||
|         "base64-js": "^1.5.1", | ||||
| @ -111,7 +111,7 @@ | ||||
|         "chartjs-adapter-date-fns": "^3.0.0", | ||||
|         "codemirror": "^6.0.1", | ||||
|         "construct-style-sheets-polyfill": "^3.1.0", | ||||
|         "core-js": "^3.38.1", | ||||
|         "core-js": "^3.42.0", | ||||
|         "country-flag-icons": "^1.5.19", | ||||
|         "date-fns": "^4.1.0", | ||||
|         "deepmerge-ts": "^7.1.5", | ||||
| @ -152,6 +152,7 @@ | ||||
|         "@storybook/addon-essentials": "^8.6.14", | ||||
|         "@storybook/addon-links": "^8.6.14", | ||||
|         "@storybook/blocks": "^8.6.12", | ||||
|         "@storybook/channels": "^8.6.14", | ||||
|         "@storybook/experimental-addon-test": "^8.6.14", | ||||
|         "@storybook/manager-api": "^8.6.14", | ||||
|         "@storybook/test": "^8.6.14", | ||||
| @ -174,11 +175,11 @@ | ||||
|         "@wdio/spec-reporter": "^9.1.2", | ||||
|         "@web/test-runner": "^0.20.2", | ||||
|         "chromedriver": "^136.0.3", | ||||
|         "esbuild": "^0.25.4", | ||||
|         "esbuild": "^0.25.5", | ||||
|         "esbuild-plugin-copy": "^2.1.1", | ||||
|         "esbuild-plugin-polyfill-node": "^0.3.0", | ||||
|         "esbuild-plugins-node-modules-polyfill": "^1.7.0", | ||||
|         "eslint": "^9.11.1", | ||||
|         "eslint": "^9.28.0", | ||||
|         "eslint-plugin-lit": "^2.1.1", | ||||
|         "eslint-plugin-wc": "^3.0.1", | ||||
|         "github-slugger": "^2.0.0", | ||||
| @ -193,7 +194,7 @@ | ||||
|         "storybook-addon-mock": "^5.0.0", | ||||
|         "turnstile-types": "^1.2.3", | ||||
|         "typescript": "^5.8.3", | ||||
|         "typescript-eslint": "^8.32.1", | ||||
|         "typescript-eslint": "^8.33.0", | ||||
|         "vite-plugin-lit-css": "^2.0.0", | ||||
|         "vite-tsconfig-paths": "^5.0.1", | ||||
|         "wireit": "^0.14.12" | ||||
|  | ||||
							
								
								
									
										59
									
								
								web/packages/esbuild-plugin-live-reload/.github/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								web/packages/esbuild-plugin-live-reload/.github/README.md
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | ||||
| _An ESBuild development plugin that watches for file changes and triggers automatic browser refreshes._ | ||||
|  | ||||
| ## Quick start | ||||
|  | ||||
| ```sh | ||||
| npm install -D @goauthentik/esbuild-plugin-live-reload | ||||
| # Or with Yarn: | ||||
| yarn add -D @goauthentik/esbuild-plugin-live-reload | ||||
| ``` | ||||
|  | ||||
| ### 1. Configure ESBuild | ||||
|  | ||||
| ```js | ||||
| import { liveReloadPlugin } from "@goauthentik/esbuild-plugin-live-reload"; | ||||
| import esbuild from "esbuild"; | ||||
|  | ||||
| const NodeEnvironment = process.env.NODE_ENV || "development"; | ||||
|  | ||||
| /** | ||||
|  * @type {esbuild.BuildOptions} | ||||
|  */ | ||||
| const buildOptions = { | ||||
|     // ... Your build options. | ||||
|     define: { | ||||
|         "process.env.NODE_ENV": JSON.stringify(NodeEnvironment), | ||||
|     }, | ||||
|     plugins: [ | ||||
|         /** @see {@link LiveReloadPluginOptions} */ | ||||
|         liveReloadPlugin(), | ||||
|     ], | ||||
| }; | ||||
|  | ||||
| const buildContext = await esbuild.context(buildOptions); | ||||
|  | ||||
| await buildContext.rebuild(); | ||||
| await buildContext.watch(); | ||||
| ``` | ||||
|  | ||||
| ### 2. Connect your browser | ||||
|  | ||||
| Add the following import near the beginning of your application's entry point. | ||||
|  | ||||
| ```js | ||||
| if (process.env.NODE_ENV === "development") { | ||||
|     await import("@goauthentik/esbuild-plugin-live-reload/client"); | ||||
| } | ||||
| ``` | ||||
|  | ||||
| That's it! Your browser will now automatically refresh whenever ESBuild finishes rebuilding your code. | ||||
|  | ||||
| ## About authentik | ||||
|  | ||||
| [authentik](https://goauthentik.io) is an open source Identity Provider that unifies your identity needs into a single platform, replacing Okta, Active Directory, and Auth0. | ||||
|  | ||||
| We built this plugin to streamline our development workflow, and we're sharing it with the community. If you have any questions, feature requests, or bug reports, please [open an issue](https://github.com/goauthentik/authentik/issues/new/choose). | ||||
|  | ||||
| ## License | ||||
|  | ||||
| This code is licensed under the [MIT License](https://www.tldrlegal.com/license/mit-license) | ||||
							
								
								
									
										3
									
								
								web/packages/esbuild-plugin-live-reload/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/packages/esbuild-plugin-live-reload/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| README.md | ||||
| node_modules | ||||
| _media | ||||
							
								
								
									
										3
									
								
								web/packages/esbuild-plugin-live-reload/.prettierignore
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								web/packages/esbuild-plugin-live-reload/.prettierignore
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| node_modules | ||||
| ./README.md | ||||
| out | ||||
							
								
								
									
										18
									
								
								web/packages/esbuild-plugin-live-reload/LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								web/packages/esbuild-plugin-live-reload/LICENSE.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| The MIT License (MIT) | ||||
|  | ||||
| Copyright (c) 2025 Authentik Security, Inc. | ||||
|  | ||||
| Permission is hereby granted, free of charge, to any person obtaining a copy of this software and | ||||
| associated documentation files (the "Software"), to deal in the Software without restriction, | ||||
| including without limitation the rights to use, copy, modify, merge, publish, distribute, | ||||
| sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is | ||||
| furnished to do so, subject to the following conditions: | ||||
|  | ||||
| The above copyright notice and this permission notice shall be included in all copies or substantial | ||||
| portions of the Software. | ||||
|  | ||||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT | ||||
| NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||||
| NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES | ||||
| OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | ||||
| CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	