Compare commits
101 Commits
version/20
...
web/legibi
Author | SHA1 | Date | |
---|---|---|---|
1bc8fa0a9d | |||
91572b8621 | |||
080d31f189 | |||
15b59594e2 | |||
b4e295a14a | |||
b590b6be44 | |||
15ee3d3566 | |||
aea6c7adbe | |||
42a2337200 | |||
ffdd49e176 | |||
b41231141c | |||
88d3b7f5a4 | |||
2b39748c84 | |||
93b93517be | |||
6da55dc8aa | |||
b93dc48030 | |||
7aba4b0c01 | |||
d5572a2570 | |||
55b1ddff6e | |||
77c913bfd3 | |||
69b80e5bb5 | |||
ba63399a7b | |||
86893d83b8 | |||
85ab201803 | |||
2c96b24b62 | |||
1f2cbca833 | |||
c2db998041 | |||
18a70e93a1 | |||
3123b3ac5e | |||
f2e1b6d466 | |||
6bcacd744b | |||
e5af964d9d | |||
122b95197b | |||
8d4e7f5d55 | |||
9d32ba261a | |||
b5a9b645f4 | |||
46303cc59f | |||
4af415f3fd | |||
ef82143811 | |||
c7567e031a | |||
3b2cd9e8d6 | |||
261e18b3d6 | |||
51a0f7d314 | |||
041ffef812 | |||
68b4d58ebd | |||
881571bd14 | |||
64a0f66e62 | |||
7d5cda4c25 | |||
8ba2679036 | |||
d98523f243 | |||
6da0548fa2 | |||
8734710e61 | |||
64b996aa1f | |||
dbe91cbc55 | |||
a56e037eae | |||
b8f1e2fac0 | |||
e1b56aac05 | |||
794731eed7 | |||
19fbc2a022 | |||
38e467bf8e | |||
9e32cf361b | |||
42a5a43640 | |||
8d5b835c4f | |||
ca3b948895 | |||
a714c781a6 | |||
df2e3878d5 | |||
1370c32aea | |||
0ae373bc1e | |||
6facb5872e | |||
c67de17dd8 | |||
2128e7f45f | |||
0e7a4849f6 | |||
85343fa5d4 | |||
3ec0d30965 | |||
50d2f69332 | |||
7d972ec711 | |||
854427e463 | |||
be349e2e14 | |||
bd0e81b8ad | |||
f6afb59515 | |||
dddde09be5 | |||
6d7fc94698 | |||
1dcf9108ad | |||
7bb6a3dfe6 | |||
9cc440eee1 | |||
fe9e4526ac | |||
20b66f850c | |||
67b327414b | |||
5b8d86b5a9 | |||
67aed3e318 | |||
9809b94030 | |||
e7527c551b | |||
36b10b434a | |||
831797b871 | |||
5cc2c0f45f | |||
32442766f4 | |||
75790909a8 | |||
e0d5df89ca | |||
f25a9c624e | |||
914993a788 | |||
89dad07a66 |
@ -1,16 +1,16 @@
|
||||
[bumpversion]
|
||||
current_version = 2024.12.3
|
||||
current_version = 2025.2.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*))?
|
||||
serialize =
|
||||
serialize =
|
||||
{major}.{minor}.{patch}-{rc_t}{rc_n}
|
||||
{major}.{minor}.{patch}
|
||||
message = release: {new_version}
|
||||
tag_name = version/{new_version}
|
||||
|
||||
[bumpversion:part:rc_t]
|
||||
values =
|
||||
values =
|
||||
rc
|
||||
final
|
||||
optional_value = final
|
||||
|
6
.github/ISSUE_TEMPLATE/bug_report.md
vendored
6
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -28,7 +28,11 @@ Output of docker-compose logs or kubectl logs respectively
|
||||
|
||||
**Version and Deployment (please complete the following information):**
|
||||
|
||||
- authentik version: [e.g. 2021.8.5]
|
||||
<!--
|
||||
Notice: authentik supports installation via Docker, Kubernetes, and AWS CloudFormation only. Support is not available for other methods. For detailed installation and configuration instructions, please refer to the official documentation at https://docs.goauthentik.io/docs/install-config/.
|
||||
-->
|
||||
|
||||
- authentik version: [e.g. 2025.2.0]
|
||||
- Deployment: [e.g. docker-compose, helm]
|
||||
|
||||
**Additional context**
|
||||
|
7
.github/ISSUE_TEMPLATE/question.md
vendored
7
.github/ISSUE_TEMPLATE/question.md
vendored
@ -20,7 +20,12 @@ Output of docker-compose logs or kubectl logs respectively
|
||||
|
||||
**Version and Deployment (please complete the following information):**
|
||||
|
||||
- authentik version: [e.g. 2021.8.5]
|
||||
<!--
|
||||
Notice: authentik supports installation via Docker, Kubernetes, and AWS CloudFormation only. Support is not available for other methods. For detailed installation and configuration instructions, please refer to the official documentation at https://docs.goauthentik.io/docs/install-config/.
|
||||
-->
|
||||
|
||||
|
||||
- authentik version: [e.g. 2025.2.0]
|
||||
- Deployment: [e.g. docker-compose, helm]
|
||||
|
||||
**Additional context**
|
||||
|
2
.github/actions/setup/action.yml
vendored
2
.github/actions/setup/action.yml
vendored
@ -35,7 +35,7 @@ runs:
|
||||
run: |
|
||||
export PSQL_TAG=${{ inputs.postgresql_version }}
|
||||
docker compose -f .github/actions/setup/docker-compose.yml up -d
|
||||
poetry install --sync
|
||||
poetry sync
|
||||
cd web && npm ci
|
||||
- name: Generate config
|
||||
shell: poetry run python {0}
|
||||
|
@ -1,9 +1,13 @@
|
||||
---
|
||||
name: authentik-backend-translate-extract-compile
|
||||
name: authentik-translate-extract-compile
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *" # every day at midnight
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
- version-*
|
||||
|
||||
env:
|
||||
POSTGRES_DB: authentik
|
||||
@ -32,6 +36,7 @@ jobs:
|
||||
poetry run ak compilemessages
|
||||
make web-check-compile
|
||||
- name: Create Pull Request
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
uses: peter-evans/create-pull-request@v7
|
||||
with:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
|
@ -20,8 +20,8 @@ Even if the issue is not a CVE, we still greatly appreciate your help in hardeni
|
||||
|
||||
| Version | Supported |
|
||||
| --------- | --------- |
|
||||
| 2024.10.x | ✅ |
|
||||
| 2024.12.x | ✅ |
|
||||
| 2025.2.x | ✅ |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
from os import environ
|
||||
|
||||
__version__ = "2024.12.3"
|
||||
__version__ = "2025.2.0"
|
||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
||||
|
||||
|
||||
|
@ -50,7 +50,6 @@ from authentik.enterprise.providers.microsoft_entra.models import (
|
||||
MicrosoftEntraProviderGroup,
|
||||
MicrosoftEntraProviderUser,
|
||||
)
|
||||
from authentik.enterprise.providers.rac.models import ConnectionToken
|
||||
from authentik.enterprise.providers.ssf.models import StreamEvent
|
||||
from authentik.enterprise.stages.authenticator_endpoint_gdtc.models import (
|
||||
EndpointDevice,
|
||||
@ -72,6 +71,7 @@ from authentik.providers.oauth2.models import (
|
||||
DeviceToken,
|
||||
RefreshToken,
|
||||
)
|
||||
from authentik.providers.rac.models import ConnectionToken
|
||||
from authentik.providers.scim.models import SCIMProviderGroup, SCIMProviderUser
|
||||
from authentik.rbac.models import Role
|
||||
from authentik.sources.scim.models import SCIMSourceGroup, SCIMSourceUser
|
||||
|
@ -35,8 +35,7 @@ from authentik.flows.planner import (
|
||||
FlowPlanner,
|
||||
)
|
||||
from authentik.flows.stage import StageView
|
||||
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET, SESSION_KEY_PLAN
|
||||
from authentik.lib.utils.urls import redirect_with_qs
|
||||
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET
|
||||
from authentik.lib.views import bad_request_message
|
||||
from authentik.policies.denied import AccessDeniedResponse
|
||||
from authentik.policies.utils import delete_none_values
|
||||
@ -47,8 +46,9 @@ from authentik.stages.user_write.stage import PLAN_CONTEXT_USER_PATH
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
SESSION_KEY_OVERRIDE_FLOW_TOKEN = "authentik/flows/source_override_flow_token" # nosec
|
||||
PLAN_CONTEXT_SOURCE_GROUPS = "source_groups"
|
||||
SESSION_KEY_SOURCE_FLOW_STAGES = "authentik/flows/source_flow_stages"
|
||||
SESSION_KEY_OVERRIDE_FLOW_TOKEN = "authentik/flows/source_override_flow_token" # nosec
|
||||
|
||||
|
||||
class MessageStage(StageView):
|
||||
@ -219,28 +219,28 @@ class SourceFlowManager:
|
||||
}
|
||||
)
|
||||
flow_context.update(self.policy_context)
|
||||
if SESSION_KEY_OVERRIDE_FLOW_TOKEN in self.request.session:
|
||||
token: FlowToken = self.request.session.get(SESSION_KEY_OVERRIDE_FLOW_TOKEN)
|
||||
self._logger.info("Replacing source flow with overridden flow", flow=token.flow.slug)
|
||||
plan = token.plan
|
||||
plan.context[PLAN_CONTEXT_IS_RESTORED] = token
|
||||
plan.context.update(flow_context)
|
||||
for stage in self.get_stages_to_append(flow):
|
||||
plan.append_stage(stage)
|
||||
if stages:
|
||||
for stage in stages:
|
||||
plan.append_stage(stage)
|
||||
self.request.session[SESSION_KEY_PLAN] = plan
|
||||
flow_slug = token.flow.slug
|
||||
token.delete()
|
||||
return redirect_with_qs(
|
||||
"authentik_core:if-flow",
|
||||
self.request.GET,
|
||||
flow_slug=flow_slug,
|
||||
)
|
||||
flow_context.setdefault(PLAN_CONTEXT_REDIRECT, final_redirect)
|
||||
|
||||
if not flow:
|
||||
# We only check for the flow token here if we don't have a flow, otherwise we rely on
|
||||
# SESSION_KEY_SOURCE_FLOW_STAGES to delegate the usage of this token and dynamically add
|
||||
# stages that deal with this token to return to another flow
|
||||
if SESSION_KEY_OVERRIDE_FLOW_TOKEN in self.request.session:
|
||||
token: FlowToken = self.request.session.get(SESSION_KEY_OVERRIDE_FLOW_TOKEN)
|
||||
self._logger.info(
|
||||
"Replacing source flow with overridden flow", flow=token.flow.slug
|
||||
)
|
||||
plan = token.plan
|
||||
plan.context[PLAN_CONTEXT_IS_RESTORED] = token
|
||||
plan.context.update(flow_context)
|
||||
for stage in self.get_stages_to_append(flow):
|
||||
plan.append_stage(stage)
|
||||
if stages:
|
||||
for stage in stages:
|
||||
plan.append_stage(stage)
|
||||
redirect = plan.to_redirect(self.request, token.flow)
|
||||
token.delete()
|
||||
return redirect
|
||||
return bad_request_message(
|
||||
self.request,
|
||||
_("Configured flow does not exist."),
|
||||
@ -259,6 +259,8 @@ class SourceFlowManager:
|
||||
if stages:
|
||||
for stage in stages:
|
||||
plan.append_stage(stage)
|
||||
for stage in self.request.session.get(SESSION_KEY_SOURCE_FLOW_STAGES, []):
|
||||
plan.append_stage(stage)
|
||||
return plan.to_redirect(self.request, flow)
|
||||
|
||||
def handle_auth(
|
||||
@ -295,6 +297,8 @@ class SourceFlowManager:
|
||||
# When request isn't authenticated we jump straight to auth
|
||||
if not self.request.user.is_authenticated:
|
||||
return self.handle_auth(connection)
|
||||
# When an override flow token exists we actually still use a flow for link
|
||||
# to continue the existing flow we came from
|
||||
if SESSION_KEY_OVERRIDE_FLOW_TOKEN in self.request.session:
|
||||
return self._prepare_flow(None, connection)
|
||||
connection.save()
|
||||
|
@ -67,6 +67,8 @@ def clean_expired_models(self: SystemTask):
|
||||
raise ImproperlyConfigured(
|
||||
"Invalid session_storage setting, allowed values are db and cache"
|
||||
)
|
||||
if CONFIG.get("session_storage", "cache") == "db":
|
||||
DBSessionStore.clear_expired()
|
||||
LOGGER.debug("Expired sessions", model=AuthenticatedSession, amount=amount)
|
||||
|
||||
messages.append(f"Expired {amount} {AuthenticatedSession._meta.verbose_name_plural}")
|
||||
|
@ -8,6 +8,8 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
|
||||
{# Darkreader breaks the site regardless of theme as its not compatible with webcomponents, and we default to a dark theme based on preferred colour-scheme #}
|
||||
<meta name="darkreader-lock">
|
||||
<title>{% block title %}{% trans title|default:brand.branding_title %}{% endblock %}</title>
|
||||
<link rel="icon" href="{{ brand.branding_favicon_url }}">
|
||||
<link rel="shortcut icon" href="{{ brand.branding_favicon_url }}">
|
||||
|
@ -1,14 +0,0 @@
|
||||
"""RAC app config"""
|
||||
|
||||
from authentik.enterprise.apps import EnterpriseConfig
|
||||
|
||||
|
||||
class AuthentikEnterpriseProviderRAC(EnterpriseConfig):
|
||||
"""authentik enterprise rac app config"""
|
||||
|
||||
name = "authentik.enterprise.providers.rac"
|
||||
label = "authentik_providers_rac"
|
||||
verbose_name = "authentik Enterprise.Providers.RAC"
|
||||
default = True
|
||||
mountpoint = ""
|
||||
ws_mountpoint = "authentik.enterprise.providers.rac.urls"
|
@ -16,7 +16,6 @@ TENANT_APPS = [
|
||||
"authentik.enterprise.audit",
|
||||
"authentik.enterprise.providers.google_workspace",
|
||||
"authentik.enterprise.providers.microsoft_entra",
|
||||
"authentik.enterprise.providers.rac",
|
||||
"authentik.enterprise.providers.ssf",
|
||||
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
|
||||
"authentik.enterprise.stages.source",
|
||||
|
@ -9,13 +9,16 @@ from django.utils.timezone import now
|
||||
from guardian.shortcuts import get_anonymous_user
|
||||
|
||||
from authentik.core.models import Source, User
|
||||
from authentik.core.sources.flow_manager import SESSION_KEY_OVERRIDE_FLOW_TOKEN
|
||||
from authentik.core.sources.flow_manager import (
|
||||
SESSION_KEY_OVERRIDE_FLOW_TOKEN,
|
||||
SESSION_KEY_SOURCE_FLOW_STAGES,
|
||||
)
|
||||
from authentik.core.types import UILoginButton
|
||||
from authentik.enterprise.stages.source.models import SourceStage
|
||||
from authentik.flows.challenge import Challenge, ChallengeResponse
|
||||
from authentik.flows.models import FlowToken
|
||||
from authentik.flows.models import FlowToken, in_memory_stage
|
||||
from authentik.flows.planner import PLAN_CONTEXT_IS_RESTORED
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.flows.stage import ChallengeStageView, StageView
|
||||
from authentik.lib.utils.time import timedelta_from_string
|
||||
|
||||
PLAN_CONTEXT_RESUME_TOKEN = "resume_token" # nosec
|
||||
@ -49,6 +52,7 @@ class SourceStageView(ChallengeStageView):
|
||||
def get_challenge(self, *args, **kwargs) -> Challenge:
|
||||
resume_token = self.create_flow_token()
|
||||
self.request.session[SESSION_KEY_OVERRIDE_FLOW_TOKEN] = resume_token
|
||||
self.request.session[SESSION_KEY_SOURCE_FLOW_STAGES] = [in_memory_stage(SourceStageFinal)]
|
||||
return self.login_button.challenge
|
||||
|
||||
def create_flow_token(self) -> FlowToken:
|
||||
@ -77,3 +81,19 @@ class SourceStageView(ChallengeStageView):
|
||||
|
||||
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
|
||||
return self.executor.stage_ok()
|
||||
|
||||
|
||||
class SourceStageFinal(StageView):
|
||||
"""Dynamic stage injected in the source flow manager. This is injected in the
|
||||
flow the source flow manager picks (authentication or enrollment), and will run at the end.
|
||||
This stage uses the override flow token to resume execution of the initial flow the
|
||||
source stage is bound to."""
|
||||
|
||||
def dispatch(self):
|
||||
token: FlowToken = self.request.session.get(SESSION_KEY_OVERRIDE_FLOW_TOKEN)
|
||||
self._logger.info("Replacing source flow with overridden flow", flow=token.flow.slug)
|
||||
plan = token.plan
|
||||
plan.context[PLAN_CONTEXT_IS_RESTORED] = token
|
||||
response = plan.to_redirect(self.request, token.flow)
|
||||
token.delete()
|
||||
return response
|
||||
|
@ -64,6 +64,8 @@ debugger: false
|
||||
log_level: info
|
||||
|
||||
session_storage: cache
|
||||
sessions:
|
||||
unauthenticated_age: days=1
|
||||
|
||||
error_reporting:
|
||||
enabled: false
|
||||
|
@ -19,7 +19,6 @@ from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.api.utils import JSONDictField, ModelSerializer, PassiveSerializer
|
||||
from authentik.core.models import Provider
|
||||
from authentik.enterprise.license import LicenseKey
|
||||
from authentik.enterprise.providers.rac.models import RACProvider
|
||||
from authentik.lib.utils.time import timedelta_from_string, timedelta_string_validator
|
||||
from authentik.outposts.api.service_connections import ServiceConnectionSerializer
|
||||
from authentik.outposts.apps import MANAGED_OUTPOST, MANAGED_OUTPOST_NAME
|
||||
@ -31,6 +30,7 @@ from authentik.outposts.models import (
|
||||
)
|
||||
from authentik.providers.ldap.models import LDAPProvider
|
||||
from authentik.providers.proxy.models import ProxyProvider
|
||||
from authentik.providers.rac.models import RACProvider
|
||||
from authentik.providers.radius.models import RadiusProvider
|
||||
|
||||
|
||||
|
@ -18,8 +18,6 @@ from kubernetes.config.kube_config import KUBE_CONFIG_DEFAULT_LOCATION
|
||||
from structlog.stdlib import get_logger
|
||||
from yaml import safe_load
|
||||
|
||||
from authentik.enterprise.providers.rac.controllers.docker import RACDockerController
|
||||
from authentik.enterprise.providers.rac.controllers.kubernetes import RACKubernetesController
|
||||
from authentik.events.models import TaskStatus
|
||||
from authentik.events.system_tasks import SystemTask, prefill_task
|
||||
from authentik.lib.config import CONFIG
|
||||
@ -41,6 +39,8 @@ from authentik.providers.ldap.controllers.docker import LDAPDockerController
|
||||
from authentik.providers.ldap.controllers.kubernetes import LDAPKubernetesController
|
||||
from authentik.providers.proxy.controllers.docker import ProxyDockerController
|
||||
from authentik.providers.proxy.controllers.kubernetes import ProxyKubernetesController
|
||||
from authentik.providers.rac.controllers.docker import RACDockerController
|
||||
from authentik.providers.rac.controllers.kubernetes import RACKubernetesController
|
||||
from authentik.providers.radius.controllers.docker import RadiusDockerController
|
||||
from authentik.providers.radius.controllers.kubernetes import RadiusKubernetesController
|
||||
from authentik.root.celery import CELERY_APP
|
||||
|
@ -128,7 +128,7 @@ class GeoIPPolicy(Policy):
|
||||
(geoip_data["lat"], geoip_data["long"]),
|
||||
)
|
||||
if self.check_history_distance and dist.km >= (
|
||||
self.history_max_distance_km - self.distance_tolerance_km
|
||||
self.history_max_distance_km + self.distance_tolerance_km
|
||||
):
|
||||
return PolicyResult(
|
||||
False, _("Distance from previous authentication is larger than threshold.")
|
||||
@ -139,7 +139,7 @@ class GeoIPPolicy(Policy):
|
||||
# clamped to be at least 1 hour
|
||||
rel_time_hours = max(int((_now - previous_login.created).total_seconds() / 3600), 1)
|
||||
if self.check_impossible_travel and dist.km >= (
|
||||
(MAX_DISTANCE_HOUR_KM * rel_time_hours) - self.distance_tolerance_km
|
||||
(MAX_DISTANCE_HOUR_KM * rel_time_hours) + self.distance_tolerance_km
|
||||
):
|
||||
return PolicyResult(False, _("Distance is further than possible."))
|
||||
return PolicyResult(True)
|
||||
|
@ -148,10 +148,10 @@ class PasswordPolicy(Policy):
|
||||
user_inputs.append(request.user.email)
|
||||
if request.http_request:
|
||||
user_inputs.append(request.http_request.brand.branding_title)
|
||||
# Only calculate result for the first 100 characters, as with over 100 char
|
||||
# Only calculate result for the first 72 characters, as with over 100 char
|
||||
# long passwords we can be reasonably sure that they'll surpass the score anyways
|
||||
# See https://github.com/dropbox/zxcvbn#runtime-latency
|
||||
results = zxcvbn(password[:100], user_inputs)
|
||||
results = zxcvbn(password[:72], user_inputs)
|
||||
LOGGER.debug("password failed", check="zxcvbn", score=results["score"])
|
||||
result = PolicyResult(results["score"] > self.zxcvbn_score_threshold)
|
||||
if not result.passing:
|
||||
|
@ -6,13 +6,12 @@ from rest_framework.viewsets import GenericViewSet
|
||||
from authentik.core.api.groups import GroupMemberSerializer
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.api.utils import ModelSerializer
|
||||
from authentik.enterprise.api import EnterpriseRequiredMixin
|
||||
from authentik.enterprise.providers.rac.api.endpoints import EndpointSerializer
|
||||
from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer
|
||||
from authentik.enterprise.providers.rac.models import ConnectionToken
|
||||
from authentik.providers.rac.api.endpoints import EndpointSerializer
|
||||
from authentik.providers.rac.api.providers import RACProviderSerializer
|
||||
from authentik.providers.rac.models import ConnectionToken
|
||||
|
||||
|
||||
class ConnectionTokenSerializer(EnterpriseRequiredMixin, ModelSerializer):
|
||||
class ConnectionTokenSerializer(ModelSerializer):
|
||||
"""ConnectionToken Serializer"""
|
||||
|
||||
provider_obj = RACProviderSerializer(source="provider", read_only=True)
|
@ -14,10 +14,9 @@ from structlog.stdlib import get_logger
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.api.utils import ModelSerializer
|
||||
from authentik.core.models import Provider
|
||||
from authentik.enterprise.api import EnterpriseRequiredMixin
|
||||
from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer
|
||||
from authentik.enterprise.providers.rac.models import Endpoint
|
||||
from authentik.policies.engine import PolicyEngine
|
||||
from authentik.providers.rac.api.providers import RACProviderSerializer
|
||||
from authentik.providers.rac.models import Endpoint
|
||||
from authentik.rbac.filters import ObjectFilter
|
||||
|
||||
LOGGER = get_logger()
|
||||
@ -28,7 +27,7 @@ def user_endpoint_cache_key(user_pk: str) -> str:
|
||||
return f"goauthentik.io/providers/rac/endpoint_access/{user_pk}"
|
||||
|
||||
|
||||
class EndpointSerializer(EnterpriseRequiredMixin, ModelSerializer):
|
||||
class EndpointSerializer(ModelSerializer):
|
||||
"""Endpoint Serializer"""
|
||||
|
||||
provider_obj = RACProviderSerializer(source="provider", read_only=True)
|
@ -10,7 +10,7 @@ from rest_framework.viewsets import ModelViewSet
|
||||
from authentik.core.api.property_mappings import PropertyMappingSerializer
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.api.utils import JSONDictField
|
||||
from authentik.enterprise.providers.rac.models import RACPropertyMapping
|
||||
from authentik.providers.rac.models import RACPropertyMapping
|
||||
|
||||
|
||||
class RACPropertyMappingSerializer(PropertyMappingSerializer):
|
@ -5,11 +5,10 @@ from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.core.api.providers import ProviderSerializer
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.enterprise.api import EnterpriseRequiredMixin
|
||||
from authentik.enterprise.providers.rac.models import RACProvider
|
||||
from authentik.providers.rac.models import RACProvider
|
||||
|
||||
|
||||
class RACProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
|
||||
class RACProviderSerializer(ProviderSerializer):
|
||||
"""RACProvider Serializer"""
|
||||
|
||||
outpost_set = ListField(child=CharField(), read_only=True, source="outpost_set.all")
|
14
authentik/providers/rac/apps.py
Normal file
14
authentik/providers/rac/apps.py
Normal file
@ -0,0 +1,14 @@
|
||||
"""RAC app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class AuthentikProviderRAC(AppConfig):
|
||||
"""authentik rac app config"""
|
||||
|
||||
name = "authentik.providers.rac"
|
||||
label = "authentik_providers_rac"
|
||||
verbose_name = "authentik Providers.RAC"
|
||||
default = True
|
||||
mountpoint = ""
|
||||
ws_mountpoint = "authentik.providers.rac.urls"
|
@ -7,22 +7,22 @@ from channels.generic.websocket import AsyncWebsocketConsumer
|
||||
from django.http.request import QueryDict
|
||||
from structlog.stdlib import BoundLogger, get_logger
|
||||
|
||||
from authentik.enterprise.providers.rac.models import ConnectionToken, RACProvider
|
||||
from authentik.outposts.consumer import OUTPOST_GROUP_INSTANCE
|
||||
from authentik.outposts.models import Outpost, OutpostState, OutpostType
|
||||
from authentik.providers.rac.models import ConnectionToken, RACProvider
|
||||
|
||||
# Global broadcast group, which messages are sent to when the outpost connects back
|
||||
# to authentik for a specific connection
|
||||
# The `RACClientConsumer` consumer adds itself to this group on connection,
|
||||
# and removes itself once it has been assigned a specific outpost channel
|
||||
RAC_CLIENT_GROUP = "group_enterprise_rac_client"
|
||||
RAC_CLIENT_GROUP = "group_rac_client"
|
||||
# A group for all connections in a given authentik session ID
|
||||
# A disconnect message is sent to this group when the session expires/is deleted
|
||||
RAC_CLIENT_GROUP_SESSION = "group_enterprise_rac_client_%(session)s"
|
||||
RAC_CLIENT_GROUP_SESSION = "group_rac_client_%(session)s"
|
||||
# A group for all connections with a specific token, which in almost all cases
|
||||
# is just one connection, however this is used to disconnect the connection
|
||||
# when the token is deleted
|
||||
RAC_CLIENT_GROUP_TOKEN = "group_enterprise_rac_token_%(token)s" # nosec
|
||||
RAC_CLIENT_GROUP_TOKEN = "group_rac_token_%(token)s" # nosec
|
||||
|
||||
# Step 1: Client connects to this websocket endpoint
|
||||
# Step 2: We prepare all the connection args for Guac
|
@ -3,7 +3,7 @@
|
||||
from channels.exceptions import ChannelFull
|
||||
from channels.generic.websocket import AsyncWebsocketConsumer
|
||||
|
||||
from authentik.enterprise.providers.rac.consumer_client import RAC_CLIENT_GROUP
|
||||
from authentik.providers.rac.consumer_client import RAC_CLIENT_GROUP
|
||||
|
||||
|
||||
class RACOutpostConsumer(AsyncWebsocketConsumer):
|
@ -74,7 +74,7 @@ class RACProvider(Provider):
|
||||
|
||||
@property
|
||||
def serializer(self) -> type[Serializer]:
|
||||
from authentik.enterprise.providers.rac.api.providers import RACProviderSerializer
|
||||
from authentik.providers.rac.api.providers import RACProviderSerializer
|
||||
|
||||
return RACProviderSerializer
|
||||
|
||||
@ -100,7 +100,7 @@ class Endpoint(SerializerModel, PolicyBindingModel):
|
||||
|
||||
@property
|
||||
def serializer(self) -> type[Serializer]:
|
||||
from authentik.enterprise.providers.rac.api.endpoints import EndpointSerializer
|
||||
from authentik.providers.rac.api.endpoints import EndpointSerializer
|
||||
|
||||
return EndpointSerializer
|
||||
|
||||
@ -129,7 +129,7 @@ class RACPropertyMapping(PropertyMapping):
|
||||
|
||||
@property
|
||||
def serializer(self) -> type[Serializer]:
|
||||
from authentik.enterprise.providers.rac.api.property_mappings import (
|
||||
from authentik.providers.rac.api.property_mappings import (
|
||||
RACPropertyMappingSerializer,
|
||||
)
|
||||
|
@ -10,12 +10,12 @@ from django.dispatch import receiver
|
||||
from django.http import HttpRequest
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.enterprise.providers.rac.api.endpoints import user_endpoint_cache_key
|
||||
from authentik.enterprise.providers.rac.consumer_client import (
|
||||
from authentik.providers.rac.api.endpoints import user_endpoint_cache_key
|
||||
from authentik.providers.rac.consumer_client import (
|
||||
RAC_CLIENT_GROUP_SESSION,
|
||||
RAC_CLIENT_GROUP_TOKEN,
|
||||
)
|
||||
from authentik.enterprise.providers.rac.models import ConnectionToken, Endpoint
|
||||
from authentik.providers.rac.models import ConnectionToken, Endpoint
|
||||
|
||||
|
||||
@receiver(user_logged_out)
|
@ -3,7 +3,7 @@
|
||||
{% load authentik_core %}
|
||||
|
||||
{% block head %}
|
||||
<script src="{% versioned_script 'dist/enterprise/rac/index-%v.js' %}" type="module"></script>
|
||||
<script src="{% versioned_script 'dist/rac/index-%v.js' %}" type="module"></script>
|
||||
<meta name="theme-color" content="#18191a" media="(prefers-color-scheme: dark)">
|
||||
<meta name="theme-color" content="#ffffff" media="(prefers-color-scheme: light)">
|
||||
<link rel="icon" href="{{ tenant.branding_favicon_url }}">
|
@ -1,16 +1,9 @@
|
||||
"""Test RAC Provider"""
|
||||
|
||||
from datetime import timedelta
|
||||
from time import mktime
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import now
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||
from authentik.enterprise.license import LicenseKey
|
||||
from authentik.enterprise.models import License
|
||||
from authentik.lib.generators import generate_id
|
||||
|
||||
|
||||
@ -20,21 +13,8 @@ class TestAPI(APITestCase):
|
||||
def setUp(self) -> None:
|
||||
self.user = create_test_admin_user()
|
||||
|
||||
@patch(
|
||||
"authentik.enterprise.license.LicenseKey.validate",
|
||||
MagicMock(
|
||||
return_value=LicenseKey(
|
||||
aud="",
|
||||
exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
|
||||
name=generate_id(),
|
||||
internal_users=100,
|
||||
external_users=100,
|
||||
)
|
||||
),
|
||||
)
|
||||
def test_create(self):
|
||||
"""Test creation of RAC Provider"""
|
||||
License.objects.create(key=generate_id())
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:racprovider-list"),
|
@ -5,10 +5,10 @@ from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_admin_user
|
||||
from authentik.enterprise.providers.rac.models import Endpoint, Protocols, RACProvider
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.policies.dummy.models import DummyPolicy
|
||||
from authentik.policies.models import PolicyBinding
|
||||
from authentik.providers.rac.models import Endpoint, Protocols, RACProvider
|
||||
|
||||
|
||||
class TestEndpointsAPI(APITestCase):
|
@ -4,14 +4,14 @@ from django.test import TransactionTestCase
|
||||
|
||||
from authentik.core.models import Application, AuthenticatedSession
|
||||
from authentik.core.tests.utils import create_test_admin_user
|
||||
from authentik.enterprise.providers.rac.models import (
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.providers.rac.models import (
|
||||
ConnectionToken,
|
||||
Endpoint,
|
||||
Protocols,
|
||||
RACPropertyMapping,
|
||||
RACProvider,
|
||||
)
|
||||
from authentik.lib.generators import generate_id
|
||||
|
||||
|
||||
class TestModels(TransactionTestCase):
|
@ -1,23 +1,17 @@
|
||||
"""RAC Views tests"""
|
||||
|
||||
from datetime import timedelta
|
||||
from json import loads
|
||||
from time import mktime
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from django.urls import reverse
|
||||
from django.utils.timezone import now
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
|
||||
from authentik.enterprise.license import LicenseKey
|
||||
from authentik.enterprise.models import License
|
||||
from authentik.enterprise.providers.rac.models import Endpoint, Protocols, RACProvider
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.policies.denied import AccessDeniedResponse
|
||||
from authentik.policies.dummy.models import DummyPolicy
|
||||
from authentik.policies.models import PolicyBinding
|
||||
from authentik.providers.rac.models import Endpoint, Protocols, RACProvider
|
||||
|
||||
|
||||
class TestRACViews(APITestCase):
|
||||
@ -39,21 +33,8 @@ class TestRACViews(APITestCase):
|
||||
provider=self.provider,
|
||||
)
|
||||
|
||||
@patch(
|
||||
"authentik.enterprise.license.LicenseKey.validate",
|
||||
MagicMock(
|
||||
return_value=LicenseKey(
|
||||
aud="",
|
||||
exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
|
||||
name=generate_id(),
|
||||
internal_users=100,
|
||||
external_users=100,
|
||||
)
|
||||
),
|
||||
)
|
||||
def test_no_policy(self):
|
||||
"""Test request"""
|
||||
License.objects.create(key=generate_id())
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
@ -70,18 +51,6 @@ class TestRACViews(APITestCase):
|
||||
final_response = self.client.get(next_url)
|
||||
self.assertEqual(final_response.status_code, 200)
|
||||
|
||||
@patch(
|
||||
"authentik.enterprise.license.LicenseKey.validate",
|
||||
MagicMock(
|
||||
return_value=LicenseKey(
|
||||
aud="",
|
||||
exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
|
||||
name=generate_id(),
|
||||
internal_users=100,
|
||||
external_users=100,
|
||||
)
|
||||
),
|
||||
)
|
||||
def test_app_deny(self):
|
||||
"""Test request (deny on app level)"""
|
||||
PolicyBinding.objects.create(
|
||||
@ -89,7 +58,6 @@ class TestRACViews(APITestCase):
|
||||
policy=DummyPolicy.objects.create(name="deny", result=False, wait_min=1, wait_max=2),
|
||||
order=0,
|
||||
)
|
||||
License.objects.create(key=generate_id())
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
@ -99,18 +67,6 @@ class TestRACViews(APITestCase):
|
||||
)
|
||||
self.assertIsInstance(response, AccessDeniedResponse)
|
||||
|
||||
@patch(
|
||||
"authentik.enterprise.license.LicenseKey.validate",
|
||||
MagicMock(
|
||||
return_value=LicenseKey(
|
||||
aud="",
|
||||
exp=int(mktime((now() + timedelta(days=3000)).timetuple())),
|
||||
name=generate_id(),
|
||||
internal_users=100,
|
||||
external_users=100,
|
||||
)
|
||||
),
|
||||
)
|
||||
def test_endpoint_deny(self):
|
||||
"""Test request (deny on endpoint level)"""
|
||||
PolicyBinding.objects.create(
|
||||
@ -118,7 +74,6 @@ class TestRACViews(APITestCase):
|
||||
policy=DummyPolicy.objects.create(name="deny", result=False, wait_min=1, wait_max=2),
|
||||
order=0,
|
||||
)
|
||||
License.objects.create(key=generate_id())
|
||||
self.client.force_login(self.user)
|
||||
response = self.client.get(
|
||||
reverse(
|
@ -4,14 +4,14 @@ from channels.auth import AuthMiddleware
|
||||
from channels.sessions import CookieMiddleware
|
||||
from django.urls import path
|
||||
|
||||
from authentik.enterprise.providers.rac.api.connection_tokens import ConnectionTokenViewSet
|
||||
from authentik.enterprise.providers.rac.api.endpoints import EndpointViewSet
|
||||
from authentik.enterprise.providers.rac.api.property_mappings import RACPropertyMappingViewSet
|
||||
from authentik.enterprise.providers.rac.api.providers import RACProviderViewSet
|
||||
from authentik.enterprise.providers.rac.consumer_client import RACClientConsumer
|
||||
from authentik.enterprise.providers.rac.consumer_outpost import RACOutpostConsumer
|
||||
from authentik.enterprise.providers.rac.views import RACInterface, RACStartView
|
||||
from authentik.outposts.channels import TokenOutpostMiddleware
|
||||
from authentik.providers.rac.api.connection_tokens import ConnectionTokenViewSet
|
||||
from authentik.providers.rac.api.endpoints import EndpointViewSet
|
||||
from authentik.providers.rac.api.property_mappings import RACPropertyMappingViewSet
|
||||
from authentik.providers.rac.api.providers import RACProviderViewSet
|
||||
from authentik.providers.rac.consumer_client import RACClientConsumer
|
||||
from authentik.providers.rac.consumer_outpost import RACOutpostConsumer
|
||||
from authentik.providers.rac.views import RACInterface, RACStartView
|
||||
from authentik.root.asgi_middleware import SessionMiddleware
|
||||
from authentik.root.middleware import ChannelsLoggingMiddleware
|
||||
|
@ -10,8 +10,6 @@ from django.utils.translation import gettext as _
|
||||
|
||||
from authentik.core.models import Application, AuthenticatedSession
|
||||
from authentik.core.views.interface import InterfaceView
|
||||
from authentik.enterprise.policy import EnterprisePolicyAccessView
|
||||
from authentik.enterprise.providers.rac.models import ConnectionToken, Endpoint, RACProvider
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.flows.challenge import RedirectChallenge
|
||||
from authentik.flows.exceptions import FlowNonApplicableException
|
||||
@ -20,9 +18,11 @@ from authentik.flows.planner import PLAN_CONTEXT_APPLICATION, FlowPlanner
|
||||
from authentik.flows.stage import RedirectStage
|
||||
from authentik.lib.utils.time import timedelta_from_string
|
||||
from authentik.policies.engine import PolicyEngine
|
||||
from authentik.policies.views import PolicyAccessView
|
||||
from authentik.providers.rac.models import ConnectionToken, Endpoint, RACProvider
|
||||
|
||||
|
||||
class RACStartView(EnterprisePolicyAccessView):
|
||||
class RACStartView(PolicyAccessView):
|
||||
"""Start a RAC connection by checking access and creating a connection token"""
|
||||
|
||||
endpoint: Endpoint
|
@ -2,7 +2,7 @@
|
||||
|
||||
from django.apps import apps
|
||||
from django.contrib.auth.models import Permission
|
||||
from django.db.models import Q, QuerySet
|
||||
from django.db.models import QuerySet
|
||||
from django_filters.filters import ModelChoiceFilter
|
||||
from django_filters.filterset import FilterSet
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
@ -18,7 +18,6 @@ from rest_framework.filters import OrderingFilter, SearchFilter
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from authentik.blueprints.v1.importer import excluded_models
|
||||
from authentik.core.api.utils import ModelSerializer, PassiveSerializer
|
||||
from authentik.core.models import User
|
||||
from authentik.lib.validators import RequiredTogetherValidator
|
||||
@ -106,13 +105,13 @@ class RBACPermissionViewSet(ReadOnlyModelViewSet):
|
||||
]
|
||||
|
||||
def get_queryset(self) -> QuerySet:
|
||||
query = Q()
|
||||
for model in excluded_models():
|
||||
query |= Q(
|
||||
content_type__app_label=model._meta.app_label,
|
||||
content_type__model=model._meta.model_name,
|
||||
return (
|
||||
Permission.objects.all()
|
||||
.select_related("content_type")
|
||||
.filter(
|
||||
content_type__app_label__startswith="authentik",
|
||||
)
|
||||
return Permission.objects.all().select_related("content_type").exclude(query)
|
||||
)
|
||||
|
||||
|
||||
class PermissionAssignSerializer(PassiveSerializer):
|
||||
|
@ -16,6 +16,7 @@ from authentik.lib.config import CONFIG, django_db_config, redis_url
|
||||
from authentik.lib.logging import get_logger_config, structlog_configure
|
||||
from authentik.lib.sentry import sentry_init
|
||||
from authentik.lib.utils.reflection import get_env
|
||||
from authentik.lib.utils.time import timedelta_from_string
|
||||
from authentik.stages.password import BACKEND_APP_PASSWORD, BACKEND_INBUILT, BACKEND_LDAP
|
||||
|
||||
BASE_DIR = Path(__file__).absolute().parent.parent.parent
|
||||
@ -87,6 +88,7 @@ TENANT_APPS = [
|
||||
"authentik.providers.ldap",
|
||||
"authentik.providers.oauth2",
|
||||
"authentik.providers.proxy",
|
||||
"authentik.providers.rac",
|
||||
"authentik.providers.radius",
|
||||
"authentik.providers.saml",
|
||||
"authentik.providers.scim",
|
||||
@ -241,6 +243,9 @@ SESSION_CACHE_ALIAS = "default"
|
||||
# Configured via custom SessionMiddleware
|
||||
# SESSION_COOKIE_SAMESITE = "None"
|
||||
# SESSION_COOKIE_SECURE = True
|
||||
SESSION_COOKIE_AGE = timedelta_from_string(
|
||||
CONFIG.get("sessions.unauthenticated_age", "days=1")
|
||||
).total_seconds()
|
||||
SESSION_EXPIRE_AT_BROWSER_CLOSE = True
|
||||
|
||||
MESSAGE_STORAGE = "authentik.root.messages.storage.ChannelsStorage"
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
from typing import Any
|
||||
|
||||
from requests import RequestException
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.sources.oauth.clients.oauth2 import UserprofileHeaderAuthClient
|
||||
@ -21,10 +22,35 @@ class AzureADOAuthRedirect(OAuthRedirect):
|
||||
}
|
||||
|
||||
|
||||
class AzureADClient(UserprofileHeaderAuthClient):
|
||||
"""Fetch AzureAD group information"""
|
||||
|
||||
def get_profile_info(self, token):
|
||||
profile_data = super().get_profile_info(token)
|
||||
if "https://graph.microsoft.com/GroupMember.Read.All" not in self.source.additional_scopes:
|
||||
return profile_data
|
||||
group_response = self.session.request(
|
||||
"get",
|
||||
"https://graph.microsoft.com/v1.0/me/memberOf",
|
||||
headers={"Authorization": f"{token['token_type']} {token['access_token']}"},
|
||||
)
|
||||
try:
|
||||
group_response.raise_for_status()
|
||||
except RequestException as exc:
|
||||
LOGGER.warning(
|
||||
"Unable to fetch user profile",
|
||||
exc=exc,
|
||||
response=exc.response.text if exc.response else str(exc),
|
||||
)
|
||||
return None
|
||||
profile_data["raw_groups"] = group_response.json()
|
||||
return profile_data
|
||||
|
||||
|
||||
class AzureADOAuthCallback(OpenIDConnectOAuth2Callback):
|
||||
"""AzureAD OAuth2 Callback"""
|
||||
|
||||
client_class = UserprofileHeaderAuthClient
|
||||
client_class = AzureADClient
|
||||
|
||||
def get_user_id(self, info: dict[str, str]) -> str:
|
||||
# Default try to get `id` for the Graph API endpoint
|
||||
@ -53,8 +79,24 @@ class AzureADType(SourceType):
|
||||
|
||||
def get_base_user_properties(self, info: dict[str, Any], **kwargs) -> dict[str, Any]:
|
||||
mail = info.get("mail", None) or info.get("otherMails", [None])[0]
|
||||
# Format group info
|
||||
groups = []
|
||||
group_id_dict = {}
|
||||
for group in info.get("raw_groups", {}).get("value", []):
|
||||
if group["@odata.type"] != "#microsoft.graph.group":
|
||||
continue
|
||||
groups.append(group["id"])
|
||||
group_id_dict[group["id"]] = group
|
||||
info["raw_groups"] = group_id_dict
|
||||
return {
|
||||
"username": info.get("userPrincipalName"),
|
||||
"email": mail,
|
||||
"name": info.get("displayName"),
|
||||
"groups": groups,
|
||||
}
|
||||
|
||||
def get_base_group_properties(self, source, group_id, **kwargs):
|
||||
raw_group = kwargs["info"]["raw_groups"][group_id]
|
||||
return {
|
||||
"name": raw_group["displayName"],
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"$id": "https://goauthentik.io/blueprints/schema.json",
|
||||
"type": "object",
|
||||
"title": "authentik 2024.12.3 Blueprint schema",
|
||||
"title": "authentik 2025.2.0 Blueprint schema",
|
||||
"required": [
|
||||
"version",
|
||||
"entries"
|
||||
@ -801,6 +801,126 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"model",
|
||||
"identifiers"
|
||||
],
|
||||
"properties": {
|
||||
"model": {
|
||||
"const": "authentik_providers_rac.racprovider"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"absent",
|
||||
"present",
|
||||
"created",
|
||||
"must_created"
|
||||
],
|
||||
"default": "present"
|
||||
},
|
||||
"conditions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racprovider_permissions"
|
||||
},
|
||||
"attrs": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racprovider"
|
||||
},
|
||||
"identifiers": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racprovider"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"model",
|
||||
"identifiers"
|
||||
],
|
||||
"properties": {
|
||||
"model": {
|
||||
"const": "authentik_providers_rac.endpoint"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"absent",
|
||||
"present",
|
||||
"created",
|
||||
"must_created"
|
||||
],
|
||||
"default": "present"
|
||||
},
|
||||
"conditions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.endpoint_permissions"
|
||||
},
|
||||
"attrs": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.endpoint"
|
||||
},
|
||||
"identifiers": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.endpoint"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"model",
|
||||
"identifiers"
|
||||
],
|
||||
"properties": {
|
||||
"model": {
|
||||
"const": "authentik_providers_rac.racpropertymapping"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"absent",
|
||||
"present",
|
||||
"created",
|
||||
"must_created"
|
||||
],
|
||||
"default": "present"
|
||||
},
|
||||
"conditions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping_permissions"
|
||||
},
|
||||
"attrs": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
|
||||
},
|
||||
"identifiers": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -3561,126 +3681,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"model",
|
||||
"identifiers"
|
||||
],
|
||||
"properties": {
|
||||
"model": {
|
||||
"const": "authentik_providers_rac.racprovider"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"absent",
|
||||
"present",
|
||||
"created",
|
||||
"must_created"
|
||||
],
|
||||
"default": "present"
|
||||
},
|
||||
"conditions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racprovider_permissions"
|
||||
},
|
||||
"attrs": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racprovider"
|
||||
},
|
||||
"identifiers": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racprovider"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"model",
|
||||
"identifiers"
|
||||
],
|
||||
"properties": {
|
||||
"model": {
|
||||
"const": "authentik_providers_rac.endpoint"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"absent",
|
||||
"present",
|
||||
"created",
|
||||
"must_created"
|
||||
],
|
||||
"default": "present"
|
||||
},
|
||||
"conditions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.endpoint_permissions"
|
||||
},
|
||||
"attrs": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.endpoint"
|
||||
},
|
||||
"identifiers": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.endpoint"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
"model",
|
||||
"identifiers"
|
||||
],
|
||||
"properties": {
|
||||
"model": {
|
||||
"const": "authentik_providers_rac.racpropertymapping"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"state": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"absent",
|
||||
"present",
|
||||
"created",
|
||||
"must_created"
|
||||
],
|
||||
"default": "present"
|
||||
},
|
||||
"conditions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping_permissions"
|
||||
},
|
||||
"attrs": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
|
||||
},
|
||||
"identifiers": {
|
||||
"$ref": "#/$defs/model_authentik_providers_rac.racpropertymapping"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -4663,6 +4663,7 @@
|
||||
"authentik.providers.ldap",
|
||||
"authentik.providers.oauth2",
|
||||
"authentik.providers.proxy",
|
||||
"authentik.providers.rac",
|
||||
"authentik.providers.radius",
|
||||
"authentik.providers.saml",
|
||||
"authentik.providers.scim",
|
||||
@ -4703,7 +4704,6 @@
|
||||
"authentik.enterprise.audit",
|
||||
"authentik.enterprise.providers.google_workspace",
|
||||
"authentik.enterprise.providers.microsoft_entra",
|
||||
"authentik.enterprise.providers.rac",
|
||||
"authentik.enterprise.providers.ssf",
|
||||
"authentik.enterprise.stages.authenticator_endpoint_gdtc",
|
||||
"authentik.enterprise.stages.source",
|
||||
@ -4738,6 +4738,9 @@
|
||||
"authentik_providers_oauth2.scopemapping",
|
||||
"authentik_providers_oauth2.oauth2provider",
|
||||
"authentik_providers_proxy.proxyprovider",
|
||||
"authentik_providers_rac.racprovider",
|
||||
"authentik_providers_rac.endpoint",
|
||||
"authentik_providers_rac.racpropertymapping",
|
||||
"authentik_providers_radius.radiusprovider",
|
||||
"authentik_providers_radius.radiusproviderpropertymapping",
|
||||
"authentik_providers_saml.samlprovider",
|
||||
@ -4807,9 +4810,6 @@
|
||||
"authentik_providers_google_workspace.googleworkspaceprovidermapping",
|
||||
"authentik_providers_microsoft_entra.microsoftentraprovider",
|
||||
"authentik_providers_microsoft_entra.microsoftentraprovidermapping",
|
||||
"authentik_providers_rac.racprovider",
|
||||
"authentik_providers_rac.endpoint",
|
||||
"authentik_providers_rac.racpropertymapping",
|
||||
"authentik_providers_ssf.ssfprovider",
|
||||
"authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage",
|
||||
"authentik_stages_source.sourcestage",
|
||||
@ -6046,6 +6046,216 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_providers_rac.racprovider": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Name"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||
},
|
||||
"authorization_flow": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authorization flow",
|
||||
"description": "Flow used when authorizing this provider."
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
"settings": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "Settings"
|
||||
},
|
||||
"connection_expiry": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Connection expiry",
|
||||
"description": "Determines how long a session lasts. Default of 0 means that the sessions lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
|
||||
},
|
||||
"delete_token_on_disconnect": {
|
||||
"type": "boolean",
|
||||
"title": "Delete token on disconnect",
|
||||
"description": "When set to true, connection tokens will be deleted upon disconnect."
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"model_authentik_providers_rac.racprovider_permissions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permission"
|
||||
],
|
||||
"properties": {
|
||||
"permission": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"add_racprovider",
|
||||
"change_racprovider",
|
||||
"delete_racprovider",
|
||||
"view_racprovider"
|
||||
]
|
||||
},
|
||||
"user": {
|
||||
"type": "integer"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_providers_rac.endpoint": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Name"
|
||||
},
|
||||
"provider": {
|
||||
"type": "integer",
|
||||
"title": "Provider"
|
||||
},
|
||||
"protocol": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"rdp",
|
||||
"vnc",
|
||||
"ssh"
|
||||
],
|
||||
"title": "Protocol"
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Host"
|
||||
},
|
||||
"settings": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "Settings"
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
"auth_mode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"static",
|
||||
"prompt"
|
||||
],
|
||||
"title": "Auth mode"
|
||||
},
|
||||
"maximum_connections": {
|
||||
"type": "integer",
|
||||
"minimum": -2147483648,
|
||||
"maximum": 2147483647,
|
||||
"title": "Maximum connections"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"model_authentik_providers_rac.endpoint_permissions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permission"
|
||||
],
|
||||
"properties": {
|
||||
"permission": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"add_endpoint",
|
||||
"change_endpoint",
|
||||
"delete_endpoint",
|
||||
"view_endpoint"
|
||||
]
|
||||
},
|
||||
"user": {
|
||||
"type": "integer"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_providers_rac.racpropertymapping": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"managed": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"minLength": 1,
|
||||
"title": "Managed by authentik",
|
||||
"description": "Objects that are managed by authentik. These objects are created and updated automatically. This flag only indicates that an object can be overwritten by migrations. You can still modify the objects via the API, but expect changes to be overwritten in a later update."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Name"
|
||||
},
|
||||
"expression": {
|
||||
"type": "string",
|
||||
"title": "Expression"
|
||||
},
|
||||
"static_settings": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "Static settings"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"model_authentik_providers_rac.racpropertymapping_permissions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permission"
|
||||
],
|
||||
"properties": {
|
||||
"permission": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"add_racpropertymapping",
|
||||
"change_racpropertymapping",
|
||||
"delete_racpropertymapping",
|
||||
"view_racpropertymapping"
|
||||
]
|
||||
},
|
||||
"user": {
|
||||
"type": "integer"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_providers_radius.radiusprovider": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -14215,216 +14425,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_providers_rac.racprovider": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Name"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||
},
|
||||
"authorization_flow": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authorization flow",
|
||||
"description": "Flow used when authorizing this provider."
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
"settings": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "Settings"
|
||||
},
|
||||
"connection_expiry": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Connection expiry",
|
||||
"description": "Determines how long a session lasts. Default of 0 means that the sessions lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
|
||||
},
|
||||
"delete_token_on_disconnect": {
|
||||
"type": "boolean",
|
||||
"title": "Delete token on disconnect",
|
||||
"description": "When set to true, connection tokens will be deleted upon disconnect."
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"model_authentik_providers_rac.racprovider_permissions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permission"
|
||||
],
|
||||
"properties": {
|
||||
"permission": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"add_racprovider",
|
||||
"change_racprovider",
|
||||
"delete_racprovider",
|
||||
"view_racprovider"
|
||||
]
|
||||
},
|
||||
"user": {
|
||||
"type": "integer"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_providers_rac.endpoint": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Name"
|
||||
},
|
||||
"provider": {
|
||||
"type": "integer",
|
||||
"title": "Provider"
|
||||
},
|
||||
"protocol": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"rdp",
|
||||
"vnc",
|
||||
"ssh"
|
||||
],
|
||||
"title": "Protocol"
|
||||
},
|
||||
"host": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Host"
|
||||
},
|
||||
"settings": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "Settings"
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
"auth_mode": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"static",
|
||||
"prompt"
|
||||
],
|
||||
"title": "Auth mode"
|
||||
},
|
||||
"maximum_connections": {
|
||||
"type": "integer",
|
||||
"minimum": -2147483648,
|
||||
"maximum": 2147483647,
|
||||
"title": "Maximum connections"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"model_authentik_providers_rac.endpoint_permissions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permission"
|
||||
],
|
||||
"properties": {
|
||||
"permission": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"add_endpoint",
|
||||
"change_endpoint",
|
||||
"delete_endpoint",
|
||||
"view_endpoint"
|
||||
]
|
||||
},
|
||||
"user": {
|
||||
"type": "integer"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_providers_rac.racpropertymapping": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"managed": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
],
|
||||
"minLength": 1,
|
||||
"title": "Managed by authentik",
|
||||
"description": "Objects that are managed by authentik. These objects are created and updated automatically. This flag only indicates that an object can be overwritten by migrations. You can still modify the objects via the API, but expect changes to be overwritten in a later update."
|
||||
},
|
||||
"name": {
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Name"
|
||||
},
|
||||
"expression": {
|
||||
"type": "string",
|
||||
"title": "Expression"
|
||||
},
|
||||
"static_settings": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"title": "Static settings"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"model_authentik_providers_rac.racpropertymapping_permissions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"permission"
|
||||
],
|
||||
"properties": {
|
||||
"permission": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"add_racpropertymapping",
|
||||
"change_racpropertymapping",
|
||||
"delete_racpropertymapping",
|
||||
"view_racpropertymapping"
|
||||
]
|
||||
},
|
||||
"user": {
|
||||
"type": "integer"
|
||||
},
|
||||
"role": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"model_authentik_providers_ssf.ssfprovider": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"goauthentik.io/internal/common"
|
||||
"goauthentik.io/internal/config"
|
||||
"goauthentik.io/internal/constants"
|
||||
"goauthentik.io/internal/debug"
|
||||
"goauthentik.io/internal/outpost/ak"
|
||||
"goauthentik.io/internal/outpost/ak/healthcheck"
|
||||
@ -24,7 +25,8 @@ Required environment variables:
|
||||
- AUTHENTIK_INSECURE: Skip SSL Certificate verification`
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Long: helpMessage,
|
||||
Long: helpMessage,
|
||||
Version: constants.FullVersion(),
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.SetFormatter(&log.JSONFormatter{
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
|
||||
"goauthentik.io/internal/common"
|
||||
"goauthentik.io/internal/config"
|
||||
"goauthentik.io/internal/constants"
|
||||
"goauthentik.io/internal/debug"
|
||||
"goauthentik.io/internal/outpost/ak"
|
||||
"goauthentik.io/internal/outpost/ak/healthcheck"
|
||||
@ -27,7 +28,8 @@ Optionally, you can set these:
|
||||
- AUTHENTIK_HOST_BROWSER: URL to use in the browser, when it differs from AUTHENTIK_HOST`
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Long: helpMessage,
|
||||
Long: helpMessage,
|
||||
Version: constants.FullVersion(),
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.SetFormatter(&log.JSONFormatter{
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"goauthentik.io/internal/common"
|
||||
"goauthentik.io/internal/constants"
|
||||
"goauthentik.io/internal/debug"
|
||||
"goauthentik.io/internal/outpost/ak"
|
||||
"goauthentik.io/internal/outpost/ak/healthcheck"
|
||||
@ -23,7 +24,8 @@ Required environment variables:
|
||||
- AUTHENTIK_INSECURE: Skip SSL Certificate verification`
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Long: helpMessage,
|
||||
Long: helpMessage,
|
||||
Version: constants.FullVersion(),
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.SetFormatter(&log.JSONFormatter{
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"goauthentik.io/internal/common"
|
||||
"goauthentik.io/internal/constants"
|
||||
"goauthentik.io/internal/debug"
|
||||
"goauthentik.io/internal/outpost/ak"
|
||||
"goauthentik.io/internal/outpost/ak/healthcheck"
|
||||
@ -23,7 +24,8 @@ Required environment variables:
|
||||
- AUTHENTIK_INSECURE: Skip SSL Certificate verification`
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
Long: helpMessage,
|
||||
Long: helpMessage,
|
||||
Version: constants.FullVersion(),
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.SetFormatter(&log.JSONFormatter{
|
||||
|
@ -31,7 +31,7 @@ services:
|
||||
volumes:
|
||||
- redis:/data
|
||||
server:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.3}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.0}
|
||||
restart: unless-stopped
|
||||
command: server
|
||||
environment:
|
||||
@ -54,7 +54,7 @@ services:
|
||||
redis:
|
||||
condition: service_healthy
|
||||
worker:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.12.3}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.2.0}
|
||||
restart: unless-stopped
|
||||
command: worker
|
||||
environment:
|
||||
|
24
go.mod
24
go.mod
@ -1,8 +1,8 @@
|
||||
module goauthentik.io
|
||||
|
||||
go 1.23
|
||||
go 1.23.0
|
||||
|
||||
toolchain go1.23.0
|
||||
toolchain go1.24.0
|
||||
|
||||
require (
|
||||
beryju.io/ldap v0.1.0
|
||||
@ -22,16 +22,16 @@ require (
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
|
||||
github.com/pires/go-proxyproto v0.8.0
|
||||
github.com/prometheus/client_golang v1.20.5
|
||||
github.com/redis/go-redis/v9 v9.7.0
|
||||
github.com/prometheus/client_golang v1.21.0
|
||||
github.com/redis/go-redis/v9 v9.7.1
|
||||
github.com/sethvargo/go-envconfig v1.1.1
|
||||
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.2024123.6
|
||||
goauthentik.io/api/v3 v3.2025020.1
|
||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||
golang.org/x/oauth2 v0.26.0
|
||||
golang.org/x/oauth2 v0.27.0
|
||||
golang.org/x/sync v0.11.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
|
||||
@ -48,7 +48,7 @@ require (
|
||||
github.com/go-asn1-ber/asn1-ber v1.5.7 // indirect
|
||||
github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 // indirect
|
||||
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.2 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/analysis v0.23.0 // indirect
|
||||
@ -62,23 +62,23 @@ require (
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/klauspost/compress v1.17.9 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.55.0 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
go.mongodb.org/mongo-driver v1.14.0 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/crypto v0.32.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
google.golang.org/protobuf v1.34.2 // indirect
|
||||
google.golang.org/protobuf v1.36.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
38
go.sum
38
go.sum
@ -84,8 +84,8 @@ github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 h1:O6yi4xa9b2D
|
||||
github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27/go.mod h1:AYvN8omj7nKLmbcXS2dyABYU6JB1Lz1bHmkkq1kf4I4=
|
||||
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a h1:v6zMvHuY9yue4+QkG/HQ/W67wvtQmWJ4SDo9aK/GIno=
|
||||
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw=
|
||||
github.com/go-jose/go-jose/v4 v4.0.2 h1:R3l3kkBds16bO7ZFAEEcofK0MkrAJt3jlJznWZG0nvk=
|
||||
github.com/go-jose/go-jose/v4 v4.0.2/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/go-ldap/ldap/v3 v3.4.10 h1:ot/iwPOhfpNVgB1o+AVXljizWZ9JTp7YF5oeyONmcJU=
|
||||
github.com/go-ldap/ldap/v3 v3.4.10/go.mod h1:JXh4Uxgi40P6E9rdsYqpUtbW46D9UTjJ9QSwGRznplY=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
@ -207,8 +207,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF
|
||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@ -239,17 +239,17 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||
github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA=
|
||||
github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||
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.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E=
|
||||
github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||
github.com/redis/go-redis/v9 v9.7.1 h1:4LhKRCIduqXqtvCUlaq9c8bdHOkICjDMrr1+Zb3osAc=
|
||||
github.com/redis/go-redis/v9 v9.7.1/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw=
|
||||
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=
|
||||
@ -299,8 +299,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.2024123.6 h1:AGOCa7Fc/9eONCPEW4sEhTiyEBvxN57Lfqz1zm6Gy98=
|
||||
goauthentik.io/api/v3 v3.2024123.6/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
|
||||
goauthentik.io/api/v3 v3.2025020.1 h1:7922W4XiGif7lUCl2qlaeQJ3wSx1wDDDpXx8ryx0Hv0=
|
||||
goauthentik.io/api/v3 v3.2025020.1/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=
|
||||
@ -312,8 +312,9 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
|
||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@ -393,8 +394,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
||||
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M=
|
||||
golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -447,8 +448,9 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
|
||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@ -595,8 +597,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
|
||||
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
|
||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
|
@ -29,4 +29,4 @@ func UserAgent() string {
|
||||
return fmt.Sprintf("authentik@%s", FullVersion())
|
||||
}
|
||||
|
||||
const VERSION = "2024.12.3"
|
||||
const VERSION = "2025.2.0"
|
||||
|
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.179.0",
|
||||
"aws-cdk": "^2.1000.3",
|
||||
"cross-env": "^7.0.3"
|
||||
},
|
||||
"engines": {
|
||||
@ -17,9 +17,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/aws-cdk": {
|
||||
"version": "2.179.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.179.0.tgz",
|
||||
"integrity": "sha512-aA2+8S2g4UBQHkUEt0mYd16VLt/ucR+QfyUJi34LDKRAhOCNDjPCZ4z9z/JEDyuni0BdzsYA55pnpDN9tMULpA==",
|
||||
"version": "2.1000.3",
|
||||
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1000.3.tgz",
|
||||
"integrity": "sha512-y0sU603gGWpVTwqDw9MKVHg3e1t49Mvve6t3YDOvjeKY195Vu6dgHlHjW4h8n1vX04r49NKfpoApG60V8sMbdw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
|
@ -10,7 +10,7 @@
|
||||
"node": ">=20"
|
||||
},
|
||||
"devDependencies": {
|
||||
"aws-cdk": "^2.179.0",
|
||||
"aws-cdk": "^2.1000.3",
|
||||
"cross-env": "^7.0.3"
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ Parameters:
|
||||
Description: authentik Docker image
|
||||
AuthentikVersion:
|
||||
Type: String
|
||||
Default: 2024.12.3
|
||||
Default: 2025.2.0
|
||||
Description: authentik Docker image tag
|
||||
AuthentikServerCPU:
|
||||
Type: Number
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-02-14 14:49+0000\n"
|
||||
"POT-Creation-Date: 2025-02-25 00:11+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"
|
||||
@ -109,6 +109,10 @@ msgstr ""
|
||||
msgid "Extra description not available"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/api/groups.py
|
||||
msgid "Cannot set group as parent of itself."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/api/providers.py
|
||||
msgid ""
|
||||
"When not set all providers are returned. When set to true, only backchannel "
|
||||
@ -152,6 +156,14 @@ msgstr ""
|
||||
msgid "Remove user from group"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/models.py
|
||||
msgid "Enable superuser status"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/models.py
|
||||
msgid "Disable superuser status"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/models.py
|
||||
msgid "User's display name."
|
||||
msgstr ""
|
||||
@ -500,57 +512,6 @@ msgstr ""
|
||||
msgid "Microsoft Entra Provider Mappings"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
#: authentik/stages/user_login/models.py
|
||||
msgid ""
|
||||
"Determines how long a session lasts. Default of 0 means that the sessions "
|
||||
"lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
msgid "When set to true, connection tokens will be deleted upon disconnect."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
msgid "RAC Provider"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
msgid "RAC Providers"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
msgid "RAC Endpoint"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
msgid "RAC Endpoints"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
msgid "RAC Provider Property Mapping"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
msgid "RAC Provider Property Mappings"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
msgid "RAC Connection token"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/models.py
|
||||
msgid "RAC Connection tokens"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/views.py
|
||||
msgid "Maximum connection limit reached."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/rac/views.py
|
||||
msgid "(You are already connected in another tab/window)"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/enterprise/providers/ssf/models.py
|
||||
#: authentik/providers/oauth2/models.py
|
||||
msgid "Signing Key"
|
||||
@ -651,7 +612,7 @@ msgstr ""
|
||||
msgid "Slack Webhook (Slack/Discord)"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py
|
||||
#: authentik/events/models.py authentik/stages/authenticator_validate/models.py
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
@ -1105,6 +1066,14 @@ msgstr ""
|
||||
msgid "Client IP is not in an allowed country."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/policies/geoip/models.py
|
||||
msgid "Distance from previous authentication is larger than threshold."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/policies/geoip/models.py
|
||||
msgid "Distance is further than possible."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/policies/geoip/models.py
|
||||
msgid "GeoIP Policy"
|
||||
msgstr ""
|
||||
@ -1643,6 +1612,56 @@ msgstr ""
|
||||
msgid "Proxy Providers"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py authentik/stages/user_login/models.py
|
||||
msgid ""
|
||||
"Determines how long a session lasts. Default of 0 means that the sessions "
|
||||
"lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py
|
||||
msgid "When set to true, connection tokens will be deleted upon disconnect."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py
|
||||
msgid "RAC Provider"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py
|
||||
msgid "RAC Providers"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py
|
||||
msgid "RAC Endpoint"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py
|
||||
msgid "RAC Endpoints"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py
|
||||
msgid "RAC Provider Property Mapping"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py
|
||||
msgid "RAC Provider Property Mappings"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py
|
||||
msgid "RAC Connection token"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/models.py
|
||||
msgid "RAC Connection tokens"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/views.py
|
||||
msgid "Maximum connection limit reached."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/rac/views.py
|
||||
msgid "(You are already connected in another tab/window)"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/radius/models.py
|
||||
msgid "Shared secret between clients and server to hash packets."
|
||||
msgstr ""
|
||||
@ -2486,6 +2505,98 @@ msgstr ""
|
||||
msgid "Duo Devices"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/models.py
|
||||
msgid "Email OTP"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/models.py
|
||||
#: authentik/stages/email/models.py
|
||||
msgid ""
|
||||
"When enabled, global Email connection settings will be used and connection "
|
||||
"settings below will be ignored."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/models.py
|
||||
msgid "Time the token sent is valid (Format: hours=3,minutes=17,seconds=300)."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/models.py
|
||||
msgid "Email Authenticator Setup Stage"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/models.py
|
||||
msgid "Email Authenticator Setup Stages"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/models.py
|
||||
#: authentik/stages/authenticator_email/stage.py
|
||||
#: authentik/stages/email/stage.py
|
||||
msgid "Exception occurred while rendering E-mail template"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/models.py
|
||||
msgid "Email Device"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/models.py
|
||||
msgid "Email Devices"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/stage.py
|
||||
#: authentik/stages/authenticator_sms/stage.py
|
||||
#: authentik/stages/authenticator_totp/stage.py
|
||||
msgid "Code does not match"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/stage.py
|
||||
msgid "Invalid email"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/templates/email/email_otp.html
|
||||
#: authentik/stages/email/templates/email/password_reset.html
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Hi %(username)s,\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/templates/email/email_otp.html
|
||||
msgid ""
|
||||
"\n"
|
||||
" Email MFA code.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/templates/email/email_otp.html
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" If you did not request this code, please ignore this email. The code "
|
||||
"above is valid for %(expires)s.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/templates/email/email_otp.txt
|
||||
#: authentik/stages/email/templates/email/password_reset.txt
|
||||
#, python-format
|
||||
msgid "Hi %(username)s,"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/templates/email/email_otp.txt
|
||||
msgid ""
|
||||
"\n"
|
||||
"Email MFA code\n"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_email/templates/email/email_otp.txt
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
"If you did not request this code, please ignore this email. The code above "
|
||||
"is valid for %(expires)s.\n"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/models.py
|
||||
msgid ""
|
||||
"When enabled, the Phone number is only used during enrollment to verify the "
|
||||
@ -2518,11 +2629,6 @@ msgstr ""
|
||||
msgid "SMS Devices"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/stage.py
|
||||
#: authentik/stages/authenticator_totp/stage.py
|
||||
msgid "Code does not match"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/stage.py
|
||||
msgid "Invalid phone number"
|
||||
msgstr ""
|
||||
@ -2745,12 +2851,6 @@ msgstr ""
|
||||
msgid "Account Confirmation"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/models.py
|
||||
msgid ""
|
||||
"When enabled, global Email connection settings will be used and connection "
|
||||
"settings below will be ignored."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/models.py
|
||||
msgid "Activate users upon completion of stage."
|
||||
msgstr ""
|
||||
@ -2767,10 +2867,6 @@ msgstr ""
|
||||
msgid "Email Stages"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/stage.py
|
||||
msgid "Exception occurred while rendering E-mail template"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/stage.py
|
||||
msgid "Successfully verified Email."
|
||||
msgstr ""
|
||||
@ -2845,14 +2941,6 @@ msgid ""
|
||||
"This email was sent from the notification transport %(name)s.\n"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/templates/email/password_reset.html
|
||||
#, python-format
|
||||
msgid ""
|
||||
"\n"
|
||||
" Hi %(username)s,\n"
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/templates/email/password_reset.html
|
||||
msgid ""
|
||||
"\n"
|
||||
@ -2870,11 +2958,6 @@ msgid ""
|
||||
" "
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/templates/email/password_reset.txt
|
||||
#, python-format
|
||||
msgid "Hi %(username)s,"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/email/templates/email/password_reset.txt
|
||||
msgid ""
|
||||
"\n"
|
||||
|
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "@goauthentik/authentik",
|
||||
"version": "2024.12.3",
|
||||
"version": "2025.2.0",
|
||||
"private": true
|
||||
}
|
||||
|
264
poetry.lock
generated
264
poetry.lock
generated
@ -392,13 +392,13 @@ typeguard = ">=2.13.3,<4.3.0"
|
||||
|
||||
[[package]]
|
||||
name = "aws-cdk-lib"
|
||||
version = "2.179.0"
|
||||
version = "2.180.0"
|
||||
description = "Version 2 of the AWS Cloud Development Kit library"
|
||||
optional = false
|
||||
python-versions = "~=3.8"
|
||||
files = [
|
||||
{file = "aws_cdk_lib-2.179.0-py3-none-any.whl", hash = "sha256:1d7b88ee69067b8d58dac9eeb6697bbaf5d5c032a3070898389c41e7c4f3e3d7"},
|
||||
{file = "aws_cdk_lib-2.179.0.tar.gz", hash = "sha256:b653a55754f4020a4b36e4ae183d213e76e27b18b842cbf9e430e9eccb700550"},
|
||||
{file = "aws_cdk_lib-2.180.0-py3-none-any.whl", hash = "sha256:5700a84dc4c2c6d323e596119fb4100e66aef6265a4d984bbe2e9341174d048b"},
|
||||
{file = "aws_cdk_lib-2.180.0.tar.gz", hash = "sha256:28ba2c75bd55886eb5e686c58be656c9ab29b895f774f9129eaa3255ffcd6b42"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1694,18 +1694,17 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "duo-client"
|
||||
version = "5.3.0"
|
||||
version = "5.4.0"
|
||||
description = "Reference client for Duo Security APIs"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "duo_client-5.3.0-py3-none-any.whl", hash = "sha256:85614bb684cef96285268aef0c1e858df939f6e8a190fb2c707d700bb0215766"},
|
||||
{file = "duo_client-5.3.0.tar.gz", hash = "sha256:afa5ef98a42f06965a2702ca41dba9c85c483abd945e0a440f0ec4871b7593bf"},
|
||||
{file = "duo_client-5.4.0-py3-none-any.whl", hash = "sha256:092d2f79ca2dd7107f944807a109c98c08b99c2dd7fc422b979a248787852068"},
|
||||
{file = "duo_client-5.4.0.tar.gz", hash = "sha256:8e0fec41006951ce7d0ac5281ddfef59f154e194c71d5a00d717e1769e9077bb"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
setuptools = "*"
|
||||
six = "*"
|
||||
|
||||
[[package]]
|
||||
name = "durationpy"
|
||||
@ -2524,13 +2523,13 @@ zookeeper = ["kazoo (>=2.8.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "kubernetes"
|
||||
version = "32.0.0"
|
||||
version = "32.0.1"
|
||||
description = "Kubernetes python client"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "kubernetes-32.0.0-py2.py3-none-any.whl", hash = "sha256:60fd8c29e8e43d9c553ca4811895a687426717deba9c0a66fb2dcc3f5ef96692"},
|
||||
{file = "kubernetes-32.0.0.tar.gz", hash = "sha256:319fa840345a482001ac5d6062222daeb66ec4d1bcb3087402aed685adf0aecb"},
|
||||
{file = "kubernetes-32.0.1-py2.py3-none-any.whl", hash = "sha256:35282ab8493b938b08ab5526c7ce66588232df00ef5e1dbe88a419107dc10998"},
|
||||
{file = "kubernetes-32.0.1.tar.gz", hash = "sha256:42f43d49abd437ada79a79a16bd48a604d3471a117a8347e87db693f2ba0ba28"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -3718,36 +3717,36 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "psycopg"
|
||||
version = "3.2.4"
|
||||
version = "3.2.5"
|
||||
description = "PostgreSQL database adapter for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "psycopg-3.2.4-py3-none-any.whl", hash = "sha256:43665368ccd48180744cab26b74332f46b63b7e06e8ce0775547a3533883d381"},
|
||||
{file = "psycopg-3.2.4.tar.gz", hash = "sha256:f26f1346d6bf1ef5f5ef1714dd405c67fb365cfd1c6cea07de1792747b167b92"},
|
||||
{file = "psycopg-3.2.5-py3-none-any.whl", hash = "sha256:b782130983e5b3de30b4c529623d3687033b4dafa05bb661fc6bf45837ca5879"},
|
||||
{file = "psycopg-3.2.5.tar.gz", hash = "sha256:f5f750611c67cb200e85b408882f29265c66d1de7f813add4f8125978bfd70e8"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
psycopg-c = {version = "3.2.4", optional = true, markers = "implementation_name != \"pypy\" and extra == \"c\""}
|
||||
psycopg-c = {version = "3.2.5", optional = true, markers = "implementation_name != \"pypy\" and extra == \"c\""}
|
||||
typing-extensions = {version = ">=4.6", markers = "python_version < \"3.13\""}
|
||||
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
|
||||
|
||||
[package.extras]
|
||||
binary = ["psycopg-binary (==3.2.4)"]
|
||||
c = ["psycopg-c (==3.2.4)"]
|
||||
dev = ["ast-comments (>=1.1.2)", "black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "mypy (>=1.14)", "pre-commit (>=4.0.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"]
|
||||
binary = ["psycopg-binary (==3.2.5)"]
|
||||
c = ["psycopg-c (==3.2.5)"]
|
||||
dev = ["ast-comments (>=1.1.2)", "black (>=24.1.0)", "codespell (>=2.2)", "dnspython (>=2.1)", "flake8 (>=4.0)", "isort-psycopg", "isort[colors] (>=6.0)", "mypy (>=1.14)", "pre-commit (>=4.0.1)", "types-setuptools (>=57.4)", "wheel (>=0.37)"]
|
||||
docs = ["Sphinx (>=5.0)", "furo (==2022.6.21)", "sphinx-autobuild (>=2021.3.14)", "sphinx-autodoc-typehints (>=1.12)"]
|
||||
pool = ["psycopg-pool"]
|
||||
test = ["anyio (>=4.0)", "mypy (>=1.14)", "pproxy (>=2.7)", "pytest (>=6.2.5)", "pytest-cov (>=3.0)", "pytest-randomly (>=3.5)"]
|
||||
|
||||
[[package]]
|
||||
name = "psycopg-c"
|
||||
version = "3.2.4"
|
||||
version = "3.2.5"
|
||||
description = "PostgreSQL database adapter for Python -- C optimisation distribution"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "psycopg_c-3.2.4.tar.gz", hash = "sha256:22097a04263efb2efd2cc8b00a51fa90e23f9cd4a2e09903fe4d9c6923dac17a"},
|
||||
{file = "psycopg_c-3.2.5.tar.gz", hash = "sha256:57ad4cfd28de278c424aaceb1f2ad5c7910466e315dfe84e403f3c7a0a2ce81b"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4548,29 +4547,29 @@ pyasn1 = ">=0.1.3"
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.9.6"
|
||||
version = "0.9.7"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.9.6-py3-none-linux_armv6l.whl", hash = "sha256:2f218f356dd2d995839f1941322ff021c72a492c470f0b26a34f844c29cdf5ba"},
|
||||
{file = "ruff-0.9.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b908ff4df65dad7b251c9968a2e4560836d8f5487c2f0cc238321ed951ea0504"},
|
||||
{file = "ruff-0.9.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b109c0ad2ececf42e75fa99dc4043ff72a357436bb171900714a9ea581ddef83"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de4367cca3dac99bcbd15c161404e849bb0bfd543664db39232648dc00112dc"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3ee4d7c2c92ddfdaedf0bf31b2b176fa7aa8950efc454628d477394d35638b"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dc1edd1775270e6aa2386119aea692039781429f0be1e0949ea5884e011aa8e"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4a091729086dffa4bd070aa5dab7e39cc6b9d62eb2bef8f3d91172d30d599666"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1bbc6808bf7b15796cef0815e1dfb796fbd383e7dbd4334709642649625e7c5"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:589d1d9f25b5754ff230dce914a174a7c951a85a4e9270613a2b74231fdac2f5"},
|
||||
{file = "ruff-0.9.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc61dd5131742e21103fbbdcad683a8813be0e3c204472d520d9a5021ca8b217"},
|
||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5e2d9126161d0357e5c8f30b0bd6168d2c3872372f14481136d13de9937f79b6"},
|
||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:68660eab1a8e65babb5229a1f97b46e3120923757a68b5413d8561f8a85d4897"},
|
||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c4cae6c4cc7b9b4017c71114115db0445b00a16de3bcde0946273e8392856f08"},
|
||||
{file = "ruff-0.9.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19f505b643228b417c1111a2a536424ddde0db4ef9023b9e04a46ed8a1cb4656"},
|
||||
{file = "ruff-0.9.6-py3-none-win32.whl", hash = "sha256:194d8402bceef1b31164909540a597e0d913c0e4952015a5b40e28c146121b5d"},
|
||||
{file = "ruff-0.9.6-py3-none-win_amd64.whl", hash = "sha256:03482d5c09d90d4ee3f40d97578423698ad895c87314c4de39ed2af945633caa"},
|
||||
{file = "ruff-0.9.6-py3-none-win_arm64.whl", hash = "sha256:0e2bb706a2be7ddfea4a4af918562fdc1bcb16df255e5fa595bbd800ce322a5a"},
|
||||
{file = "ruff-0.9.6.tar.gz", hash = "sha256:81761592f72b620ec8fa1068a6fd00e98a5ebee342a3642efd84454f3031dca9"},
|
||||
{file = "ruff-0.9.7-py3-none-linux_armv6l.whl", hash = "sha256:99d50def47305fe6f233eb8dabfd60047578ca87c9dcb235c9723ab1175180f4"},
|
||||
{file = "ruff-0.9.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d59105ae9c44152c3d40a9c40d6331a7acd1cdf5ef404fbe31178a77b174ea66"},
|
||||
{file = "ruff-0.9.7-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f313b5800483770bd540cddac7c90fc46f895f427b7820f18fe1822697f1fec9"},
|
||||
{file = "ruff-0.9.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:042ae32b41343888f59c0a4148f103208bf6b21c90118d51dc93a68366f4e903"},
|
||||
{file = "ruff-0.9.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:87862589373b33cc484b10831004e5e5ec47dc10d2b41ba770e837d4f429d721"},
|
||||
{file = "ruff-0.9.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a17e1e01bee0926d351a1ee9bc15c445beae888f90069a6192a07a84af544b6b"},
|
||||
{file = "ruff-0.9.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:7c1f880ac5b2cbebd58b8ebde57069a374865c73f3bf41f05fe7a179c1c8ef22"},
|
||||
{file = "ruff-0.9.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e63fc20143c291cab2841dbb8260e96bafbe1ba13fd3d60d28be2c71e312da49"},
|
||||
{file = "ruff-0.9.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91ff963baed3e9a6a4eba2a02f4ca8eaa6eba1cc0521aec0987da8d62f53cbef"},
|
||||
{file = "ruff-0.9.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88362e3227c82f63eaebf0b2eff5b88990280fb1ecf7105523883ba8c3aaf6fb"},
|
||||
{file = "ruff-0.9.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0372c5a90349f00212270421fe91874b866fd3626eb3b397ede06cd385f6f7e0"},
|
||||
{file = "ruff-0.9.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:d76b8ab60e99e6424cd9d3d923274a1324aefce04f8ea537136b8398bbae0a62"},
|
||||
{file = "ruff-0.9.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0c439bdfc8983e1336577f00e09a4e7a78944fe01e4ea7fe616d00c3ec69a3d0"},
|
||||
{file = "ruff-0.9.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:115d1f15e8fdd445a7b4dc9a30abae22de3f6bcabeb503964904471691ef7606"},
|
||||
{file = "ruff-0.9.7-py3-none-win32.whl", hash = "sha256:e9ece95b7de5923cbf38893f066ed2872be2f2f477ba94f826c8defdd6ec6b7d"},
|
||||
{file = "ruff-0.9.7-py3-none-win_amd64.whl", hash = "sha256:3770fe52b9d691a15f0b87ada29c45324b2ace8f01200fb0c14845e499eb0c2c"},
|
||||
{file = "ruff-0.9.7-py3-none-win_arm64.whl", hash = "sha256:b075a700b2533feb7a01130ff656a4ec0d5f340bb540ad98759b8401c32c2037"},
|
||||
{file = "ruff-0.9.7.tar.gz", hash = "sha256:643757633417907510157b206e490c3aa11cab0c087c912f60e07fbafa87a4c6"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -4609,13 +4608,13 @@ django-query = ["django (>=3.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "selenium"
|
||||
version = "4.28.1"
|
||||
version = "4.29.0"
|
||||
description = "Official Python bindings for Selenium WebDriver"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
files = [
|
||||
{file = "selenium-4.28.1-py3-none-any.whl", hash = "sha256:4238847e45e24e4472cfcf3554427512c7aab9443396435b1623ef406fff1cc1"},
|
||||
{file = "selenium-4.28.1.tar.gz", hash = "sha256:0072d08670d7ec32db901bd0107695a330cecac9f196e3afb3fa8163026e022a"},
|
||||
{file = "selenium-4.29.0-py3-none-any.whl", hash = "sha256:ce5d26f1ddc1111641113653af33694c13947dd36c2df09cdd33f554351d372e"},
|
||||
{file = "selenium-4.29.0.tar.gz", hash = "sha256:3a62f7ec33e669364a6c0562a701deb69745b569c50d55f1a912bf8eb33358ba"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -4708,96 +4707,96 @@ tests = ["coverage[toml] (>=5.0.2)", "pytest"]
|
||||
|
||||
[[package]]
|
||||
name = "setproctitle"
|
||||
version = "1.3.4"
|
||||
version = "1.3.5"
|
||||
description = "A Python module to customize the process title"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0f6661a69c68349172ba7b4d5dd65fec2b0917abc99002425ad78c3e58cf7595"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:754bac5e470adac7f7ec2239c485cd0b75f8197ca8a5b86ffb20eb3a3676cc42"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7bc7088c15150745baf66db62a4ced4507d44419eb66207b609f91b64a682af"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a46ef3ecf61e4840fbc1145fdd38acf158d0da7543eda7b773ed2b30f75c2830"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcb09d5c0ffa043254ec9a734a73f3791fec8bf6333592f906bb2e91ed2af1a"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06c16b7a91cdc5d700271899e4383384a61aae83a3d53d0e2e5a266376083342"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9f9732e59863eaeedd3feef94b2b216cb86d40dda4fad2d0f0aaec3b31592716"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e152f4ab9ea1632b5fecdd87cee354f2b2eb6e2dfc3aceb0eb36a01c1e12f94c"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:020ea47a79b2bbd7bd7b94b85ca956ba7cb026e82f41b20d2e1dac4008cead25"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8c52b12b10e4057fc302bd09cb3e3f28bb382c30c044eb3396e805179a8260e4"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-win32.whl", hash = "sha256:a65a147f545f3fac86f11acb2d0b316d3e78139a9372317b7eb50561b2817ba0"},
|
||||
{file = "setproctitle-1.3.4-cp310-cp310-win_amd64.whl", hash = "sha256:66821fada6426998762a3650a37fba77e814a249a95b1183011070744aff47f6"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0f749f07002c2d6fecf37cedc43207a88e6c651926a470a5f229070cf791879"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:90ea8d302a5d30b948451d146e94674a3c5b020cc0ced9a1c28f8ddb0f203a5d"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f859c88193ed466bee4eb9d45fbc29d2253e6aa3ccd9119c9a1d8d95f409a60d"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b3afa5a0ed08a477ded239c05db14c19af585975194a00adf594d48533b23701"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a78fce9018cc3e9a772b6537bbe3fe92380acf656c9f86db2f45e685af376e"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d758e2eed2643afac5f2881542fbb5aa97640b54be20d0a5ed0691d02f0867d"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ef133a1a2ee378d549048a12d56f4ef0e2b9113b0b25b6b77821e9af94d50634"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1d2a154b79d5fb42d1eff06e05e22f0e8091261d877dd47b37d31352b74ecc37"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:202eae632815571297833876a0f407d0d9c7ad9d843b38adbe687fe68c5192ee"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2b0080819859e80a7776ac47cf6accb4b7ad313baf55fabac89c000480dcd103"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-win32.whl", hash = "sha256:9c9d7d1267dee8c6627963d9376efa068858cfc8f573c083b1b6a2d297a8710f"},
|
||||
{file = "setproctitle-1.3.4-cp311-cp311-win_amd64.whl", hash = "sha256:475986ddf6df65d619acd52188336a20f616589403f5a5ceb3fc70cdc137037a"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d06990dcfcd41bb3543c18dd25c8476fbfe1f236757f42fef560f6aa03ac8dfc"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:317218c9d8b17a010ab2d2f0851e8ef584077a38b1ba2b7c55c9e44e79a61e73"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb5fefb53b9d9f334a5d9ec518a36b92a10b936011ac8a6b6dffd60135f16459"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0855006261635e8669646c7c304b494b6df0a194d2626683520103153ad63cc9"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a88e466fcaee659679c1d64dcb2eddbcb4bfadffeb68ba834d9c173a25b6184"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f963b6ed8ba33eda374a98d979e8a0eaf21f891b6e334701693a2c9510613c4c"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:122c2e05697fa91f5d23f00bbe98a9da1bd457b32529192e934095fadb0853f1"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1bba0a866f5895d5b769d8c36b161271c7fd407e5065862ab80ff91c29fbe554"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:97f1f861998e326e640708488c442519ad69046374b2c3fe9bcc9869b387f23c"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:726aee40357d4bdb70115442cb85ccc8e8bc554fc0bbbaa3a57cbe81df42287d"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-win32.whl", hash = "sha256:04d6ba8b816dbb0bfd62000b0c3e583160893e6e8c4233e1dca1a9ae4d95d924"},
|
||||
{file = "setproctitle-1.3.4-cp312-cp312-win_amd64.whl", hash = "sha256:9c76e43cb351ba8887371240b599925cdf3ecececc5dfb7125c71678e7722c55"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d6e3b177e634aa6bbbfbf66d097b6d1cdb80fc60e912c7d8bace2e45699c07dd"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6b17655a5f245b416e127e02087ea6347a48821cc4626bc0fd57101bfcd88afc"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa5057a86df920faab8ee83960b724bace01a3231eb8e3f2c93d78283504d598"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149fdfb8a26a555780c4ce53c92e6d3c990ef7b30f90a675eca02e83c6d5f76d"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ded03546938a987f463c68ab98d683af87a83db7ac8093bbc179e77680be5ba2"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ab9f5b7f2bbc1754bc6292d9a7312071058e5a891b0391e6d13b226133f36aa"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0b19813c852566fa031902124336fa1f080c51e262fc90266a8c3d65ca47b74c"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:db78b645dc63c0ccffca367a498f3b13492fb106a2243a1e998303ba79c996e2"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b669aaac70bd9f03c070270b953f78d9ee56c4af6f0ff9f9cd3e6d1878c10b40"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6dc3d656702791565994e64035a208be56b065675a5bc87b644c657d6d9e2232"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-win32.whl", hash = "sha256:091f682809a4d12291cf0205517619d2e7014986b7b00ebecfde3d76f8ae5a8f"},
|
||||
{file = "setproctitle-1.3.4-cp313-cp313-win_amd64.whl", hash = "sha256:adcd6ba863a315702184d92d3d3bbff290514f24a14695d310f02ae5e28bd1f7"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:acf41cf91bbc5a36d1fa4455a818bb02bf2a4ccfed2f892ba166ba2fcbb0ec8a"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ceb3ce3262b0e8e088e4117175591b7a82b3bdc5e52e33b1e74778b5fb53fd38"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b2ef636a6a25fe7f3d5a064bea0116b74a4c8c7df9646b17dc7386c439a26cf"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:28b8614de08679ae95bc4e8d6daaef6b61afdf027fa0d23bf13d619000286b3c"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24f3c8be826a7d44181eac2269b15b748b76d98cd9a539d4c69f09321dcb5c12"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc9d79b1bf833af63b7c720a6604eb16453ac1ad4e718eb8b59d1f97d986b98c"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:fb693000b65842c85356b667d057ae0d0bac6519feca7e1c437cc2cfeb0afc59"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:a166251b8fbc6f2755e2ce9d3c11e9edb0c0c7d2ed723658ff0161fbce26ac1c"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:0361428e6378911a378841509c56ba472d991cbed1a7e3078ec0cacc103da44a"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:62d66e0423e3bd520b4c897063506b309843a8d07343fbfad04197e91a4edd28"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-win32.whl", hash = "sha256:5edd01909348f3b0b2da329836d6b5419cd4869fec2e118e8ff3275b38af6267"},
|
||||
{file = "setproctitle-1.3.4-cp38-cp38-win_amd64.whl", hash = "sha256:59e0dda9ad245921af0328035a961767026e1fa94bb65957ab0db0a0491325d6"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bdaaa81a6e95a0a19fba0285f10577377f3503ae4e9988b403feba79da3e2f80"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ee5b19a2d794463bcc19153dfceede7beec784b4cf7967dec0bc0fc212ab3a3"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3058a1bb0c767b3a6ccbb38b27ef870af819923eb732e21e44a3f300370fe159"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a97d37ee4fe0d1c6e87d2a97229c27a88787a8f4ebfbdeee95f91b818e52efe"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e61dd7d05da11fc69bb86d51f1e0ee08f74dccf3ecf884c94de41135ffdc75d"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eb115d53dc2a1299ae72f1119c96a556db36073bacb6da40c47ece5db0d9587"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:342570716e2647a51ea859b8a9126da9dc1a96a0153c9c0a3514effd60ab57ad"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0ad212ae2b03951367a69584af034579b34e1e4199a75d377ef9f8e08ee299b1"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:4afcb38e22122465013f4621b7e9ff8d42a7a48ae0ffeb94133a806cb91b4aad"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:30bb223e6c3f95ad9e9bb2a113292759e947d1cfd60dbd4adb55851c370006b2"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-win32.whl", hash = "sha256:5f0521ed3bb9f02e9486573ea95e2062cd6bf036fa44e640bd54a06f22d85f35"},
|
||||
{file = "setproctitle-1.3.4-cp39-cp39-win_amd64.whl", hash = "sha256:0baadeb27f9e97e65922b4151f818b19c311d30b9efdb62af0e53b3db4006ce2"},
|
||||
{file = "setproctitle-1.3.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:939d364a187b2adfbf6ae488664277e717d56c7951a4ddeb4f23b281bc50bfe5"},
|
||||
{file = "setproctitle-1.3.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb8a6a19be0cbf6da6fcbf3698b76c8af03fe83e4bd77c96c3922be3b88bf7da"},
|
||||
{file = "setproctitle-1.3.4-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:779006f9e1aade9522a40e8d9635115ab15dd82b7af8e655967162e9c01e2573"},
|
||||
{file = "setproctitle-1.3.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:5519f2a7b8c535b0f1f77b30441476571373add72008230c81211ee17b423b57"},
|
||||
{file = "setproctitle-1.3.4-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:743836d484151334ebba1490d6907ca9e718fe815dcd5756f2a01bc3067d099c"},
|
||||
{file = "setproctitle-1.3.4-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abda20aff8d1751e48d7967fa8945fef38536b82366c49be39b83678d4be3893"},
|
||||
{file = "setproctitle-1.3.4-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a2041b5788ce52f218b5be94af458e04470f997ab46fdebd57cf0b8374cc20e"},
|
||||
{file = "setproctitle-1.3.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2c3b1ce68746557aa6e6f4547e76883925cdc7f8d7c7a9f518acd203f1265ca5"},
|
||||
{file = "setproctitle-1.3.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:0b6a4cbabf024cb263a45bdef425760f14470247ff223f0ec51699ca9046c0fe"},
|
||||
{file = "setproctitle-1.3.4-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e55d7ecc68bdc80de5a553691a3ed260395d5362c19a266cf83cbb4e046551f"},
|
||||
{file = "setproctitle-1.3.4-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02ca3802902d91a89957f79da3ec44b25b5804c88026362cb85eea7c1fbdefd1"},
|
||||
{file = "setproctitle-1.3.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:47669fc8ed8b27baa2d698104732234b5389f6a59c37c046f6bcbf9150f7a94e"},
|
||||
{file = "setproctitle-1.3.4.tar.gz", hash = "sha256:3b40d32a3e1f04e94231ed6dfee0da9e43b4f9c6b5450d53e6dd7754c34e0c50"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:02870e0cb0de7f68a7a8a5b23c2bc0ce63821cab3d9b126f9be80bb6cd674c80"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:55b278135be742b8901067479626d909f6613bd2d2c4fd0de6bb46f80e07a919"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53fc971f7bf7a674f571a23cdec70f2f0ac88152c59c06aa0808d0be6d834046"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fb0500e1bc6f00b8ba696c3743ddff14c8679e3c2ca9d292c008ac51488d17cf"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:995b3ac1b5fe510f4e1d1c19ebf19f4bceb448f2d6e8d99ea23f33cb6f1a277e"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5a05e2c3fdfbda32b9c9da72d0506398d1efb5bd2c5981b9e12d3622eb3d4f9"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:310c7f4ca4c8476a9840b2cd4b22ee602a49a3c902fdcd2dd8284685abd10a9a"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:867af4a5c3d85484fbcc50ea88bcd375acf709cff88a3259575361849c0da351"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8ec0a7fe9f1ba90900144489bc93ce7dd4dec3f3df1e7f188c9e58364fe4a4c5"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:aaee7acba2733a14a886488b7495bfec4a8d6407124c04a0946dbde1684230a3"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-win32.whl", hash = "sha256:bd2cccd972e4282af4ce2c13cd9ebdf07be157eabafd8ce648fffdc8ae6fbe28"},
|
||||
{file = "setproctitle-1.3.5-cp310-cp310-win_amd64.whl", hash = "sha256:81f2328ac34c9584e1e5f87eea916c0bc48476a06606a07debae07acdd7ab5ea"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1c8dcc250872385f2780a5ea58050b58cbc8b6a7e8444952a5a65c359886c593"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ca82fae9eb4800231dd20229f06e8919787135a5581da245b8b05e864f34cc8b"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0424e1d33232322541cb36fb279ea5242203cd6f20de7b4fb2a11973d8e8c2ce"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fec8340ab543144d04a9d805d80a0aad73fdeb54bea6ff94e70d39a676ea4ec0"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eab441c89f181271ab749077dcc94045a423e51f2fb0b120a1463ef9820a08d0"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2c371550a2288901a0dcd84192691ebd3197a43c95f3e0b396ed6d1cedf5c6c"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:78288ff5f9c415c56595b2257ad218936dd9fa726b36341b373b31ca958590fe"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f1f13a25fc46731acab518602bb1149bfd8b5fabedf8290a7c0926d61414769d"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1534d6cd3854d035e40bf4c091984cbdd4d555d7579676d406c53c8f187c006f"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:62a01c76708daac78b9688ffb95268c57cb57fa90b543043cda01358912fe2db"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-win32.whl", hash = "sha256:ea07f29735d839eaed985990a0ec42c8aecefe8050da89fec35533d146a7826d"},
|
||||
{file = "setproctitle-1.3.5-cp311-cp311-win_amd64.whl", hash = "sha256:ab3ae11e10d13d514d4a5a15b4f619341142ba3e18da48c40e8614c5a1b5e3c3"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:523424b9be4dea97d95b8a584b183f35c7bab2d0a3d995b01febf5b8a8de90e4"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b6ec1d86c1b4d7b5f2bdceadf213310cf24696b82480a2a702194b8a0bfbcb47"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea6c505264275a43e9b2acd2acfc11ac33caf52bc3167c9fced4418a810f6b1c"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b91e68e6685998e6353f296100ecabc313a6cb3e413d66a03d74b988b61f5ff"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bc1fda208ae3a2285ad27aeab44c41daf2328abe58fa3270157a739866779199"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:828727d220e46f048b82289018300a64547b46aaed96bf8810c05fe105426b41"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:83b016221cf80028b2947be20630faa14e3e72a403e35f0ba29550b4e856767b"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6d8a411e752e794d052434139ca4234ffeceeb8d8d8ddc390a9051d7942b2726"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:50cfbf86b9c63a2c2903f1231f0a58edeb775e651ae1af84eec8430b0571f29b"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f3b5e2eacd572444770026c9dd3ddc7543ce427cdf452d40a408d1e95beefb30"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-win32.whl", hash = "sha256:cf4e3ded98027de2596c6cc5bbd3302adfb3ca315c848f56516bb0b7e88de1e9"},
|
||||
{file = "setproctitle-1.3.5-cp312-cp312-win_amd64.whl", hash = "sha256:f7a8c01ffd013dda2bed6e7d5cb59fbb609e72f805abf3ee98360f38f7758d9b"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:162fd76781f57f42ddf27c475e5fef6a8df4fdd69b28dd554e53e2eb2bfe0f95"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4969d996bdfbe23bbd023cd0bae6c73a27371615c4ec5296a60cecce268659ef"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd70c95a94473216e7c7a7a1f7d8ecbaca5b16d4ba93ddbfd32050fc485a8451"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7a887582bfdb6dcbc482db0ef9e630ad23ca95875806ef2b444bf6fbd7b7d7ca"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:755671c39a9e70834eeec6dc6b61e344399c49881d2e7ea3534a1c69669dd9cc"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ab52b4c2ce056a1b60d439991a81ca90f019488d4b4f64b2779e6badd3677e6"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:36178b944019ec7fc52bb967ffeee296a11d373734a7be276755bedb3db5c141"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:269d41cd4f085b69821d1ee6599124f02dbbc79962b256e260b6c9021d037994"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d880630fd81d1b3bde121c352ca7ea2f2ff507ef40c3c011d0928ed491f912c9"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8a7fed67ab49f60bd51f3b4cffff3f8d754d1bb0a40e42869911301ec6519b65"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-win32.whl", hash = "sha256:e9c0d0cfcf715631b10d5950d04a9978f63bc46535724ef7c2eaf1dca9988642"},
|
||||
{file = "setproctitle-1.3.5-cp313-cp313-win_amd64.whl", hash = "sha256:e1d28eb98c91fbebd3e443a45c7da5d84974959851ef304c330eabd654a386f1"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8995a1217b52d11d92bafd069961a47c5e13d8751ca976a32b3ecbbd471eaf9b"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae2ce64ea87837c4e3e65a7a232ff80cf09aa7d916e74cb34a245c47fcd87981"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20b84de1780bbb0adc67560a113a0ea57e6ecfce2325680de8efe6c2a2f781ac"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b1d2628ac9868f960d7e87b3a9b2bb337104c3644b699e52e01efd7e106e4fe"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa912c4d08c66afda30dd5af8f2e9c59065dfc36a51edbd5419c3a7c962875aa"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4f783e100f8b451cd92fcabd3b831edfb1f7cb02be4a79b972f138e0001885"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:8ca56e39d10b6758046694a84950e5c5570a034c409ef3337595f64fc2cfa94d"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:8915d69260ba6a6aaf9a48f6b53dbf9f8e4dc0cb4ae25bc5edb16a1666b6e47c"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7edd4fbb9fd17ed0e5a7f8bde9fa61c3987a34372084c45bab4eab6a2e554762"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d0b19fd76d46b8096a463724739c3b09cf5ce38317f559f56f424f6ce7158de3"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-win32.whl", hash = "sha256:53ce572cdbd43a0bed2aa24299cd823ebf233a7fa720cc7f8634728c213679c0"},
|
||||
{file = "setproctitle-1.3.5-cp38-cp38-win_amd64.whl", hash = "sha256:a58f00f35d6038ce1e8a9e5f87cb5ecce13ce118c5977a603566ad1fccc8d2cb"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c4b299b5bbadf00034978b8d741c85af25173146747eb9dab22596ec805a52d6"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d57e7626329d4fb138da5ce15270b08a91326969956fb19c7a8fec2639066704"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4272295721cf1fd2acf960b674d6dc09bec87f2a1e48995817b4ec4a3d483faf"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8305b6e6c203222c61318f338f1de08269ec66c247bf251593c215ff1fbeaf9"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:becc9f3f605936506d2bd63d9cf817b7ee66b10d204184c4a633064dbed579d6"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4629de80c47155a26e8d87a0a92d9428aa8d79ccfe2c20fd18888580619704e1"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f1af1d310b5b6cda692da52bd862a9833086c0a3f8380fa92505dd23857dcf60"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3bb6ea3d6e690677619508050bc681d86223723bdf67e4e8a8dffc3d04ca3044"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:322067ef1ffe70d297b00bee8a3862fed96021aa4318e3bce2d7c3bfa7a8d1e7"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1b58d49c32a46c48dcc2812635a89e6bee31139b03818da49a0bbaeaf01edef9"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-win32.whl", hash = "sha256:707c23d4a88f5e66f1005d93558bf84eb45fc0fb0c4f33480a0c7d0895e8e848"},
|
||||
{file = "setproctitle-1.3.5-cp39-cp39-win_amd64.whl", hash = "sha256:c64199a73d442a06d372b5286942229a43e86fa41bf36f317dcc60c036aff0bb"},
|
||||
{file = "setproctitle-1.3.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:dc66b84beb0d5eb03abf0c3140c6d2cbe3d67ae9f0824a09dfa8c6ff164319a6"},
|
||||
{file = "setproctitle-1.3.5-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:31dc9b330e7cac7685bdef790747c07914081c11ee1066eb0c597303dfb52010"},
|
||||
{file = "setproctitle-1.3.5-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4028639b511f5e641d116b3b54ad70c637ebd1b4baac0948283daf11b104119f"},
|
||||
{file = "setproctitle-1.3.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:6bddef4e27d0ed74e44b58bf050bc3108591bf17d20d461fc59cd141282f849c"},
|
||||
{file = "setproctitle-1.3.5-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:9996be1d1df399c3cdc6d72ce0064e46bc74fc6e29fe16a328511a303dd4d418"},
|
||||
{file = "setproctitle-1.3.5-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5cefc2dbdc48121022c3c05644cd3706f08e0b3c0ce07814d3c04daba0617936"},
|
||||
{file = "setproctitle-1.3.5-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cef63879c79a570aabf7c158f453bf8d1285f0fda4b6b9b7a52d64b49c084d40"},
|
||||
{file = "setproctitle-1.3.5-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a863296a31fb578726c570314cb78ff3a3fddb65963dc01ea33731760f20a92c"},
|
||||
{file = "setproctitle-1.3.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b63bda3cb4b6526720dc7c6940b891c593f41771d119aeb8763875801ce2296d"},
|
||||
{file = "setproctitle-1.3.5-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:95913af603da5b4c7635bf1fb67ecc5df7c18360b6cfb6740fd743bb150a6e17"},
|
||||
{file = "setproctitle-1.3.5-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36b130cf8fe76dc05ad1d48cc9ff3699eb1f0d8edbf6f46a3ce46a7041e49d7b"},
|
||||
{file = "setproctitle-1.3.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fe3bfd5e51c24349d022e062a96c316a1b8862ea9a0cf5ea2a8b2ae008b77cec"},
|
||||
{file = "setproctitle-1.3.5.tar.gz", hash = "sha256:1e6eaeaf8a734d428a95d8c104643b39af7d247d604f40a7bebcf3960a853c5e"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
@ -5007,13 +5006,13 @@ wsproto = ">=0.14"
|
||||
|
||||
[[package]]
|
||||
name = "twilio"
|
||||
version = "9.4.5"
|
||||
version = "9.4.6"
|
||||
description = "Twilio API client and TwiML generator"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
{file = "twilio-9.4.5-py2.py3-none-any.whl", hash = "sha256:284295946a5dcdaae65de9116c35db9065e1f3bd237d81da05b89fe1825013c6"},
|
||||
{file = "twilio-9.4.5.tar.gz", hash = "sha256:8db69103a850cd05aaaa6bfb6952ef7a5d784aaff83f01d9a0c594b5ce784cd1"},
|
||||
{file = "twilio-9.4.6-py2.py3-none-any.whl", hash = "sha256:6d7d677fa9ded4ee0c366ad0155a1e0af51e129109af603b6ec9cdc8826a5c37"},
|
||||
{file = "twilio-9.4.6.tar.gz", hash = "sha256:ff33a6c3609f4a0769d02c4eb75f7ab55ff2ba962762b076cd39ef7da56fdaa4"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -5854,12 +5853,13 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
|
||||
|
||||
[[package]]
|
||||
name = "zxcvbn"
|
||||
version = "4.4.28"
|
||||
version = "4.5.0"
|
||||
description = ""
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
files = [
|
||||
{file = "zxcvbn-4.4.28.tar.gz", hash = "sha256:151bd816817e645e9064c354b13544f85137ea3320ca3be1fb6873ea75ef7dc1"},
|
||||
{file = "zxcvbn-4.5.0-py2.py3-none-any.whl", hash = "sha256:2b6eed621612ce6d65e6e4c7455b966acee87d0280e257956b1f06ccc66bd5ff"},
|
||||
{file = "zxcvbn-4.5.0.tar.gz", hash = "sha256:70392c0fff39459d7f55d0211151401e79e76fcc6e2c22b61add62900359c7c1"},
|
||||
]
|
||||
|
||||
[metadata]
|
||||
|
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "authentik"
|
||||
version = "2024.12.3"
|
||||
version = "2025.2.0"
|
||||
description = ""
|
||||
authors = ["authentik Team <hello@goauthentik.io>"]
|
||||
|
||||
|
10
schema.yml
10
schema.yml
@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: authentik
|
||||
version: 2024.12.3
|
||||
version: 2025.2.0
|
||||
description: Making authentication simple.
|
||||
contact:
|
||||
email: hello@goauthentik.io
|
||||
@ -39482,6 +39482,7 @@ components:
|
||||
- authentik.providers.ldap
|
||||
- authentik.providers.oauth2
|
||||
- authentik.providers.proxy
|
||||
- authentik.providers.rac
|
||||
- authentik.providers.radius
|
||||
- authentik.providers.saml
|
||||
- authentik.providers.scim
|
||||
@ -39522,7 +39523,6 @@ components:
|
||||
- authentik.enterprise.audit
|
||||
- authentik.enterprise.providers.google_workspace
|
||||
- authentik.enterprise.providers.microsoft_entra
|
||||
- authentik.enterprise.providers.rac
|
||||
- authentik.enterprise.providers.ssf
|
||||
- authentik.enterprise.stages.authenticator_endpoint_gdtc
|
||||
- authentik.enterprise.stages.source
|
||||
@ -46625,6 +46625,9 @@ components:
|
||||
- authentik_providers_oauth2.scopemapping
|
||||
- authentik_providers_oauth2.oauth2provider
|
||||
- authentik_providers_proxy.proxyprovider
|
||||
- authentik_providers_rac.racprovider
|
||||
- authentik_providers_rac.endpoint
|
||||
- authentik_providers_rac.racpropertymapping
|
||||
- authentik_providers_radius.radiusprovider
|
||||
- authentik_providers_radius.radiusproviderpropertymapping
|
||||
- authentik_providers_saml.samlprovider
|
||||
@ -46694,9 +46697,6 @@ components:
|
||||
- authentik_providers_google_workspace.googleworkspaceprovidermapping
|
||||
- authentik_providers_microsoft_entra.microsoftentraprovider
|
||||
- authentik_providers_microsoft_entra.microsoftentraprovidermapping
|
||||
- authentik_providers_rac.racprovider
|
||||
- authentik_providers_rac.endpoint
|
||||
- authentik_providers_rac.racpropertymapping
|
||||
- authentik_providers_ssf.ssfprovider
|
||||
- authentik_stages_authenticator_endpoint_gdtc.authenticatorendpointgdtcstage
|
||||
- authentik_stages_source.sourcestage
|
||||
|
@ -4,7 +4,7 @@ This package provides a generated API Client for [authentik](https://goauthentik
|
||||
|
||||
### Building
|
||||
|
||||
See https://docs.goauthentik.io/docs/developer-docs/making-schema-changes
|
||||
See https://docs.goauthentik.io/docs/developer-docs/api/making-schema-changes#building-the-web-client
|
||||
|
||||
### Consuming
|
||||
|
||||
|
@ -74,7 +74,7 @@ const interfaces = [
|
||||
["user/UserInterface.ts", "user"],
|
||||
["flow/FlowInterface.ts", "flow"],
|
||||
["standalone/api-browser/index.ts", "standalone/api-browser"],
|
||||
["enterprise/rac/index.ts", "enterprise/rac"],
|
||||
["rac/index.ts", "rac"],
|
||||
["standalone/loading/index.ts", "standalone/loading"],
|
||||
["polyfill/poly.ts", "."],
|
||||
];
|
||||
@ -88,7 +88,11 @@ const baseArgs = {
|
||||
treeShaking: true,
|
||||
external: ["*.woff", "*.woff2"],
|
||||
tsconfig: "./tsconfig.json",
|
||||
loader: { ".css": "text", ".md": "text" },
|
||||
loader: {
|
||||
".css": "text",
|
||||
".md": "text",
|
||||
".mdx": "text",
|
||||
},
|
||||
define: definitions,
|
||||
format: "esm",
|
||||
logOverride: {
|
||||
|
8
web/package-lock.json
generated
8
web/package-lock.json
generated
@ -23,7 +23,7 @@
|
||||
"@floating-ui/dom": "^1.6.11",
|
||||
"@formatjs/intl-listformat": "^7.5.7",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@goauthentik/api": "^2024.12.3-1739814462",
|
||||
"@goauthentik/api": "^2025.2.0-1740418530",
|
||||
"@lit-labs/ssr": "^3.2.2",
|
||||
"@lit/context": "^1.1.2",
|
||||
"@lit/localize": "^0.12.2",
|
||||
@ -1814,9 +1814,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@goauthentik/api": {
|
||||
"version": "2024.12.3-1739814462",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.12.3-1739814462.tgz",
|
||||
"integrity": "sha512-qWGsq7zP0rG1PfjZA+iimaX4cVkd1n2JA/WceTOKgBmqnomQSI7SJNkdSpD+Qdy76PI0UuQWN73PInq/3rmm5Q=="
|
||||
"version": "2025.2.0-1740418530",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.2.0-1740418530.tgz",
|
||||
"integrity": "sha512-vFoIzmEuQ7sbWxIEFP7l7OwEMt8M9TqvxScyv0liQSgGd/xanc2W/R+JuOdhq9ePrCfXa1YcmuZtT41HZXFP6g=="
|
||||
},
|
||||
"node_modules/@goauthentik/web": {
|
||||
"resolved": "",
|
||||
|
@ -11,7 +11,7 @@
|
||||
"@floating-ui/dom": "^1.6.11",
|
||||
"@formatjs/intl-listformat": "^7.5.7",
|
||||
"@fortawesome/fontawesome-free": "^6.6.0",
|
||||
"@goauthentik/api": "^2024.12.3-1739814462",
|
||||
"@goauthentik/api": "^2025.2.0-1740418530",
|
||||
"@lit-labs/ssr": "^3.2.2",
|
||||
"@lit/context": "^1.1.2",
|
||||
"@lit/localize": "^0.12.2",
|
||||
|
@ -6,7 +6,7 @@ const config: KnipConfig = {
|
||||
"./src/user/UserInterface.ts",
|
||||
"./src/flow/FlowInterface.ts",
|
||||
"./src/standalone/api-browser/index.ts",
|
||||
"./src/enterprise/rac/index.ts",
|
||||
"./src/rac/index.ts",
|
||||
"./src/standalone/loading/index.ts",
|
||||
"./src/polyfill/poly.ts",
|
||||
],
|
||||
|
@ -7,6 +7,7 @@ import "@goauthentik/components/ak-radio-input";
|
||||
import "@goauthentik/components/ak-switch-input";
|
||||
import "@goauthentik/components/ak-text-input";
|
||||
import "@goauthentik/components/ak-textarea-input";
|
||||
import "@goauthentik/elements/Alert.js";
|
||||
import {
|
||||
CapabilitiesEnum,
|
||||
WithCapabilitiesConfig,
|
||||
@ -21,7 +22,7 @@ import "@goauthentik/elements/forms/SearchSelect";
|
||||
import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
import { TemplateResult, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
@ -120,7 +121,12 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
const alertMsg = msg(
|
||||
"Using this form will only create an Application. In order to authenticate with the application, you will have to manually pair it with a Provider.",
|
||||
);
|
||||
|
||||
return html`<form class="pf-c-form pf-m-horizontal">
|
||||
${this.instance ? nothing : html`<ak-alert level="pf-m-info">${alertMsg}</ak-alert>`}
|
||||
<ak-text-input
|
||||
name="name"
|
||||
value=${ifDefined(this.instance?.name)}
|
||||
|
@ -50,7 +50,7 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
||||
}
|
||||
pageDescription(): string {
|
||||
return msg(
|
||||
str`External applications that use ${this.brand.brandingTitle || "authentik"} as an identity provider via protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.`,
|
||||
str`External applications that use ${this.brand?.brandingTitle ?? "authentik"} as an identity provider via protocols like OAuth2 and SAML. All applications are shown here, even ones you cannot access.`,
|
||||
);
|
||||
}
|
||||
pageIcon(): string {
|
||||
@ -85,10 +85,6 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
||||
];
|
||||
}
|
||||
|
||||
renderSectionBefore(): TemplateResult {
|
||||
return html`<ak-application-wizard-hint></ak-application-wizard-hint>`;
|
||||
}
|
||||
|
||||
renderSidebarAfter(): TemplateResult {
|
||||
return html`<div class="pf-c-sidebar__panel pf-m-width-25">
|
||||
<div class="pf-c-card">
|
||||
@ -160,12 +156,21 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
|
||||
}
|
||||
|
||||
renderObjectCreate(): TemplateResult {
|
||||
return html`<ak-forms-modal .open=${getURLParam("createForm", false)}>
|
||||
<span slot="submit"> ${msg("Create")} </span>
|
||||
<span slot="header"> ${msg("Create Application")} </span>
|
||||
<ak-application-form slot="form"> </ak-application-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
</ak-forms-modal>`;
|
||||
return html` <ak-application-wizard .open=${getURLParam("createWizard", false)}>
|
||||
<button
|
||||
slot="trigger"
|
||||
class="pf-c-button pf-m-primary"
|
||||
data-ouia-component-id="start-application-wizard"
|
||||
>
|
||||
${msg("Create with Provider")}
|
||||
</button>
|
||||
</ak-application-wizard>
|
||||
<ak-forms-modal .open=${getURLParam("createForm", false)}>
|
||||
<span slot="submit"> ${msg("Create")} </span>
|
||||
<span slot="header"> ${msg("Create Application")} </span>
|
||||
<ak-application-form slot="form"> </ak-application-form>
|
||||
<button slot="trigger" class="pf-c-button pf-m-primary">${msg("Create")}</button>
|
||||
</ak-forms-modal>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ export class ApplicationWizardStep extends WizardStep {
|
||||
// As recommended in [WizardStep](../../../components/ak-wizard/WizardStep.ts), we override
|
||||
// these fields and provide them to all the child classes.
|
||||
wizardTitle = msg("New application");
|
||||
wizardDescription = msg("Create a new application");
|
||||
wizardDescription = msg("Create a new application and configure a provider for it.");
|
||||
canCancel = true;
|
||||
|
||||
// This should be overridden in the children for more precise targeting.
|
||||
|
@ -31,9 +31,9 @@ export class BoundPoliciesList extends Table<PolicyBinding> {
|
||||
|
||||
@property({ type: Array })
|
||||
allowedTypes: PolicyBindingCheckTarget[] = [
|
||||
PolicyBindingCheckTarget.policy,
|
||||
PolicyBindingCheckTarget.group,
|
||||
PolicyBindingCheckTarget.user,
|
||||
PolicyBindingCheckTarget.policy,
|
||||
];
|
||||
|
||||
@property({ type: Array })
|
||||
|
@ -58,9 +58,9 @@ export class PolicyBindingForm extends ModelForm<PolicyBinding, string> {
|
||||
|
||||
@property({ type: Array })
|
||||
allowedTypes: PolicyBindingCheckTarget[] = [
|
||||
PolicyBindingCheckTarget.policy,
|
||||
PolicyBindingCheckTarget.group,
|
||||
PolicyBindingCheckTarget.user,
|
||||
PolicyBindingCheckTarget.policy,
|
||||
];
|
||||
|
||||
@property({ type: Array })
|
||||
|
@ -105,6 +105,22 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Maximum distance")}
|
||||
name="historyMaxDistanceKm"
|
||||
>
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
value="${first(this.instance?.historyMaxDistanceKm, 100)}"
|
||||
class="pf-c-form-control"
|
||||
/>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Maximum distance a login attempt is allowed from in kilometers.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Distance tolerance")}
|
||||
name="distanceToleranceKm"
|
||||
@ -133,27 +149,6 @@ export class GeoIPPolicyForm extends BasePolicyForm<GeoIPPolicy> {
|
||||
${msg("Amount of previous login events to check against.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Maximum distance")}
|
||||
name="historyMaxDistanceKm"
|
||||
>
|
||||
<input
|
||||
type="number"
|
||||
min="1"
|
||||
value="${first(this.instance?.historyMaxDistanceKm, 100)}"
|
||||
class="pf-c-form-control"
|
||||
/>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Maximum distance a login attempt is allowed from in kilometers.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
</div>
|
||||
</ak-form-group>
|
||||
<ak-form-group>
|
||||
<span slot="header"> ${msg("Distance settings (Impossible travel)")} </span>
|
||||
<div slot="body" class="pf-c-form">
|
||||
<ak-form-element-horizontal name="checkImpossibleTravel">
|
||||
<label class="pf-c-switch">
|
||||
<input
|
||||
|
@ -4,7 +4,7 @@ import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { EVENT_REFRESH } from "@goauthentik/common/constants";
|
||||
import renderDescriptionList from "@goauthentik/components/DescriptionList";
|
||||
import "@goauthentik/components/events/ObjectChangelog";
|
||||
import MDProviderOAuth2 from "@goauthentik/docs/add-secure-apps/providers/oauth2/index.md";
|
||||
import MDProviderOAuth2 from "@goauthentik/docs/add-secure-apps/providers/oauth2/index.mdx";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import "@goauthentik/elements/CodeMirror";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
|
@ -13,7 +13,7 @@ import MDNginxStandalone from "@goauthentik/docs/add-secure-apps/providers/proxy
|
||||
import MDTraefikCompose from "@goauthentik/docs/add-secure-apps/providers/proxy/_traefik_compose.md";
|
||||
import MDTraefikIngress from "@goauthentik/docs/add-secure-apps/providers/proxy/_traefik_ingress.md";
|
||||
import MDTraefikStandalone from "@goauthentik/docs/add-secure-apps/providers/proxy/_traefik_standalone.md";
|
||||
import MDHeaderAuthentication from "@goauthentik/docs/add-secure-apps/providers/proxy/header_authentication.md";
|
||||
import MDHeaderAuthentication from "@goauthentik/docs/add-secure-apps/providers/proxy/header_authentication.mdx";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import "@goauthentik/elements/CodeMirror";
|
||||
import "@goauthentik/elements/Markdown";
|
||||
@ -118,7 +118,7 @@ export class ProxyProviderViewPage extends AKElement {
|
||||
}
|
||||
|
||||
renderConfig(): TemplateResult {
|
||||
const serves = [
|
||||
const servers = [
|
||||
{
|
||||
label: msg("Nginx (Ingress)"),
|
||||
md: MDNginxIngress,
|
||||
@ -184,7 +184,7 @@ export class ProxyProviderViewPage extends AKElement {
|
||||
},
|
||||
];
|
||||
return html`<ak-tabs pageIdentifier="proxy-setup">
|
||||
${serves.map((server) => {
|
||||
${servers.map((server) => {
|
||||
return html`<section
|
||||
slot="page-${convertToSlug(server.label)}"
|
||||
data-tab-title="${server.label}"
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 772 KiB After Width: | Height: | Size: 628 KiB |
@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
|
||||
export const ERROR_CLASS = "pf-m-danger";
|
||||
export const PROGRESS_CLASS = "pf-m-in-progress";
|
||||
export const CURRENT_CLASS = "pf-m-current";
|
||||
export const VERSION = "2024.12.3";
|
||||
export const VERSION = "2025.2.0";
|
||||
export const TITLE_DEFAULT = "authentik";
|
||||
export const ROUTE_SEPARATOR = ";";
|
||||
|
||||
|
@ -13,6 +13,7 @@ export interface GlobalAuthentik {
|
||||
build: string;
|
||||
api: {
|
||||
base: string;
|
||||
relBase: string;
|
||||
};
|
||||
}
|
||||
|
||||
@ -27,6 +28,7 @@ export function globalAK(): GlobalAuthentik {
|
||||
ak.brand = CurrentBrandFromJSON(ak.brand);
|
||||
ak.config = ConfigFromJSON(ak.config);
|
||||
}
|
||||
const apiBase = new URL(process.env.AK_API_BASE_PATH || window.location.origin);
|
||||
if (!ak) {
|
||||
return {
|
||||
config: ConfigFromJSON({
|
||||
@ -39,7 +41,8 @@ export function globalAK(): GlobalAuthentik {
|
||||
versionSubdomain: "",
|
||||
build: "",
|
||||
api: {
|
||||
base: process.env.AK_API_BASE_PATH || window.location.origin,
|
||||
base: apiBase.toString(),
|
||||
relBase: apiBase.pathname,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -45,6 +45,8 @@ html > form > input {
|
||||
left: -2000px;
|
||||
}
|
||||
|
||||
/*#region Icons*/
|
||||
|
||||
.pf-icon {
|
||||
display: inline-block;
|
||||
font-style: normal;
|
||||
@ -54,6 +56,18 @@ html > form > input {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.pf-c-form-control {
|
||||
--pf-c-form-control--m-caps-lock--BackgroundUrl: url("data:image/svg+xml;charset=utf8,%3Csvg fill='%23aaabac' viewBox='0 0 56 56' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M 20.7812 37.6211 L 35.2421 37.6211 C 38.5233 37.6211 40.2577 35.6992 40.2577 32.6055 L 40.2577 28.4570 L 49.1404 28.4570 C 51.0859 28.4570 52.6329 27.3086 52.6329 25.5039 C 52.6329 24.4024 52.0703 23.5351 51.0158 22.6211 L 30.9062 4.8789 C 29.9452 4.0351 29.0546 3.4727 27.9999 3.4727 C 26.9687 3.4727 26.0780 4.0351 25.1171 4.8789 L 4.9843 22.6445 C 3.8828 23.6055 3.3671 24.4024 3.3671 25.5039 C 3.3671 27.3086 4.9140 28.4570 6.8828 28.4570 L 15.7421 28.4570 L 15.7421 32.6055 C 15.7421 35.6992 17.4999 37.6211 20.7812 37.6211 Z M 21.1562 34.0820 C 20.2655 34.0820 19.6562 33.4961 19.6562 32.6055 L 19.6562 25.7149 C 19.6562 25.1524 19.4452 24.9180 18.8828 24.9180 L 8.6640 24.9180 C 8.4999 24.9180 8.4296 24.8476 8.4296 24.7305 C 8.4296 24.6367 8.4530 24.5430 8.5702 24.4492 L 27.5077 7.9961 C 27.7187 7.8086 27.8359 7.7383 27.9999 7.7383 C 28.1640 7.7383 28.3046 7.8086 28.4921 7.9961 L 47.4532 24.4492 C 47.5703 24.5430 47.5939 24.6367 47.5939 24.7305 C 47.5939 24.8476 47.4998 24.9180 47.3356 24.9180 L 37.1406 24.9180 C 36.5780 24.9180 36.3671 25.1524 36.3671 25.7149 L 36.3671 32.6055 C 36.3671 33.4727 35.7109 34.0820 34.8671 34.0820 Z M 19.7733 52.5273 L 36.0624 52.5273 C 38.7577 52.5273 40.3046 51.0273 40.3046 48.3086 L 40.3046 44.9336 C 40.3046 42.2148 38.7577 40.6680 36.0624 40.6680 L 19.7733 40.6680 C 17.0546 40.6680 15.5077 42.2383 15.5077 44.9336 L 15.5077 48.3086 C 15.5077 51.0039 17.0546 52.5273 19.7733 52.5273 Z M 20.3124 49.2227 C 19.4921 49.2227 19.0468 48.8008 19.0468 47.9805 L 19.0468 45.2617 C 19.0468 44.4414 19.4921 43.9727 20.3124 43.9727 L 35.5233 43.9727 C 36.3202 43.9727 36.7655 44.4414 36.7655 45.2617 L 36.7655 47.9805 C 36.7655 48.8008 36.3202 49.2227 35.5233 49.2227 Z'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.pf-c-form-control.pf-m-icon.pf-m-caps-lock {
|
||||
--pf-c-form-control--m-icon--BackgroundUrl: var(
|
||||
--pf-c-form-control--m-caps-lock--BackgroundUrl
|
||||
);
|
||||
}
|
||||
|
||||
/*#endregion*/
|
||||
|
||||
.pf-c-page__header {
|
||||
z-index: 0;
|
||||
background-color: var(--ak-dark-background-light);
|
||||
|
@ -3,6 +3,7 @@ import type { AbstractConstructor } from "@goauthentik/elements/types.js";
|
||||
|
||||
import { consume } from "@lit/context";
|
||||
import type { LitElement } from "lit";
|
||||
import { state } from "lit/decorators.js";
|
||||
|
||||
import type { CurrentBrand } from "@goauthentik/api";
|
||||
|
||||
@ -12,6 +13,7 @@ export function WithBrandConfig<T extends AbstractConstructor<LitElement>>(
|
||||
) {
|
||||
abstract class WithBrandProvider extends superclass {
|
||||
@consume({ context: authentikBrandContext, subscribe })
|
||||
@state()
|
||||
public brand!: CurrentBrand;
|
||||
}
|
||||
return WithBrandProvider;
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { AkControlElement } from "@goauthentik/elements/AkControlElement.js";
|
||||
import { debounce } from "@goauthentik/elements/utils/debounce";
|
||||
import { CustomListenerElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { PropertyValues, html } from "lit";
|
||||
@ -12,6 +11,11 @@ import type { Pagination } from "@goauthentik/api";
|
||||
|
||||
import "./ak-dual-select";
|
||||
import { AkDualSelect } from "./ak-dual-select";
|
||||
import {
|
||||
DualSelectChangeEvent,
|
||||
DualSelectPaginatorNavEvent,
|
||||
DualSelectSearchEvent,
|
||||
} from "./events";
|
||||
import type { DataProvider, DualSelectPair } from "./types";
|
||||
|
||||
/**
|
||||
@ -26,7 +30,7 @@ import type { DataProvider, DualSelectPair } from "./types";
|
||||
*/
|
||||
|
||||
@customElement("ak-dual-select-provider")
|
||||
export class AkDualSelectProvider extends CustomListenerElement(AkControlElement) {
|
||||
export class AkDualSelectProvider extends AkControlElement {
|
||||
/** A function that takes a page and returns the DualSelectPair[] collection with which to update
|
||||
* the "Available" pane.
|
||||
*
|
||||
@ -86,9 +90,9 @@ export class AkDualSelectProvider extends CustomListenerElement(AkControlElement
|
||||
this.onNav = this.onNav.bind(this);
|
||||
this.onChange = this.onChange.bind(this);
|
||||
this.onSearch = this.onSearch.bind(this);
|
||||
this.addCustomListener("ak-pagination-nav-to", this.onNav);
|
||||
this.addCustomListener("ak-dual-select-change", this.onChange);
|
||||
this.addCustomListener("ak-dual-select-search", this.onSearch);
|
||||
this.addEventListener(DualSelectPaginatorNavEvent.eventName, this.onNav);
|
||||
this.addEventListener(DualSelectSearchEvent.eventName, this.onSearch);
|
||||
this.addEventListener(DualSelectChangeEvent.eventName, this.onChange);
|
||||
}
|
||||
|
||||
willUpdate(changedProperties: PropertyValues<this>) {
|
||||
@ -122,26 +126,16 @@ export class AkDualSelectProvider extends CustomListenerElement(AkControlElement
|
||||
this.isLoading = false;
|
||||
}
|
||||
|
||||
onNav(event: Event) {
|
||||
if (!(event instanceof CustomEvent)) {
|
||||
throw new Error(`Expecting a CustomEvent for navigation, received ${event} instead`);
|
||||
}
|
||||
this.fetch(event.detail);
|
||||
onNav(event: DualSelectPaginatorNavEvent) {
|
||||
this.fetch(event.page);
|
||||
}
|
||||
|
||||
onChange(event: Event) {
|
||||
if (!(event instanceof CustomEvent)) {
|
||||
throw new Error(`Expecting a CustomEvent for change, received ${event} instead`);
|
||||
}
|
||||
this.internalSelected = event.detail.value;
|
||||
this.selected = this.internalSelected;
|
||||
onChange(event: DualSelectChangeEvent) {
|
||||
this.selected = this.internalSelected = event.selected;
|
||||
}
|
||||
|
||||
onSearch(event: Event) {
|
||||
if (!(event instanceof CustomEvent)) {
|
||||
throw new Error(`Expecting a CustomEvent for change, received ${event} instead`);
|
||||
}
|
||||
this.doSearch(event.detail);
|
||||
onSearch(event: DualSelectSearchEvent) {
|
||||
this.doSearch(event.search);
|
||||
}
|
||||
|
||||
doSearch(search: string) {
|
||||
|
@ -1,8 +1,5 @@
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import {
|
||||
CustomEmitterElement,
|
||||
CustomListenerElement,
|
||||
} from "@goauthentik/elements/utils/eventEmitter";
|
||||
import { match } from "ts-pattern";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { PropertyValues, html, nothing } from "lit";
|
||||
@ -23,15 +20,13 @@ import { AkDualSelectSelectedPane } from "./components/ak-dual-select-selected-p
|
||||
import "./components/ak-pagination";
|
||||
import "./components/ak-search-bar";
|
||||
import {
|
||||
EVENT_ADD_ALL,
|
||||
EVENT_ADD_ONE,
|
||||
EVENT_ADD_SELECTED,
|
||||
EVENT_DELETE_ALL,
|
||||
EVENT_REMOVE_ALL,
|
||||
EVENT_REMOVE_ONE,
|
||||
EVENT_REMOVE_SELECTED,
|
||||
} from "./constants";
|
||||
import type { BasePagination, DualSelectPair, SearchbarEvent } from "./types";
|
||||
DualSelectChangeEvent,
|
||||
DualSelectMoveRequestEvent,
|
||||
DualSelectPanelSearchEvent,
|
||||
DualSelectSearchEvent,
|
||||
DualSelectUpdateEvent,
|
||||
} from "./events";
|
||||
import type { BasePagination, DualSelectPair } from "./types";
|
||||
|
||||
function alphaSort([_k1, v1, s1]: DualSelectPair, [_k2, v2, s2]: DualSelectPair) {
|
||||
const [l, r] = [s1 !== undefined ? s1 : v1, s2 !== undefined ? s2 : v2];
|
||||
@ -60,7 +55,7 @@ const keyfinder =
|
||||
k === key;
|
||||
|
||||
@customElement("ak-dual-select")
|
||||
export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKElement)) {
|
||||
export class AkDualSelect extends AKElement {
|
||||
static get styles() {
|
||||
return styles;
|
||||
}
|
||||
@ -96,21 +91,9 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
||||
super();
|
||||
this.handleMove = this.handleMove.bind(this);
|
||||
this.handleSearch = this.handleSearch.bind(this);
|
||||
[
|
||||
EVENT_ADD_ALL,
|
||||
EVENT_ADD_SELECTED,
|
||||
EVENT_DELETE_ALL,
|
||||
EVENT_REMOVE_ALL,
|
||||
EVENT_REMOVE_SELECTED,
|
||||
EVENT_ADD_ONE,
|
||||
EVENT_REMOVE_ONE,
|
||||
].forEach((eventName: string) => {
|
||||
this.addCustomListener(eventName, (event: Event) => this.handleMove(eventName, event));
|
||||
});
|
||||
this.addCustomListener("ak-dual-select-move", () => {
|
||||
this.requestUpdate();
|
||||
});
|
||||
this.addCustomListener("ak-search", this.handleSearch);
|
||||
this.addEventListener(DualSelectMoveRequestEvent.eventName, this.handleMove);
|
||||
this.addEventListener(DualSelectUpdateEvent.eventName, () => this.requestUpdate());
|
||||
this.addEventListener(DualSelectPanelSearchEvent.eventName, this.handleSearch);
|
||||
}
|
||||
|
||||
willUpdate(changedProperties: PropertyValues<this>) {
|
||||
@ -123,47 +106,17 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
||||
}
|
||||
}
|
||||
|
||||
handleMove(eventName: string, event: Event) {
|
||||
if (!(event instanceof CustomEvent)) {
|
||||
throw new Error(`Expected move event here, got ${eventName}`);
|
||||
}
|
||||
|
||||
switch (eventName) {
|
||||
case EVENT_ADD_SELECTED: {
|
||||
this.addSelected();
|
||||
break;
|
||||
}
|
||||
case EVENT_REMOVE_SELECTED: {
|
||||
this.removeSelected();
|
||||
break;
|
||||
}
|
||||
case EVENT_ADD_ALL: {
|
||||
this.addAllVisible();
|
||||
break;
|
||||
}
|
||||
case EVENT_REMOVE_ALL: {
|
||||
this.removeAllVisible();
|
||||
break;
|
||||
}
|
||||
case EVENT_DELETE_ALL: {
|
||||
this.removeAll();
|
||||
break;
|
||||
}
|
||||
case EVENT_ADD_ONE: {
|
||||
this.addOne(event.detail);
|
||||
break;
|
||||
}
|
||||
case EVENT_REMOVE_ONE: {
|
||||
this.removeOne(event.detail);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new Error(
|
||||
`AkDualSelect.handleMove received unknown event type: ${eventName}`,
|
||||
);
|
||||
}
|
||||
this.dispatchCustomEvent("ak-dual-select-change", { value: this.value });
|
||||
handleMove(event: DualSelectMoveRequestEvent) {
|
||||
match(event.move)
|
||||
.with("add-all", () => this.addAllVisible())
|
||||
.with("add-one", () => this.addOne(event.key))
|
||||
.with("add-selected", () => this.addSelected())
|
||||
.with("delete-all", () => this.removeAll())
|
||||
.with("remove-all", () => this.removeAllVisible())
|
||||
.with("remove-one", () => this.removeOne(event.key))
|
||||
.with("remove-selected", () => this.removeSelected())
|
||||
.exhaustive();
|
||||
this.dispatchEvent(new DualSelectChangeEvent(this.value));
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
@ -182,7 +135,10 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
||||
this.availablePane.value!.clearMove();
|
||||
}
|
||||
|
||||
addOne(key: string) {
|
||||
addOne(key?: string) {
|
||||
if (!key) {
|
||||
return;
|
||||
}
|
||||
const requested = this.options.find(keyfinder(key));
|
||||
if (requested && !this.selected.find(keyfinder(requested[0]))) {
|
||||
this.selected = [...this.selected, requested];
|
||||
@ -207,7 +163,10 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
||||
this.selectedPane.value!.clearMove();
|
||||
}
|
||||
|
||||
removeOne(key: string) {
|
||||
removeOne(key?: string) {
|
||||
if (!key) {
|
||||
return;
|
||||
}
|
||||
this.selected = this.selected.filter(([k]) => k !== key);
|
||||
}
|
||||
|
||||
@ -223,18 +182,18 @@ export class AkDualSelect extends CustomEmitterElement(CustomListenerElement(AKE
|
||||
this.selectedPane.value!.clearMove();
|
||||
}
|
||||
|
||||
handleSearch(event: SearchbarEvent) {
|
||||
switch (event.detail.source) {
|
||||
handleSearch(event: DualSelectPanelSearchEvent) {
|
||||
switch (event.source) {
|
||||
case "ak-dual-list-available-search":
|
||||
return this.handleAvailableSearch(event.detail.value);
|
||||
return this.handleAvailableSearch(event.filterOn);
|
||||
case "ak-dual-list-selected-search":
|
||||
return this.handleSelectedSearch(event.detail.value);
|
||||
return this.handleSelectedSearch(event.filterOn);
|
||||
}
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
handleAvailableSearch(value: string) {
|
||||
this.dispatchCustomEvent("ak-dual-select-search", value);
|
||||
this.dispatchEvent(new DualSelectSearchEvent(value));
|
||||
}
|
||||
|
||||
handleSelectedSearch(value: string) {
|
||||
|
@ -1,26 +1,19 @@
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
import { bound } from "@goauthentik/elements/decorators/bound";
|
||||
|
||||
import { html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators.js";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { classMap } from "lit/directives/class-map.js";
|
||||
import { map } from "lit/directives/map.js";
|
||||
|
||||
import { availablePaneStyles, listStyles } from "./styles.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFDualListSelector from "@patternfly/patternfly/components/DualListSelector/dual-list-selector.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import { availablePaneStyles } from "./styles.css";
|
||||
|
||||
import { EVENT_ADD_ONE } from "../constants";
|
||||
import {
|
||||
DualSelectMoveAvailableEvent,
|
||||
DualSelectMoveRequestEvent,
|
||||
DualSelectUpdateEvent,
|
||||
} from "../events";
|
||||
import type { DualSelectPair } from "../types";
|
||||
|
||||
const styles = [PFBase, PFButton, PFDualListSelector, listStyles, availablePaneStyles];
|
||||
|
||||
const hostAttributes = [
|
||||
["aria-labelledby", "dual-list-selector-available-pane-status"],
|
||||
["aria-multiselectable", "true"],
|
||||
["role", "listbox"],
|
||||
];
|
||||
import { AkDualSelectAbstractPane } from "./ak-dual-select-pane";
|
||||
|
||||
/**
|
||||
* @element ak-dual-select-available-panel
|
||||
@ -40,9 +33,9 @@ const hostAttributes = [
|
||||
*
|
||||
*/
|
||||
@customElement("ak-dual-select-available-pane")
|
||||
export class AkDualSelectAvailablePane extends CustomEmitterElement(AKElement) {
|
||||
export class AkDualSelectAvailablePane extends AkDualSelectAbstractPane {
|
||||
static get styles() {
|
||||
return styles;
|
||||
return [...AkDualSelectAbstractPane.styles, availablePaneStyles];
|
||||
}
|
||||
|
||||
/* The array of key/value pairs this pane is currently showing */
|
||||
@ -56,68 +49,31 @@ export class AkDualSelectAvailablePane extends CustomEmitterElement(AKElement) {
|
||||
@property({ type: Object })
|
||||
readonly selected: Set<string> = new Set();
|
||||
|
||||
/* This is the only mutator for this object. It collects the list of objects the user has
|
||||
* clicked on *in this pane*. It is explicitly marked as "public" to emphasize that the parent
|
||||
* orchestrator for the dual-select widget can and will access it to get the list of keys to be
|
||||
* moved (removed) if the user so requests.
|
||||
*
|
||||
*/
|
||||
@state()
|
||||
public toMove: Set<string> = new Set();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.onClick = this.onClick.bind(this);
|
||||
this.onMove = this.onMove.bind(this);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
hostAttributes.forEach(([attr, value]) => {
|
||||
if (!this.hasAttribute(attr)) {
|
||||
this.setAttribute(attr, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
clearMove() {
|
||||
this.toMove = new Set();
|
||||
}
|
||||
|
||||
@bound
|
||||
onClick(key: string) {
|
||||
if (this.selected.has(key)) {
|
||||
return;
|
||||
}
|
||||
if (this.toMove.has(key)) {
|
||||
this.toMove.delete(key);
|
||||
} else {
|
||||
this.toMove.add(key);
|
||||
}
|
||||
this.dispatchCustomEvent(
|
||||
"ak-dual-select-available-move-changed",
|
||||
Array.from(this.toMove.values()).sort(),
|
||||
);
|
||||
this.dispatchCustomEvent("ak-dual-select-move");
|
||||
this.move(key);
|
||||
this.dispatchEvent(new DualSelectMoveAvailableEvent(this.moveable.sort()));
|
||||
this.dispatchEvent(new DualSelectUpdateEvent());
|
||||
// Necessary because updating a map won't trigger a state change
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
@bound
|
||||
onMove(key: string) {
|
||||
this.toMove.delete(key);
|
||||
this.dispatchCustomEvent(EVENT_ADD_ONE, key);
|
||||
this.dispatchEvent(new DualSelectMoveRequestEvent("add-one", key));
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
get moveable() {
|
||||
return Array.from(this.toMove.values());
|
||||
}
|
||||
|
||||
// DO NOT use `Array.map()` instead of Lit's `map()` function. Lit's `map()` is object-aware and
|
||||
// will not re-arrange or reconstruct the list automatically if the actual sources do not
|
||||
// change; this allows the available pane to illustrate selected items with the checkmark
|
||||
// without causing the list to scroll back up to the top.
|
||||
|
||||
render() {
|
||||
override render() {
|
||||
return html`
|
||||
<div class="pf-c-dual-list-selector__menu">
|
||||
<ul class="pf-c-dual-list-selector__list">
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { css, html, nothing } from "lit";
|
||||
@ -8,13 +7,7 @@ import { customElement, property } from "lit/decorators.js";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import {
|
||||
EVENT_ADD_ALL,
|
||||
EVENT_ADD_SELECTED,
|
||||
EVENT_DELETE_ALL,
|
||||
EVENT_REMOVE_ALL,
|
||||
EVENT_REMOVE_SELECTED,
|
||||
} from "../constants";
|
||||
import { DualSelectMoveRequestEvent, type MoveEventType } from "../events";
|
||||
|
||||
const styles = [
|
||||
PFBase,
|
||||
@ -47,7 +40,7 @@ const styles = [
|
||||
*/
|
||||
|
||||
@customElement("ak-dual-select-controls")
|
||||
export class AkDualSelectControls extends CustomEmitterElement(AKElement) {
|
||||
export class AkDualSelectControls extends AKElement {
|
||||
static get styles() {
|
||||
return styles;
|
||||
}
|
||||
@ -96,11 +89,11 @@ export class AkDualSelectControls extends CustomEmitterElement(AKElement) {
|
||||
this.onClick = this.onClick.bind(this);
|
||||
}
|
||||
|
||||
onClick(eventName: string) {
|
||||
this.dispatchCustomEvent(eventName);
|
||||
onClick(eventName: MoveEventType) {
|
||||
this.dispatchEvent(new DualSelectMoveRequestEvent(eventName));
|
||||
}
|
||||
|
||||
renderButton(label: string, event: string, active: boolean, direction: string) {
|
||||
renderButton(label: string, event: MoveEventType, active: boolean, direction: string) {
|
||||
return html`
|
||||
<div class="pf-c-dual-list-selector__controls-item">
|
||||
<button
|
||||
@ -121,23 +114,18 @@ export class AkDualSelectControls extends CustomEmitterElement(AKElement) {
|
||||
render() {
|
||||
return html`
|
||||
<div class="ak-dual-list-selector__controls">
|
||||
${this.renderButton(
|
||||
msg("Add"),
|
||||
EVENT_ADD_SELECTED,
|
||||
this.addActive,
|
||||
"fa-angle-right",
|
||||
)}
|
||||
${this.renderButton(msg("Add"), "add-selected", this.addActive, "fa-angle-right")}
|
||||
${this.selectAll
|
||||
? html`
|
||||
${this.renderButton(
|
||||
msg("Add All Available"),
|
||||
EVENT_ADD_ALL,
|
||||
"add-all",
|
||||
this.addAllActive,
|
||||
"fa-angle-double-right",
|
||||
)}
|
||||
${this.renderButton(
|
||||
msg("Remove All Available"),
|
||||
EVENT_REMOVE_ALL,
|
||||
"remove-all",
|
||||
this.removeAllActive,
|
||||
"fa-angle-double-left",
|
||||
)}
|
||||
@ -145,14 +133,14 @@ export class AkDualSelectControls extends CustomEmitterElement(AKElement) {
|
||||
: nothing}
|
||||
${this.renderButton(
|
||||
msg("Remove"),
|
||||
EVENT_REMOVE_SELECTED,
|
||||
"remove-selected",
|
||||
this.removeActive,
|
||||
"fa-angle-left",
|
||||
)}
|
||||
${this.deleteAll
|
||||
? html`${this.renderButton(
|
||||
msg("Remove All"),
|
||||
EVENT_DELETE_ALL,
|
||||
"delete-all",
|
||||
this.enableDeleteAll,
|
||||
"fa-times",
|
||||
)}`
|
||||
|
@ -0,0 +1,75 @@
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { TemplateResult } from "lit";
|
||||
import { state } from "lit/decorators.js";
|
||||
|
||||
import { listStyles } from "./styles.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFDualListSelector from "@patternfly/patternfly/components/DualListSelector/dual-list-selector.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
const styles = [PFBase, PFButton, PFDualListSelector, listStyles];
|
||||
|
||||
const hostAttributes = [
|
||||
["aria-labelledby", "dual-list-selector-selected-pane-status"],
|
||||
["aria-multiselectable", "true"],
|
||||
["role", "listbox"],
|
||||
];
|
||||
|
||||
/**
|
||||
* @element ak-dual-select-panel
|
||||
*
|
||||
* The "selected options" or "right" pane in a dual-list multi-select. It receives from its parent
|
||||
* a list of the selected options, and maintains an internal list of objects selected to move.
|
||||
*
|
||||
* @fires ak-dual-select-selected-move-changed - When the list of "to move" entries changed.
|
||||
* Includes the current `toMove` content.
|
||||
*
|
||||
* @fires ak-dual-select-remove-one - Double-click with the element clicked on.
|
||||
*
|
||||
* It is not expected that the `ak-dual-select-selected-move-changed` will be used; instead, the
|
||||
* attribute will be read by the parent when a control is clicked.
|
||||
*
|
||||
*/
|
||||
export abstract class AkDualSelectAbstractPane extends AKElement {
|
||||
static get styles() {
|
||||
return styles;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the only mutator for this object. It collects the list of objects the user has
|
||||
* clicked on *in this pane*. It is explicitly marked as "public" to emphasize that the parent
|
||||
* orchestrator for the dual-select widget can and will access it to get the list of keys to be
|
||||
* moved (removed) if the user so requests.
|
||||
*
|
||||
*/
|
||||
@state()
|
||||
public toMove: Set<string> = new Set();
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
hostAttributes.forEach(([attr, value]) => {
|
||||
if (!this.hasAttribute(attr)) {
|
||||
this.setAttribute(attr, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
clearMove() {
|
||||
this.toMove = new Set();
|
||||
}
|
||||
|
||||
move(key: string) {
|
||||
if (this.toMove.has(key)) {
|
||||
this.toMove.delete(key);
|
||||
} else {
|
||||
this.toMove.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
get moveable() {
|
||||
return Array.from(this.toMove.values());
|
||||
}
|
||||
|
||||
abstract render(): TemplateResult;
|
||||
}
|
@ -1,26 +1,19 @@
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
import { bound } from "@goauthentik/elements/decorators/bound";
|
||||
|
||||
import { html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators.js";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { classMap } from "lit/directives/class-map.js";
|
||||
import { map } from "lit/directives/map.js";
|
||||
|
||||
import { listStyles, selectedPaneStyles } from "./styles.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFDualListSelector from "@patternfly/patternfly/components/DualListSelector/dual-list-selector.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
import { selectedPaneStyles } from "./styles.css";
|
||||
|
||||
import { EVENT_REMOVE_ONE } from "../constants";
|
||||
import {
|
||||
DualSelectMoveRequestEvent,
|
||||
DualSelectMoveSelectedEvent,
|
||||
DualSelectUpdateEvent,
|
||||
} from "../events";
|
||||
import type { DualSelectPair } from "../types";
|
||||
|
||||
const styles = [PFBase, PFButton, PFDualListSelector, listStyles, selectedPaneStyles];
|
||||
|
||||
const hostAttributes = [
|
||||
["aria-labelledby", "dual-list-selector-selected-pane-status"],
|
||||
["aria-multiselectable", "true"],
|
||||
["role", "listbox"],
|
||||
];
|
||||
import { AkDualSelectAbstractPane } from "./ak-dual-select-pane";
|
||||
|
||||
/**
|
||||
* @element ak-dual-select-available-panel
|
||||
@ -38,70 +31,32 @@ const hostAttributes = [
|
||||
*
|
||||
*/
|
||||
@customElement("ak-dual-select-selected-pane")
|
||||
export class AkDualSelectSelectedPane extends CustomEmitterElement(AKElement) {
|
||||
export class AkDualSelectSelectedPane extends AkDualSelectAbstractPane {
|
||||
static get styles() {
|
||||
return styles;
|
||||
return [...AkDualSelectAbstractPane.styles, selectedPaneStyles];
|
||||
}
|
||||
|
||||
/* The array of key/value pairs that are in the selected list. ALL of them. */
|
||||
@property({ type: Array })
|
||||
readonly selected: DualSelectPair[] = [];
|
||||
|
||||
/*
|
||||
* This is the only mutator for this object. It collects the list of objects the user has
|
||||
* clicked on *in this pane*. It is explicitly marked as "public" to emphasize that the parent
|
||||
* orchestrator for the dual-select widget can and will access it to get the list of keys to be
|
||||
* moved (removed) if the user so requests.
|
||||
*
|
||||
*/
|
||||
@state()
|
||||
public toMove: Set<string> = new Set();
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.onClick = this.onClick.bind(this);
|
||||
this.onMove = this.onMove.bind(this);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
hostAttributes.forEach(([attr, value]) => {
|
||||
if (!this.hasAttribute(attr)) {
|
||||
this.setAttribute(attr, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
clearMove() {
|
||||
this.toMove = new Set();
|
||||
}
|
||||
|
||||
@bound
|
||||
onClick(key: string) {
|
||||
if (this.toMove.has(key)) {
|
||||
this.toMove.delete(key);
|
||||
} else {
|
||||
this.toMove.add(key);
|
||||
}
|
||||
this.dispatchCustomEvent(
|
||||
"ak-dual-select-selected-move-changed",
|
||||
Array.from(this.toMove.values()).sort(),
|
||||
);
|
||||
this.dispatchCustomEvent("ak-dual-select-move");
|
||||
this.move(key);
|
||||
this.dispatchEvent(new DualSelectMoveSelectedEvent(this.moveable.sort()));
|
||||
this.dispatchEvent(new DualSelectUpdateEvent());
|
||||
// Necessary because updating a map won't trigger a state change
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
@bound
|
||||
onMove(key: string) {
|
||||
this.toMove.delete(key);
|
||||
this.dispatchCustomEvent(EVENT_REMOVE_ONE, key);
|
||||
this.dispatchEvent(new DualSelectMoveRequestEvent("remove-one", key));
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
get moveable() {
|
||||
return Array.from(this.toMove.values());
|
||||
}
|
||||
|
||||
render() {
|
||||
override render() {
|
||||
return html`
|
||||
<div class="pf-c-dual-list-selector__menu">
|
||||
<ul class="pf-c-dual-list-selector__list">
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { css, html, nothing } from "lit";
|
||||
@ -9,6 +8,7 @@ import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFPagination from "@patternfly/patternfly/components/Pagination/pagination.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import { DualSelectPaginatorNavEvent } from "../events";
|
||||
import type { BasePagination } from "../types";
|
||||
|
||||
const styles = [
|
||||
@ -27,7 +27,7 @@ const styles = [
|
||||
];
|
||||
|
||||
@customElement("ak-pagination")
|
||||
export class AkPagination extends CustomEmitterElement(AKElement) {
|
||||
export class AkPagination extends AKElement {
|
||||
static get styles() {
|
||||
return styles;
|
||||
}
|
||||
@ -41,7 +41,7 @@ export class AkPagination extends CustomEmitterElement(AKElement) {
|
||||
}
|
||||
|
||||
onClick(nav: number | undefined) {
|
||||
this.dispatchCustomEvent("ak-pagination-nav-to", nav ?? 0);
|
||||
this.dispatchEvent(new DualSelectPaginatorNavEvent(nav ?? 0));
|
||||
}
|
||||
|
||||
render() {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
|
||||
import { html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
@ -9,12 +8,12 @@ import type { Ref } from "lit/directives/ref.js";
|
||||
import { globalVariables, searchStyles } from "./search.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import type { SearchbarEvent } from "../types";
|
||||
import { DualSelectPanelSearchEvent } from "../events";
|
||||
|
||||
const styles = [PFBase, globalVariables, searchStyles];
|
||||
|
||||
@customElement("ak-search-bar")
|
||||
export class AkSearchbar extends CustomEmitterElement(AKElement) {
|
||||
export class AkSearchbar extends AKElement {
|
||||
static get styles() {
|
||||
return styles;
|
||||
}
|
||||
@ -40,10 +39,7 @@ export class AkSearchbar extends CustomEmitterElement(AKElement) {
|
||||
if (this.input.value) {
|
||||
this.value = this.input.value.value;
|
||||
}
|
||||
this.dispatchCustomEvent<SearchbarEvent>("ak-search", {
|
||||
source: this.name,
|
||||
value: this.value,
|
||||
});
|
||||
this.dispatchEvent(new DualSelectPanelSearchEvent(this.name, this.value));
|
||||
}
|
||||
|
||||
render() {
|
||||
|
112
web/src/elements/ak-dual-select/events.ts
Normal file
112
web/src/elements/ak-dual-select/events.ts
Normal file
@ -0,0 +1,112 @@
|
||||
import { DualSelectPair } from "./types";
|
||||
|
||||
// Handled by the Server layer provider
|
||||
|
||||
// Request to provide a different page of the paginated results in the "available" panel.
|
||||
export class DualSelectPaginatorNavEvent extends Event {
|
||||
static readonly eventName = "ak-dual-select-paginator-nav";
|
||||
constructor(public page: number = 0) {
|
||||
super(DualSelectPaginatorNavEvent.eventName, { bubbles: true, composed: true });
|
||||
}
|
||||
}
|
||||
|
||||
// Request to provide a filtered collection for the "available" panel via a search string
|
||||
export class DualSelectSearchEvent extends Event {
|
||||
static readonly eventName = "ak-dual-select-search";
|
||||
constructor(public search: string) {
|
||||
super(DualSelectSearchEvent.eventName, { bubbles: true, composed: true });
|
||||
}
|
||||
}
|
||||
|
||||
// Request to update the "selected" list in the provider
|
||||
export class DualSelectChangeEvent extends Event {
|
||||
static readonly eventName = "ak-dual-select-change";
|
||||
constructor(public selected: DualSelectPair[]) {
|
||||
super(DualSelectChangeEvent.eventName, { bubbles: true, composed: true });
|
||||
}
|
||||
}
|
||||
|
||||
// Paginator and specific item events
|
||||
|
||||
export const moveEvents = [
|
||||
"add-all",
|
||||
"add-one",
|
||||
"add-selected",
|
||||
"delete-all",
|
||||
"remove-all",
|
||||
"remove-one",
|
||||
"remove-selected",
|
||||
] as const;
|
||||
|
||||
export type MoveEventType = (typeof moveEvents)[number];
|
||||
|
||||
// Request to add or remove all, some, or just one item from the "selected" panel
|
||||
export class DualSelectMoveRequestEvent extends Event {
|
||||
static readonly eventName = "ak-dual-select-request-move";
|
||||
constructor(
|
||||
public move: MoveEventType,
|
||||
public key?: string,
|
||||
) {
|
||||
super(DualSelectMoveRequestEvent.eventName, { bubbles: true, composed: true });
|
||||
}
|
||||
}
|
||||
|
||||
// Update events
|
||||
|
||||
// Request to update the viewset
|
||||
export class DualSelectUpdateEvent extends Event {
|
||||
static readonly eventName = "ak-dual-select-update";
|
||||
constructor() {
|
||||
super(DualSelectUpdateEvent.eventName, { bubbles: true, composed: true });
|
||||
}
|
||||
}
|
||||
|
||||
interface DualSelectMoveChangedEvent {
|
||||
keys: string[];
|
||||
}
|
||||
|
||||
// Request to update the list of "marked for move" items in the "available" panel
|
||||
export class DualSelectMoveAvailableEvent extends Event implements DualSelectMoveChangedEvent {
|
||||
static readonly eventName = "ak-dual-select-move-available";
|
||||
constructor(public keys: string[]) {
|
||||
super(DualSelectMoveAvailableEvent.eventName, { bubbles: true, composed: true });
|
||||
}
|
||||
}
|
||||
|
||||
// Request to update the list of "marked for move" items in the "selected" panel
|
||||
export class DualSelectMoveSelectedEvent extends Event implements DualSelectMoveChangedEvent {
|
||||
static readonly eventName = "ak-dual-select-move-selected";
|
||||
constructor(public keys: string[]) {
|
||||
super(DualSelectMoveSelectedEvent.eventName, { bubbles: true, composed: true });
|
||||
}
|
||||
}
|
||||
|
||||
// Request to update either panel with a Filter
|
||||
export class DualSelectPanelSearchEvent extends Event {
|
||||
static readonly eventName = "ak-dual-select-panel-search";
|
||||
constructor(
|
||||
public source: string,
|
||||
public filterOn: string,
|
||||
) {
|
||||
super(DualSelectPanelSearchEvent.eventName, { bubbles: true, composed: true });
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementEventMap {
|
||||
[DualSelectUpdateEvent.eventName]: DualSelectUpdateEvent;
|
||||
[DualSelectMoveAvailableEvent.eventName]: DualSelectMoveAvailableEvent;
|
||||
[DualSelectMoveSelectedEvent.eventName]: DualSelectMoveSelectedEvent;
|
||||
[DualSelectMoveRequestEvent.eventName]: DualSelectMoveRequestEvent;
|
||||
[DualSelectPaginatorNavEvent.eventName]: DualSelectPaginatorNavEvent;
|
||||
[DualSelectSearchEvent.eventName]: DualSelectSearchEvent;
|
||||
[DualSelectChangeEvent.eventName]: DualSelectChangeEvent;
|
||||
[DualSelectPanelSearchEvent.eventName]: DualSelectPanelSearchEvent;
|
||||
}
|
||||
|
||||
interface WindowEventMap {
|
||||
[DualSelectMoveRequestEvent.eventName]: DualSelectMoveRequestEvent;
|
||||
[DualSelectPaginatorNavEvent.eventName]: DualSelectPaginatorNavEvent;
|
||||
[DualSelectMoveSelectedEvent.eventName]: DualSelectMoveSelectedEvent;
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import { TemplateResult, html } from "lit";
|
||||
|
||||
import "../components/ak-dual-select-available-pane";
|
||||
import { AkDualSelectAvailablePane } from "../components/ak-dual-select-available-pane";
|
||||
import { DualSelectMoveSelectedEvent } from "../events";
|
||||
import "./sb-host-provider";
|
||||
|
||||
const metadata: Meta<AkDualSelectAvailablePane> = {
|
||||
@ -53,15 +54,15 @@ const container = (testItem: TemplateResult) =>
|
||||
</div>`;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const handleMoveChanged = (result: any) => {
|
||||
const handleMoveChanged = (result: DualSelectMoveSelectedEvent) => {
|
||||
const target = document.querySelector("#action-button-message-pad");
|
||||
target!.innerHTML = "";
|
||||
result.detail.forEach((key: string) => {
|
||||
result.keys.forEach((key: string) => {
|
||||
target!.append(new DOMParser().parseFromString(`<li>${key}</li>`, "text/xml").firstChild!);
|
||||
});
|
||||
};
|
||||
|
||||
window.addEventListener("ak-dual-select-available-move-changed", handleMoveChanged);
|
||||
window.addEventListener(DualSelectMoveSelectedEvent.eventName, handleMoveChanged);
|
||||
|
||||
type Story = StoryObj;
|
||||
|
||||
|
@ -5,6 +5,7 @@ import { TemplateResult, html } from "lit";
|
||||
|
||||
import "../components/ak-dual-select-controls";
|
||||
import { AkDualSelectControls } from "../components/ak-dual-select-controls";
|
||||
import { DualSelectMoveRequestEvent } from "../events";
|
||||
|
||||
const metadata: Meta<AkDualSelectControls> = {
|
||||
title: "Elements / Dual Select / Control Panel",
|
||||
@ -59,10 +60,9 @@ const displayMessage = (result: any) => {
|
||||
target!.appendChild(doc.firstChild!);
|
||||
};
|
||||
|
||||
window.addEventListener("ak-dual-select-add", () => displayMessage("add"));
|
||||
window.addEventListener("ak-dual-select-remove", () => displayMessage("remove"));
|
||||
window.addEventListener("ak-dual-select-add-all", () => displayMessage("add all"));
|
||||
window.addEventListener("ak-dual-select-remove-all", () => displayMessage("remove all"));
|
||||
window.addEventListener(DualSelectMoveRequestEvent.eventName, (ev: DualSelectMoveRequestEvent) =>
|
||||
displayMessage(ev.move.toString()),
|
||||
);
|
||||
|
||||
type Story = StoryObj;
|
||||
|
||||
|
@ -9,6 +9,7 @@ import { Pagination } from "@goauthentik/api";
|
||||
|
||||
import "../ak-dual-select";
|
||||
import { AkDualSelect } from "../ak-dual-select";
|
||||
import { DualSelectPaginatorNavEvent } from "../events";
|
||||
import type { DualSelectPair } from "../types";
|
||||
|
||||
const goodForYouRaw = `
|
||||
@ -83,11 +84,11 @@ export class AkSbFruity extends LitElement {
|
||||
totalPages: Math.ceil(this.options.length / this.pageLength),
|
||||
};
|
||||
this.onNavigation = this.onNavigation.bind(this);
|
||||
this.addEventListener("ak-pagination-nav-to", this.onNavigation);
|
||||
this.addEventListener(DualSelectPaginatorNavEvent.eventName, this.onNavigation);
|
||||
}
|
||||
|
||||
onNavigation(evt: Event) {
|
||||
const current: number = (evt as CustomEvent).detail;
|
||||
onNavigation(evt: DualSelectPaginatorNavEvent) {
|
||||
const current = evt.page;
|
||||
const index = current - 1;
|
||||
if (index * this.pageLength > this.options.length) {
|
||||
console.warn(
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user