Compare commits
11 Commits
web/reques
...
restricted
Author | SHA1 | Date | |
---|---|---|---|
efdecf949d | |||
9ea5f56715 | |||
8228b56b75 | |||
518e10dbdb | |||
79ddad28a8 | |||
beeec85c15 | |||
0561b8d578 | |||
201481bde3 | |||
7d04903d5b | |||
db7d880116 | |||
259cc81723 |
4
.github/workflows/release-publish.yml
vendored
4
.github/workflows/release-publish.yml
vendored
@ -155,8 +155,8 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Run test suite in final docker images
|
||||
run: |
|
||||
echo "PG_PASS=$(openssl rand 32 | base64)" >> .env
|
||||
echo "AUTHENTIK_SECRET_KEY=$(openssl rand 32 | base64)" >> .env
|
||||
echo "PG_PASS=$(openssl rand -base64 32)" >> .env
|
||||
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 32)" >> .env
|
||||
docker compose pull -q
|
||||
docker compose up --no-start
|
||||
docker compose start postgresql redis
|
||||
|
4
.github/workflows/release-tag.yml
vendored
4
.github/workflows/release-tag.yml
vendored
@ -14,8 +14,8 @@ jobs:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Pre-release test
|
||||
run: |
|
||||
echo "PG_PASS=$(openssl rand 32 | base64)" >> .env
|
||||
echo "AUTHENTIK_SECRET_KEY=$(openssl rand 32 | base64)" >> .env
|
||||
echo "PG_PASS=$(openssl rand -base64 32)" >> .env
|
||||
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 32)" >> .env
|
||||
docker buildx install
|
||||
mkdir -p ./gen-ts-api
|
||||
docker build -t testing:latest .
|
||||
|
@ -1,7 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Stage 1: Build website
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/node:22 as website-builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/node:21 as website-builder
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
@ -20,7 +20,7 @@ COPY ./SECURITY.md /work/
|
||||
RUN npm run build-bundled
|
||||
|
||||
# Stage 2: Build webui
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/node:22 as web-builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/node:21 as web-builder
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
|
4
Makefile
4
Makefile
@ -46,8 +46,8 @@ test-go:
|
||||
go test -timeout 0 -v -race -cover ./...
|
||||
|
||||
test-docker: ## Run all tests in a docker-compose
|
||||
echo "PG_PASS=$(shell openssl rand 32 | base64)" >> .env
|
||||
echo "AUTHENTIK_SECRET_KEY=$(shell openssl rand 32 | base64)" >> .env
|
||||
echo "PG_PASS=$(openssl rand -base64 32)" >> .env
|
||||
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 32)" >> .env
|
||||
docker compose pull -q
|
||||
docker compose up --no-start
|
||||
docker compose start postgresql redis
|
||||
|
@ -73,6 +73,11 @@ def auth_user_lookup(raw_header: bytes) -> User | None:
|
||||
if user:
|
||||
CTX_AUTH_VIA.set("secret_key")
|
||||
return user
|
||||
# then try to auth via expression JWT
|
||||
user = token_expression_jwt(auth_credentials)
|
||||
if user:
|
||||
CTX_AUTH_VIA.set("expression_jwt")
|
||||
return user
|
||||
raise AuthenticationFailed("Token invalid/expired")
|
||||
|
||||
|
||||
@ -90,6 +95,13 @@ def token_secret_key(value: str) -> User | None:
|
||||
return outpost.user
|
||||
|
||||
|
||||
def token_expression_jwt(value: str) -> User | None:
|
||||
"""Authenticate API call made by Expressions"""
|
||||
from authentik.lib.expression.evaluator import authenticate_token
|
||||
|
||||
return authenticate_token(value)
|
||||
|
||||
|
||||
class TokenAuthentication(BaseAuthentication):
|
||||
"""Token-based authentication using HTTP Bearer authentication"""
|
||||
|
||||
|
@ -36,7 +36,7 @@ class PropertyMappingEvaluator(BaseEvaluator):
|
||||
_filename = model.name
|
||||
else:
|
||||
_filename = str(model)
|
||||
super().__init__(filename=_filename)
|
||||
super().__init__(None, filename=_filename)
|
||||
req = PolicyRequest(user=User())
|
||||
req.obj = model
|
||||
if user:
|
||||
|
@ -4,7 +4,7 @@ from django.utils.text import slugify
|
||||
|
||||
from authentik.brands.models import Brand
|
||||
from authentik.core.models import Group, User
|
||||
from authentik.crypto.builder import CertificateBuilder, PrivateKeyAlg
|
||||
from authentik.crypto.builder import CertificateBuilder
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.flows.models import Flow, FlowDesignation
|
||||
from authentik.lib.generators import generate_id
|
||||
@ -50,10 +50,12 @@ def create_test_brand(**kwargs) -> Brand:
|
||||
return Brand.objects.create(domain=uid, default=True, **kwargs)
|
||||
|
||||
|
||||
def create_test_cert(alg=PrivateKeyAlg.RSA) -> CertificateKeyPair:
|
||||
def create_test_cert(use_ec_private_key=False) -> CertificateKeyPair:
|
||||
"""Generate a certificate for testing"""
|
||||
builder = CertificateBuilder(f"{generate_id()}.self-signed.goauthentik.io")
|
||||
builder.alg = alg
|
||||
builder = CertificateBuilder(
|
||||
name=f"{generate_id()}.self-signed.goauthentik.io",
|
||||
use_ec_private_key=use_ec_private_key,
|
||||
)
|
||||
builder.build(
|
||||
subject_alt_names=[f"{generate_id()}.self-signed.goauthentik.io"],
|
||||
validity_days=360,
|
||||
|
@ -14,13 +14,7 @@ from drf_spectacular.types import OpenApiTypes
|
||||
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.fields import (
|
||||
CharField,
|
||||
ChoiceField,
|
||||
DateTimeField,
|
||||
IntegerField,
|
||||
SerializerMethodField,
|
||||
)
|
||||
from rest_framework.fields import CharField, DateTimeField, IntegerField, SerializerMethodField
|
||||
from rest_framework.filters import OrderingFilter, SearchFilter
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.response import Response
|
||||
@ -32,7 +26,7 @@ from authentik.api.authorization import SecretKeyFilter
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.core.api.utils import PassiveSerializer
|
||||
from authentik.crypto.apps import MANAGED_KEY
|
||||
from authentik.crypto.builder import CertificateBuilder, PrivateKeyAlg
|
||||
from authentik.crypto.builder import CertificateBuilder
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.events.models import Event, EventAction
|
||||
from authentik.rbac.decorators import permission_required
|
||||
@ -184,7 +178,6 @@ class CertificateGenerationSerializer(PassiveSerializer):
|
||||
common_name = CharField()
|
||||
subject_alt_name = CharField(required=False, allow_blank=True, label=_("Subject-alt name"))
|
||||
validity_days = IntegerField(initial=365)
|
||||
alg = ChoiceField(default=PrivateKeyAlg.RSA, choices=PrivateKeyAlg.choices)
|
||||
|
||||
|
||||
class CertificateKeyPairFilter(FilterSet):
|
||||
@ -247,7 +240,6 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
|
||||
raw_san = data.validated_data.get("subject_alt_name", "")
|
||||
sans = raw_san.split(",") if raw_san != "" else []
|
||||
builder = CertificateBuilder(data.validated_data["common_name"])
|
||||
builder.alg = data.validated_data["alg"]
|
||||
builder.build(
|
||||
subject_alt_names=sans,
|
||||
validity_days=int(data.validated_data["validity_days"]),
|
||||
|
@ -9,28 +9,20 @@ from cryptography.hazmat.primitives import hashes, serialization
|
||||
from cryptography.hazmat.primitives.asymmetric import ec, rsa
|
||||
from cryptography.hazmat.primitives.asymmetric.types import PrivateKeyTypes
|
||||
from cryptography.x509.oid import NameOID
|
||||
from django.db import models
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from authentik import __version__
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
|
||||
|
||||
class PrivateKeyAlg(models.TextChoices):
|
||||
"""Algorithm to create private key with"""
|
||||
|
||||
RSA = "rsa", _("rsa")
|
||||
ECDSA = "ecdsa", _("ecdsa")
|
||||
|
||||
|
||||
class CertificateBuilder:
|
||||
"""Build self-signed certificates"""
|
||||
|
||||
common_name: str
|
||||
alg: PrivateKeyAlg
|
||||
|
||||
def __init__(self, name: str):
|
||||
self.alg = PrivateKeyAlg.RSA
|
||||
_use_ec_private_key: bool
|
||||
|
||||
def __init__(self, name: str, use_ec_private_key=False):
|
||||
self._use_ec_private_key = use_ec_private_key
|
||||
self.__public_key = None
|
||||
self.__private_key = None
|
||||
self.__builder = None
|
||||
@ -50,13 +42,11 @@ class CertificateBuilder:
|
||||
|
||||
def generate_private_key(self) -> PrivateKeyTypes:
|
||||
"""Generate private key"""
|
||||
if self.alg == PrivateKeyAlg.ECDSA:
|
||||
if self._use_ec_private_key:
|
||||
return ec.generate_private_key(curve=ec.SECP256R1())
|
||||
if self.alg == PrivateKeyAlg.RSA:
|
||||
return rsa.generate_private_key(
|
||||
public_exponent=65537, key_size=4096, backend=default_backend()
|
||||
)
|
||||
raise ValueError(f"Invalid alg: {self.alg}")
|
||||
return rsa.generate_private_key(
|
||||
public_exponent=65537, key_size=4096, backend=default_backend()
|
||||
)
|
||||
|
||||
def build(
|
||||
self,
|
||||
|
@ -95,6 +95,9 @@ outposts:
|
||||
discover: true
|
||||
disable_embedded_outpost: false
|
||||
|
||||
expressions:
|
||||
global_runtime: python # or python_restricted
|
||||
|
||||
ldap:
|
||||
task_timeout_hours: 2
|
||||
page_size: 50
|
||||
|
@ -3,27 +3,117 @@
|
||||
import re
|
||||
import socket
|
||||
from collections.abc import Iterable
|
||||
from datetime import timedelta
|
||||
from functools import lru_cache
|
||||
from ipaddress import ip_address, ip_network
|
||||
from pathlib import Path
|
||||
from tempfile import gettempdir
|
||||
from textwrap import indent
|
||||
from typing import Any
|
||||
|
||||
from authentik_client.api.admin_api import AdminApi
|
||||
from authentik_client.api.authenticators_api import AuthenticatorsApi
|
||||
from authentik_client.api.core_api import CoreApi
|
||||
from authentik_client.api.crypto_api import CryptoApi
|
||||
from authentik_client.api.enterprise_api import EnterpriseApi
|
||||
from authentik_client.api.events_api import EventsApi
|
||||
from authentik_client.api.flows_api import FlowsApi
|
||||
from authentik_client.api.managed_api import ManagedApi
|
||||
from authentik_client.api.oauth2_api import Oauth2Api
|
||||
from authentik_client.api.outposts_api import OutpostsApi
|
||||
from authentik_client.api.policies_api import PoliciesApi
|
||||
from authentik_client.api.propertymappings_api import PropertymappingsApi
|
||||
from authentik_client.api.providers_api import ProvidersApi
|
||||
from authentik_client.api.rac_api import RacApi
|
||||
from authentik_client.api.rbac_api import RbacApi
|
||||
from authentik_client.api.root_api import RootApi
|
||||
from authentik_client.api.schema_api import SchemaApi
|
||||
from authentik_client.api.sources_api import SourcesApi
|
||||
from authentik_client.api.stages_api import StagesApi
|
||||
from authentik_client.api.tenants_api import TenantsApi
|
||||
from authentik_client.api_client import ApiClient
|
||||
from authentik_client.configuration import Configuration
|
||||
from cachetools import TLRUCache, cached
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import FieldError
|
||||
from django.utils.timezone import now
|
||||
from guardian.shortcuts import get_anonymous_user
|
||||
from jwt import PyJWTError, decode, encode
|
||||
from rest_framework.serializers import ValidationError
|
||||
from RestrictedPython import compile_restricted, limited_builtins, safe_builtins, utility_builtins
|
||||
from sentry_sdk.hub import Hub
|
||||
from sentry_sdk.tracing import Span
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.events.models import Event
|
||||
from authentik.lib.utils.http import get_http_session
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.generators import generate_key
|
||||
from authentik.lib.utils.errors import exception_to_string
|
||||
from authentik.lib.utils.http import authentik_user_agent, get_http_session
|
||||
from authentik.lib.utils.reflection import get_apps
|
||||
from authentik.policies.models import Policy, PolicyBinding
|
||||
from authentik.policies.process import PolicyProcess
|
||||
from authentik.policies.types import PolicyRequest, PolicyResult
|
||||
from authentik.stages.authenticator import devices_for_user
|
||||
|
||||
LOGGER = get_logger()
|
||||
_tmp = Path(gettempdir())
|
||||
token_path = _tmp / "authentik-evaluator-token"
|
||||
|
||||
API_CLIENTS = {
|
||||
"AdminApi": AdminApi,
|
||||
"AuthenticatorsApi": AuthenticatorsApi,
|
||||
"CoreApi": CoreApi,
|
||||
"CryptoApi": CryptoApi,
|
||||
"EnterpriseApi": EnterpriseApi,
|
||||
"EventsApi": EventsApi,
|
||||
"FlowsApi": FlowsApi,
|
||||
"ManagedApi": ManagedApi,
|
||||
"Oauth2Api": Oauth2Api,
|
||||
"OutpostsApi": OutpostsApi,
|
||||
"PoliciesApi": PoliciesApi,
|
||||
"PropertymappingsApi": PropertymappingsApi,
|
||||
"ProvidersApi": ProvidersApi,
|
||||
"RacApi": RacApi,
|
||||
"RbacApi": RbacApi,
|
||||
"RootApi": RootApi,
|
||||
"SchemaApi": SchemaApi,
|
||||
"SourcesApi": SourcesApi,
|
||||
"StagesApi": StagesApi,
|
||||
"TenantsApi": TenantsApi,
|
||||
}
|
||||
|
||||
JWT_AUD = "goauthentik.io/api/expression"
|
||||
|
||||
_SAFE_MODULES = frozenset(("authentik_client",))
|
||||
|
||||
|
||||
def _safe_import(name, *args, **kwargs):
|
||||
if name not in _SAFE_MODULES:
|
||||
raise Exception(f"Don't you even think about {name!r}")
|
||||
return __import__(name, *args, **kwargs)
|
||||
|
||||
|
||||
@lru_cache
|
||||
def get_api_token_secret():
|
||||
if token_path.exists():
|
||||
with open(token_path) as _token_file:
|
||||
return _token_file.read()
|
||||
key = generate_key()
|
||||
with open(_tmp / "authentik-evaluator-token", "w") as _token_file:
|
||||
_token_file.write(key)
|
||||
return key
|
||||
|
||||
|
||||
def authenticate_token(raw_value: str):
|
||||
"""Authenticate API call from evaluator token"""
|
||||
try:
|
||||
jwt = decode(raw_value, get_api_token_secret(), ["HS256"], audience=JWT_AUD)
|
||||
return User.objects.filter(pk=jwt["sub"]).first()
|
||||
except PyJWTError as exc:
|
||||
LOGGER.debug("failed to auth", exc=exc)
|
||||
return None
|
||||
|
||||
|
||||
class BaseEvaluator:
|
||||
@ -37,8 +127,14 @@ class BaseEvaluator:
|
||||
# Filename used for exec
|
||||
_filename: str
|
||||
|
||||
def __init__(self, filename: str | None = None):
|
||||
_user: User
|
||||
|
||||
# Timeout in seconds, used for the expiration of the API key
|
||||
timeout = 30
|
||||
|
||||
def __init__(self, user: User, filename: str | None = None):
|
||||
self._filename = filename if filename else "BaseEvaluator"
|
||||
self._user = user
|
||||
# update website/docs/expressions/_objects.md
|
||||
# update website/docs/expressions/_functions.md
|
||||
self._globals = {
|
||||
@ -57,8 +153,44 @@ class BaseEvaluator:
|
||||
"resolve_dns": BaseEvaluator.expr_resolve_dns,
|
||||
"reverse_dns": BaseEvaluator.expr_reverse_dns,
|
||||
}
|
||||
for app in get_apps():
|
||||
# Load models from each app
|
||||
for model in app.get_models():
|
||||
self._globals[model.__name__] = model
|
||||
self._globals.update(API_CLIENTS)
|
||||
self._context = {}
|
||||
|
||||
def get_token(self) -> str:
|
||||
"""Generate API token to be used by the API Client"""
|
||||
_now = now()
|
||||
if not self._user:
|
||||
self._user = get_anonymous_user()
|
||||
return encode(
|
||||
{
|
||||
"aud": JWT_AUD,
|
||||
"iss": f"goauthentik.io/expression/{self._filename}",
|
||||
"sub": str(self._user.pk),
|
||||
"iat": int(_now.timestamp()),
|
||||
"exp": int((_now + timedelta(seconds=self.timeout)).timestamp()),
|
||||
},
|
||||
get_api_token_secret(),
|
||||
)
|
||||
|
||||
def get_api_client(self):
|
||||
token = self.get_token()
|
||||
config = Configuration(
|
||||
f"unix://{str(_tmp.joinpath('authentik-core.sock'))}/api/v3",
|
||||
api_key={
|
||||
"authentik": token,
|
||||
},
|
||||
api_key_prefix={"authentik": "Bearer"},
|
||||
)
|
||||
if settings.DEBUG:
|
||||
config.host = "http://localhost:8000/api/v3"
|
||||
client = ApiClient(config)
|
||||
client.user_agent = authentik_user_agent()
|
||||
return client
|
||||
|
||||
@cached(cache=TLRUCache(maxsize=32, ttu=lambda key, value, now: now + 180))
|
||||
@staticmethod
|
||||
def expr_resolve_dns(host: str, ip_version: int | None = None) -> list[str]:
|
||||
@ -185,7 +317,16 @@ class BaseEvaluator:
|
||||
def compile(self, expression: str) -> Any:
|
||||
"""Parse expression. Raises SyntaxError or ValueError if the syntax is incorrect."""
|
||||
param_keys = self._context.keys()
|
||||
return compile(self.wrap_expression(expression, param_keys), self._filename, "exec")
|
||||
compiler = (
|
||||
compile_restricted
|
||||
if CONFIG.get("expressions.global_runtime") == "python_restricted"
|
||||
else compile
|
||||
)
|
||||
return compiler(
|
||||
self.wrap_expression(expression, param_keys),
|
||||
self._filename,
|
||||
"exec",
|
||||
)
|
||||
|
||||
def evaluate(self, expression_source: str) -> Any:
|
||||
"""Parse and evaluate expression. If the syntax is incorrect, a SyntaxError is raised.
|
||||
@ -201,7 +342,17 @@ class BaseEvaluator:
|
||||
self.handle_error(exc, expression_source)
|
||||
raise exc
|
||||
try:
|
||||
if CONFIG.get("expressions.global_runtime") == "python_restricted":
|
||||
self._globals["__builtins__"] = {
|
||||
**safe_builtins,
|
||||
**limited_builtins,
|
||||
**utility_builtins,
|
||||
"__import__": _safe_import,
|
||||
}
|
||||
_locals = self._context
|
||||
# We need to create the API Client later so that the token is valid
|
||||
# from when the execution starts
|
||||
self._globals["api"] = self.get_api_client()
|
||||
# Yes this is an exec, yes it is potentially bad. Since we limit what variables are
|
||||
# available here, and these policies can only be edited by admins, this is a risk
|
||||
# we're willing to take.
|
||||
@ -209,6 +360,7 @@ class BaseEvaluator:
|
||||
exec(ast_obj, self._globals, _locals) # nosec # noqa
|
||||
result = _locals["result"]
|
||||
except Exception as exc:
|
||||
print(exception_to_string(exc))
|
||||
# So, this is a bit questionable. Essentially, we are edit the stacktrace
|
||||
# so the user only sees information relevant to them
|
||||
# and none of our surrounding error handling
|
||||
|
@ -1,6 +1,7 @@
|
||||
"""Test Evaluator base functions"""
|
||||
|
||||
from django.test import TestCase
|
||||
from guardian.shortcuts import get_anonymous_user
|
||||
|
||||
from authentik.core.tests.utils import create_test_admin_user
|
||||
from authentik.events.models import Event
|
||||
@ -33,7 +34,7 @@ class TestEvaluator(TestCase):
|
||||
|
||||
def test_expr_event_create(self):
|
||||
"""Test expr_event_create"""
|
||||
evaluator = BaseEvaluator(generate_id())
|
||||
evaluator = BaseEvaluator(get_anonymous_user(), generate_id())
|
||||
evaluator._context = {
|
||||
"foo": "bar",
|
||||
}
|
||||
|
@ -14,12 +14,13 @@ class ExpressionPolicySerializer(PolicySerializer):
|
||||
def validate_expression(self, expr: str) -> str:
|
||||
"""validate the syntax of the expression"""
|
||||
name = "temp-policy" if not self.instance else self.instance.name
|
||||
PolicyEvaluator(name).validate(expr)
|
||||
request = self.context.get("request")
|
||||
PolicyEvaluator(request.user if request else None, name).validate(expr)
|
||||
return expr
|
||||
|
||||
class Meta:
|
||||
model = ExpressionPolicy
|
||||
fields = PolicySerializer.Meta.fields + ["expression"]
|
||||
fields = PolicySerializer.Meta.fields + ["expression", "execution_user"]
|
||||
|
||||
|
||||
class ExpressionPolicyViewSet(UsedByMixin, ModelViewSet):
|
||||
|
@ -1,11 +1,12 @@
|
||||
"""Authentik policy_expression app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikPolicyExpressionConfig(AppConfig):
|
||||
class AuthentikPolicyExpressionConfig(ManagedAppConfig):
|
||||
"""Authentik policy_expression app config"""
|
||||
|
||||
name = "authentik.policies.expression"
|
||||
label = "authentik_policies_expression"
|
||||
verbose_name = "authentik Policies.Expression"
|
||||
default = True
|
||||
|
@ -6,6 +6,7 @@ from typing import TYPE_CHECKING, Optional
|
||||
from django.http import HttpRequest
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.core.models import User
|
||||
from authentik.flows.planner import PLAN_CONTEXT_SSO
|
||||
from authentik.lib.expression.evaluator import BaseEvaluator
|
||||
from authentik.policies.exceptions import PolicyException
|
||||
@ -24,8 +25,8 @@ class PolicyEvaluator(BaseEvaluator):
|
||||
|
||||
policy: Optional["ExpressionPolicy"] = None
|
||||
|
||||
def __init__(self, policy_name: str | None = None):
|
||||
super().__init__(policy_name or "PolicyEvaluator")
|
||||
def __init__(self, user: User, policy_name: str | None = None):
|
||||
super().__init__(user, policy_name or "PolicyEvaluator")
|
||||
self._messages = []
|
||||
# update website/docs/expressions/_objects.md
|
||||
# update website/docs/expressions/_functions.md
|
||||
@ -44,6 +45,8 @@ class PolicyEvaluator(BaseEvaluator):
|
||||
if request.http_request:
|
||||
self.set_http_request(request.http_request)
|
||||
self._context["request"] = request
|
||||
if not self._user:
|
||||
self._user = request.user
|
||||
self._context["context"] = request.context
|
||||
|
||||
def set_http_request(self, request: HttpRequest):
|
||||
|
@ -0,0 +1,26 @@
|
||||
# Generated by Django 5.0.3 on 2024-03-20 12:14
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_policies_expression", "0004_expressionpolicy_authentik_p_policy__fb6feb_idx"),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="expressionpolicy",
|
||||
name="execution_user",
|
||||
field=models.ForeignKey(
|
||||
default=None,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_DEFAULT,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
]
|
@ -12,6 +12,9 @@ from authentik.policies.types import PolicyRequest, PolicyResult
|
||||
class ExpressionPolicy(Policy):
|
||||
"""Execute arbitrary Python code to implement custom checks and validation."""
|
||||
|
||||
execution_user = models.ForeignKey(
|
||||
"authentik_core.User", default=None, null=True, on_delete=models.SET_DEFAULT
|
||||
)
|
||||
expression = models.TextField()
|
||||
|
||||
@property
|
||||
@ -26,17 +29,11 @@ class ExpressionPolicy(Policy):
|
||||
|
||||
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||
"""Evaluate and render expression. Returns PolicyResult(false) on error."""
|
||||
evaluator = PolicyEvaluator(self.name)
|
||||
evaluator = PolicyEvaluator(self.execution_user, self.name)
|
||||
evaluator.policy = self
|
||||
evaluator.set_policy_request(request)
|
||||
return evaluator.evaluate(self.expression)
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
evaluator = PolicyEvaluator(self.name)
|
||||
evaluator.policy = self
|
||||
evaluator.validate(self.expression)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
class Meta(Policy.PolicyMeta):
|
||||
verbose_name = _("Expression Policy")
|
||||
verbose_name_plural = _("Expression Policies")
|
||||
|
13
authentik/policies/expression/signals.py
Normal file
13
authentik/policies/expression/signals.py
Normal file
@ -0,0 +1,13 @@
|
||||
from django.db.models.signals import pre_save
|
||||
from django.dispatch import receiver
|
||||
|
||||
from authentik.policies.expression.evaluator import PolicyEvaluator
|
||||
from authentik.policies.expression.models import ExpressionPolicy
|
||||
|
||||
|
||||
@receiver(pre_save, sender=ExpressionPolicy)
|
||||
def pre_save_expression_policy(sender: type[ExpressionPolicy], instance: ExpressionPolicy, **_):
|
||||
"""Ensure policy is valid before saving"""
|
||||
evaluator = PolicyEvaluator(instance.execution_user, instance.name)
|
||||
evaluator.policy = instance
|
||||
evaluator.validate(instance.expression)
|
@ -41,14 +41,14 @@ class TestEvaluator(TestCase):
|
||||
def test_valid(self):
|
||||
"""test simple value expression"""
|
||||
template = "return True"
|
||||
evaluator = PolicyEvaluator("test")
|
||||
evaluator = PolicyEvaluator(self.request.user, "test")
|
||||
evaluator.set_policy_request(self.request)
|
||||
self.assertEqual(evaluator.evaluate(template).passing, True)
|
||||
|
||||
def test_messages(self):
|
||||
"""test expression with message return"""
|
||||
template = 'ak_message("some message");return False'
|
||||
evaluator = PolicyEvaluator("test")
|
||||
evaluator = PolicyEvaluator(self.request.user, "test")
|
||||
evaluator.set_policy_request(self.request)
|
||||
result = evaluator.evaluate(template)
|
||||
self.assertEqual(result.passing, False)
|
||||
@ -57,7 +57,7 @@ class TestEvaluator(TestCase):
|
||||
def test_invalid_syntax(self):
|
||||
"""test invalid syntax"""
|
||||
template = ";"
|
||||
evaluator = PolicyEvaluator("test")
|
||||
evaluator = PolicyEvaluator(self.request.user, "test")
|
||||
evaluator.set_policy_request(self.request)
|
||||
with self.assertRaises(PolicyException):
|
||||
evaluator.evaluate(template)
|
||||
@ -65,14 +65,14 @@ class TestEvaluator(TestCase):
|
||||
def test_validate(self):
|
||||
"""test validate"""
|
||||
template = "True"
|
||||
evaluator = PolicyEvaluator("test")
|
||||
evaluator = PolicyEvaluator(self.request.user, "test")
|
||||
result = evaluator.validate(template)
|
||||
self.assertEqual(result, True)
|
||||
|
||||
def test_validate_invalid(self):
|
||||
"""test validate"""
|
||||
template = ";"
|
||||
evaluator = PolicyEvaluator("test")
|
||||
evaluator = PolicyEvaluator(self.request.user, "test")
|
||||
with self.assertRaises(ValidationError):
|
||||
evaluator.validate(template)
|
||||
|
||||
@ -83,7 +83,7 @@ class TestEvaluator(TestCase):
|
||||
execution_logging=True,
|
||||
expression="ak_message(request.http_request.path)\nreturn True",
|
||||
)
|
||||
evaluator = PolicyEvaluator("test")
|
||||
evaluator = PolicyEvaluator(self.request.user, "test")
|
||||
evaluator.set_policy_request(self.request)
|
||||
proc = PolicyProcess(PolicyBinding(policy=expr), request=self.request, connection=None)
|
||||
res = proc.profiling_wrapper()
|
||||
|
@ -10,7 +10,6 @@ from jwt import PyJWKSet
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_cert, create_test_flow
|
||||
from authentik.crypto.builder import PrivateKeyAlg
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.providers.oauth2.models import OAuth2Provider
|
||||
@ -83,7 +82,7 @@ class TestJWKS(OAuthTestCase):
|
||||
client_id="test",
|
||||
authorization_flow=create_test_flow(),
|
||||
redirect_uris="http://local.invalid",
|
||||
signing_key=create_test_cert(PrivateKeyAlg.ECDSA),
|
||||
signing_key=create_test_cert(use_ec_private_key=True),
|
||||
)
|
||||
app = Application.objects.create(name="test", slug="test", provider=provider)
|
||||
response = self.client.get(
|
||||
|
@ -1,44 +0,0 @@
|
||||
# Generated by Django 5.0.4 on 2024-05-01 15:32
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_providers_saml", "0013_samlprovider_default_relay_state"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="samlprovider",
|
||||
name="digest_algorithm",
|
||||
field=models.TextField(
|
||||
choices=[
|
||||
("http://www.w3.org/2000/09/xmldsig#sha1", "SHA1"),
|
||||
("http://www.w3.org/2001/04/xmlenc#sha256", "SHA256"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#sha384", "SHA384"),
|
||||
("http://www.w3.org/2001/04/xmlenc#sha512", "SHA512"),
|
||||
],
|
||||
default="http://www.w3.org/2001/04/xmlenc#sha256",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="samlprovider",
|
||||
name="signature_algorithm",
|
||||
field=models.TextField(
|
||||
choices=[
|
||||
("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "RSA-SHA1"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "RSA-SHA256"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", "RSA-SHA384"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "RSA-SHA512"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1", "ECDSA-SHA1"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256", "ECDSA-SHA256"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384", "ECDSA-SHA384"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512", "ECDSA-SHA512"),
|
||||
("http://www.w3.org/2000/09/xmldsig#dsa-sha1", "DSA-SHA1"),
|
||||
],
|
||||
default="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
|
||||
),
|
||||
),
|
||||
]
|
@ -11,10 +11,6 @@ from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.lib.utils.time import timedelta_string_validator
|
||||
from authentik.sources.saml.processors.constants import (
|
||||
DSA_SHA1,
|
||||
ECDSA_SHA1,
|
||||
ECDSA_SHA256,
|
||||
ECDSA_SHA384,
|
||||
ECDSA_SHA512,
|
||||
RSA_SHA1,
|
||||
RSA_SHA256,
|
||||
RSA_SHA384,
|
||||
@ -96,7 +92,8 @@ class SAMLProvider(Provider):
|
||||
),
|
||||
)
|
||||
|
||||
digest_algorithm = models.TextField(
|
||||
digest_algorithm = models.CharField(
|
||||
max_length=50,
|
||||
choices=(
|
||||
(SHA1, _("SHA1")),
|
||||
(SHA256, _("SHA256")),
|
||||
@ -105,16 +102,13 @@ class SAMLProvider(Provider):
|
||||
),
|
||||
default=SHA256,
|
||||
)
|
||||
signature_algorithm = models.TextField(
|
||||
signature_algorithm = models.CharField(
|
||||
max_length=50,
|
||||
choices=(
|
||||
(RSA_SHA1, _("RSA-SHA1")),
|
||||
(RSA_SHA256, _("RSA-SHA256")),
|
||||
(RSA_SHA384, _("RSA-SHA384")),
|
||||
(RSA_SHA512, _("RSA-SHA512")),
|
||||
(ECDSA_SHA1, _("ECDSA-SHA1")),
|
||||
(ECDSA_SHA256, _("ECDSA-SHA256")),
|
||||
(ECDSA_SHA384, _("ECDSA-SHA384")),
|
||||
(ECDSA_SHA512, _("ECDSA-SHA512")),
|
||||
(DSA_SHA1, _("DSA-SHA1")),
|
||||
),
|
||||
default=RSA_SHA256,
|
||||
|
@ -7,14 +7,13 @@ from lxml import etree # nosec
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_cert, create_test_flow
|
||||
from authentik.crypto.builder import PrivateKeyAlg
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.lib.tests.utils import load_fixture
|
||||
from authentik.lib.xml import lxml_from_string
|
||||
from authentik.providers.saml.models import SAMLBindings, SAMLPropertyMapping, SAMLProvider
|
||||
from authentik.providers.saml.processors.metadata import MetadataProcessor
|
||||
from authentik.providers.saml.processors.metadata_parser import ServiceProviderMetadataParser
|
||||
from authentik.sources.saml.processors.constants import ECDSA_SHA256, NS_MAP, NS_SAML_METADATA
|
||||
from authentik.sources.saml.processors.constants import NS_MAP, NS_SAML_METADATA
|
||||
|
||||
|
||||
class TestServiceProviderMetadataParser(TestCase):
|
||||
@ -108,41 +107,12 @@ class TestServiceProviderMetadataParser(TestCase):
|
||||
load_fixture("fixtures/cert.xml").replace("/apps/user_saml", "")
|
||||
)
|
||||
|
||||
def test_signature_rsa(self):
|
||||
"""Test signature validation (RSA)"""
|
||||
def test_signature(self):
|
||||
"""Test signature validation"""
|
||||
provider = SAMLProvider.objects.create(
|
||||
name=generate_id(),
|
||||
authorization_flow=self.flow,
|
||||
signing_kp=create_test_cert(PrivateKeyAlg.RSA),
|
||||
)
|
||||
Application.objects.create(
|
||||
name=generate_id(),
|
||||
slug=generate_id(),
|
||||
provider=provider,
|
||||
)
|
||||
request = self.factory.get("/")
|
||||
metadata = MetadataProcessor(provider, request).build_entity_descriptor()
|
||||
|
||||
root = fromstring(metadata.encode())
|
||||
xmlsec.tree.add_ids(root, ["ID"])
|
||||
signature_nodes = root.xpath("/md:EntityDescriptor/ds:Signature", namespaces=NS_MAP)
|
||||
signature_node = signature_nodes[0]
|
||||
ctx = xmlsec.SignatureContext()
|
||||
key = xmlsec.Key.from_memory(
|
||||
provider.signing_kp.certificate_data,
|
||||
xmlsec.constants.KeyDataFormatCertPem,
|
||||
None,
|
||||
)
|
||||
ctx.key = key
|
||||
ctx.verify(signature_node)
|
||||
|
||||
def test_signature_ecdsa(self):
|
||||
"""Test signature validation (ECDSA)"""
|
||||
provider = SAMLProvider.objects.create(
|
||||
name=generate_id(),
|
||||
authorization_flow=self.flow,
|
||||
signing_kp=create_test_cert(PrivateKeyAlg.ECDSA),
|
||||
signature_algorithm=ECDSA_SHA256,
|
||||
signing_kp=create_test_cert(),
|
||||
)
|
||||
Application.objects.create(
|
||||
name=generate_id(),
|
||||
|
@ -3,7 +3,7 @@
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.providers.scim.models import SCIMProvider
|
||||
from authentik.providers.scim.tasks import scim_task_wrapper
|
||||
from authentik.providers.scim.tasks import scim_sync
|
||||
from authentik.tenants.management import TenantCommand
|
||||
|
||||
LOGGER = get_logger()
|
||||
@ -21,4 +21,4 @@ class Command(TenantCommand):
|
||||
if not provider:
|
||||
LOGGER.warning("Provider does not exist", name=provider_name)
|
||||
continue
|
||||
scim_task_wrapper(provider.pk).get()
|
||||
scim_sync.delay(provider.pk).get()
|
||||
|
@ -9,7 +9,7 @@ from structlog.stdlib import get_logger
|
||||
from authentik.core.models import Group, User
|
||||
from authentik.lib.utils.reflection import class_to_path
|
||||
from authentik.providers.scim.models import SCIMProvider
|
||||
from authentik.providers.scim.tasks import scim_signal_direct, scim_signal_m2m, scim_task_wrapper
|
||||
from authentik.providers.scim.tasks import scim_signal_direct, scim_signal_m2m, scim_sync
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
@ -17,7 +17,7 @@ LOGGER = get_logger()
|
||||
@receiver(post_save, sender=SCIMProvider)
|
||||
def post_save_provider(sender: type[Model], instance, created: bool, **_):
|
||||
"""Trigger sync when SCIM provider is saved"""
|
||||
scim_task_wrapper(instance.pk)
|
||||
scim_sync.delay(instance.pk)
|
||||
|
||||
|
||||
@receiver(post_save, sender=User)
|
||||
|
@ -38,23 +38,7 @@ def client_for_model(provider: SCIMProvider, model: Model) -> SCIMClient:
|
||||
def scim_sync_all():
|
||||
"""Run sync for all providers"""
|
||||
for provider in SCIMProvider.objects.filter(backchannel_application__isnull=False):
|
||||
scim_task_wrapper(provider.pk)
|
||||
|
||||
|
||||
def scim_task_wrapper(provider_pk: int):
|
||||
"""Wrap scim_sync to set the correct timeouts"""
|
||||
provider: SCIMProvider = SCIMProvider.objects.filter(
|
||||
pk=provider_pk, backchannel_application__isnull=False
|
||||
).first()
|
||||
if not provider:
|
||||
return
|
||||
users_paginator = Paginator(provider.get_user_qs(), PAGE_SIZE)
|
||||
groups_paginator = Paginator(provider.get_group_qs(), PAGE_SIZE)
|
||||
soft_time_limit = (users_paginator.num_pages + groups_paginator.num_pages) * PAGE_TIMEOUT
|
||||
time_limit = soft_time_limit * 1.5
|
||||
return scim_sync.apply_async(
|
||||
(provider.pk,), time_limit=int(time_limit), soft_time_limit=int(soft_time_limit)
|
||||
)
|
||||
scim_sync.delay(provider.pk)
|
||||
|
||||
|
||||
@CELERY_APP.task(bind=True, base=SystemTask)
|
||||
@ -76,7 +60,7 @@ def scim_sync(self: SystemTask, provider_pk: int) -> None:
|
||||
users_paginator = Paginator(provider.get_user_qs(), PAGE_SIZE)
|
||||
groups_paginator = Paginator(provider.get_group_qs(), PAGE_SIZE)
|
||||
self.soft_time_limit = self.time_limit = (
|
||||
users_paginator.num_pages + groups_paginator.num_pages
|
||||
users_paginator.count + groups_paginator.count
|
||||
) * PAGE_TIMEOUT
|
||||
with allow_join_result():
|
||||
try:
|
||||
|
@ -8,7 +8,7 @@ from authentik.core.models import Application, Group, User
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.providers.scim.clients.schema import ServiceProviderConfiguration
|
||||
from authentik.providers.scim.models import SCIMMapping, SCIMProvider
|
||||
from authentik.providers.scim.tasks import scim_task_wrapper
|
||||
from authentik.providers.scim.tasks import scim_sync
|
||||
from authentik.tenants.models import Tenant
|
||||
|
||||
|
||||
@ -79,7 +79,7 @@ class SCIMMembershipTests(TestCase):
|
||||
)
|
||||
|
||||
self.configure()
|
||||
scim_task_wrapper(self.provider.pk).get()
|
||||
scim_sync.delay(self.provider.pk).get()
|
||||
|
||||
self.assertEqual(mocker.call_count, 6)
|
||||
self.assertEqual(mocker.request_history[0].method, "GET")
|
||||
@ -169,7 +169,7 @@ class SCIMMembershipTests(TestCase):
|
||||
)
|
||||
|
||||
self.configure()
|
||||
scim_task_wrapper(self.provider.pk).get()
|
||||
scim_sync.delay(self.provider.pk).get()
|
||||
|
||||
self.assertEqual(mocker.call_count, 6)
|
||||
self.assertEqual(mocker.request_history[0].method, "GET")
|
||||
|
@ -10,7 +10,7 @@ from authentik.blueprints.tests import apply_blueprint
|
||||
from authentik.core.models import Application, Group, User
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.providers.scim.models import SCIMMapping, SCIMProvider
|
||||
from authentik.providers.scim.tasks import scim_task_wrapper
|
||||
from authentik.providers.scim.tasks import scim_sync
|
||||
from authentik.tenants.models import Tenant
|
||||
|
||||
|
||||
@ -236,7 +236,7 @@ class SCIMUserTests(TestCase):
|
||||
email=f"{uid}@goauthentik.io",
|
||||
)
|
||||
|
||||
scim_task_wrapper(self.provider.pk).get()
|
||||
scim_sync.delay(self.provider.pk).get()
|
||||
|
||||
self.assertEqual(mock.call_count, 5)
|
||||
self.assertEqual(mock.request_history[0].method, "GET")
|
||||
|
@ -1,44 +0,0 @@
|
||||
# Generated by Django 5.0.4 on 2024-05-01 15:44
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_sources_saml", "0013_samlsource_verification_kp_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="samlsource",
|
||||
name="digest_algorithm",
|
||||
field=models.TextField(
|
||||
choices=[
|
||||
("http://www.w3.org/2000/09/xmldsig#sha1", "SHA1"),
|
||||
("http://www.w3.org/2001/04/xmlenc#sha256", "SHA256"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#sha384", "SHA384"),
|
||||
("http://www.w3.org/2001/04/xmlenc#sha512", "SHA512"),
|
||||
],
|
||||
default="http://www.w3.org/2001/04/xmlenc#sha256",
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="samlsource",
|
||||
name="signature_algorithm",
|
||||
field=models.TextField(
|
||||
choices=[
|
||||
("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "RSA-SHA1"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "RSA-SHA256"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", "RSA-SHA384"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "RSA-SHA512"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1", "ECDSA-SHA1"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256", "ECDSA-SHA256"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384", "ECDSA-SHA384"),
|
||||
("http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512", "ECDSA-SHA512"),
|
||||
("http://www.w3.org/2000/09/xmldsig#dsa-sha1", "DSA-SHA1"),
|
||||
],
|
||||
default="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
|
||||
),
|
||||
),
|
||||
]
|
@ -15,10 +15,6 @@ from authentik.flows.models import Flow
|
||||
from authentik.lib.utils.time import timedelta_string_validator
|
||||
from authentik.sources.saml.processors.constants import (
|
||||
DSA_SHA1,
|
||||
ECDSA_SHA1,
|
||||
ECDSA_SHA256,
|
||||
ECDSA_SHA384,
|
||||
ECDSA_SHA512,
|
||||
RSA_SHA1,
|
||||
RSA_SHA256,
|
||||
RSA_SHA384,
|
||||
@ -147,7 +143,8 @@ class SAMLSource(Source):
|
||||
verbose_name=_("Signing Keypair"),
|
||||
)
|
||||
|
||||
digest_algorithm = models.TextField(
|
||||
digest_algorithm = models.CharField(
|
||||
max_length=50,
|
||||
choices=(
|
||||
(SHA1, _("SHA1")),
|
||||
(SHA256, _("SHA256")),
|
||||
@ -156,16 +153,13 @@ class SAMLSource(Source):
|
||||
),
|
||||
default=SHA256,
|
||||
)
|
||||
signature_algorithm = models.TextField(
|
||||
signature_algorithm = models.CharField(
|
||||
max_length=50,
|
||||
choices=(
|
||||
(RSA_SHA1, _("RSA-SHA1")),
|
||||
(RSA_SHA256, _("RSA-SHA256")),
|
||||
(RSA_SHA384, _("RSA-SHA384")),
|
||||
(RSA_SHA512, _("RSA-SHA512")),
|
||||
(ECDSA_SHA1, _("ECDSA-SHA1")),
|
||||
(ECDSA_SHA256, _("ECDSA-SHA256")),
|
||||
(ECDSA_SHA384, _("ECDSA-SHA384")),
|
||||
(ECDSA_SHA512, _("ECDSA-SHA512")),
|
||||
(DSA_SHA1, _("DSA-SHA1")),
|
||||
),
|
||||
default=RSA_SHA256,
|
||||
|
@ -26,16 +26,9 @@ SAML_BINDING_REDIRECT = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
|
||||
|
||||
DSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#dsa-sha1"
|
||||
RSA_SHA1 = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"
|
||||
# https://datatracker.ietf.org/doc/html/rfc4051#section-2.3.2
|
||||
RSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"
|
||||
RSA_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384"
|
||||
RSA_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha512"
|
||||
# https://datatracker.ietf.org/doc/html/rfc4051#section-2.3.6
|
||||
ECDSA_SHA1 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1"
|
||||
ECDSA_SHA224 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha224"
|
||||
ECDSA_SHA256 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"
|
||||
ECDSA_SHA384 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384"
|
||||
ECDSA_SHA512 = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512"
|
||||
|
||||
SHA1 = "http://www.w3.org/2000/09/xmldsig#sha1"
|
||||
SHA256 = "http://www.w3.org/2001/04/xmlenc#sha256"
|
||||
@ -48,11 +41,6 @@ SIGN_ALGORITHM_TRANSFORM_MAP = {
|
||||
RSA_SHA256: xmlsec.constants.TransformRsaSha256,
|
||||
RSA_SHA384: xmlsec.constants.TransformRsaSha384,
|
||||
RSA_SHA512: xmlsec.constants.TransformRsaSha512,
|
||||
ECDSA_SHA1: xmlsec.constants.TransformEcdsaSha1,
|
||||
ECDSA_SHA224: xmlsec.constants.TransformEcdsaSha224,
|
||||
ECDSA_SHA256: xmlsec.constants.TransformEcdsaSha256,
|
||||
ECDSA_SHA384: xmlsec.constants.TransformEcdsaSha384,
|
||||
ECDSA_SHA512: xmlsec.constants.TransformEcdsaSha512,
|
||||
}
|
||||
|
||||
DIGEST_ALGORITHM_TRANSLATION_MAP = {
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,23 +0,0 @@
|
||||
# Generated by Django 5.0.4 on 2024-05-01 15:32
|
||||
|
||||
import authentik.lib.utils.time
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_tenants", "0002_tenant_default_token_duration_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="tenant",
|
||||
name="default_token_duration",
|
||||
field=models.TextField(
|
||||
default="days=1",
|
||||
help_text="Default token duration",
|
||||
validators=[authentik.lib.utils.time.timedelta_string_validator],
|
||||
),
|
||||
),
|
||||
]
|
@ -85,30 +85,19 @@ entries:
|
||||
model: authentik_stages_prompt.prompt
|
||||
- attrs:
|
||||
expression: |
|
||||
from authentik.core.models import (
|
||||
USER_ATTRIBUTE_CHANGE_EMAIL,
|
||||
USER_ATTRIBUTE_CHANGE_NAME,
|
||||
USER_ATTRIBUTE_CHANGE_USERNAME
|
||||
)
|
||||
prompt_data = request.context.get("prompt_data")
|
||||
|
||||
if not request.user.group_attributes(request.http_request).get(
|
||||
USER_ATTRIBUTE_CHANGE_EMAIL, request.http_request.tenant.default_user_change_email
|
||||
):
|
||||
user_group_attributes = request.user.group_attributes(request.http_request)
|
||||
if not user_group_attributes.get(USER_ATTRIBUTE_CHANGE_EMAIL, request.http_request.tenant.default_user_change_email):
|
||||
if prompt_data.get("email") != request.user.email:
|
||||
ak_message("Not allowed to change email address.")
|
||||
return False
|
||||
|
||||
if not request.user.group_attributes(request.http_request).get(
|
||||
USER_ATTRIBUTE_CHANGE_NAME, request.http_request.tenant.default_user_change_name
|
||||
):
|
||||
if not user_group_attributes.get(USER_ATTRIBUTE_CHANGE_NAME, request.http_request.tenant.default_user_change_name):
|
||||
if prompt_data.get("name") != request.user.name:
|
||||
ak_message("Not allowed to change name.")
|
||||
return False
|
||||
|
||||
if not request.user.group_attributes(request.http_request).get(
|
||||
USER_ATTRIBUTE_CHANGE_USERNAME, request.http_request.tenant.default_user_change_username
|
||||
):
|
||||
if not user_group_attributes.get(USER_ATTRIBUTE_CHANGE_USERNAME, request.http_request.tenant.default_user_change_username):
|
||||
if prompt_data.get("username") != request.user.username:
|
||||
ak_message("Not allowed to change username.")
|
||||
return False
|
||||
|
@ -89,10 +89,9 @@ entries:
|
||||
expression: |
|
||||
# This policy ensures that the setup flow can only be
|
||||
# used one time
|
||||
from authentik.flows.models import Flow, FlowAuthenticationRequirement
|
||||
Flow.objects.filter(slug="initial-setup").update(
|
||||
authentication=FlowAuthenticationRequirement.REQUIRE_SUPERUSER,
|
||||
)
|
||||
FlowsApi(api).flows_instances_partial_update("initial-setup", {
|
||||
"authentication": "REQUIRE_SUPERUSER"
|
||||
})
|
||||
return True
|
||||
id: policy-default-oobe-flow-set-authentication
|
||||
identifiers:
|
||||
|
@ -3477,6 +3477,10 @@
|
||||
"type": "string",
|
||||
"minLength": 1,
|
||||
"title": "Expression"
|
||||
},
|
||||
"execution_user": {
|
||||
"type": "integer",
|
||||
"title": "Execution user"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@ -4131,10 +4135,6 @@
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha384",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512",
|
||||
"http://www.w3.org/2000/09/xmldsig#dsa-sha1"
|
||||
],
|
||||
"title": "Signature algorithm"
|
||||
@ -4939,10 +4939,6 @@
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha384",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#rsa-sha512",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384",
|
||||
"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512",
|
||||
"http://www.w3.org/2000/09/xmldsig#dsa-sha1"
|
||||
],
|
||||
"title": "Signature algorithm"
|
||||
|
2
go.mod
2
go.mod
@ -28,7 +28,7 @@ require (
|
||||
github.com/spf13/cobra v1.8.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/wwt/guac v1.3.2
|
||||
goauthentik.io/api/v3 v3.2024041.2
|
||||
goauthentik.io/api/v3 v3.2024041.1
|
||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||
golang.org/x/oauth2 v0.19.0
|
||||
golang.org/x/sync v0.7.0
|
||||
|
4
go.sum
4
go.sum
@ -294,8 +294,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.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
|
||||
go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
|
||||
goauthentik.io/api/v3 v3.2024041.2 h1:gbquIA8RU+9jJbFdGckQTtJzOfWVp2+QdF4LuNVTAWM=
|
||||
goauthentik.io/api/v3 v3.2024041.2/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
|
||||
goauthentik.io/api/v3 v3.2024041.1 h1:oYj6DYqmZJd6/wyknBZLnLa+4+ShT4ry7HQn0W8VXxY=
|
||||
goauthentik.io/api/v3 v3.2024041.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=
|
||||
|
@ -117,8 +117,6 @@ def run_migrations():
|
||||
)
|
||||
finally:
|
||||
release_lock(curr)
|
||||
curr.close()
|
||||
conn.close()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-05-03 00:08+0000\n"
|
||||
"POT-Creation-Date: 2024-04-16 00:07+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"
|
||||
@ -363,14 +363,6 @@ msgstr ""
|
||||
msgid "Subject-alt name"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/builder.py
|
||||
msgid "rsa"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/builder.py
|
||||
msgid "ecdsa"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/crypto/models.py
|
||||
msgid "PEM-encoded Certificate data"
|
||||
msgstr ""
|
||||
@ -1557,22 +1549,6 @@ msgstr ""
|
||||
msgid "RSA-SHA512"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/saml/models.py authentik/sources/saml/models.py
|
||||
msgid "ECDSA-SHA1"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/saml/models.py authentik/sources/saml/models.py
|
||||
msgid "ECDSA-SHA256"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/saml/models.py authentik/sources/saml/models.py
|
||||
msgid "ECDSA-SHA384"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/saml/models.py authentik/sources/saml/models.py
|
||||
msgid "ECDSA-SHA512"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/saml/models.py authentik/sources/saml/models.py
|
||||
msgid "DSA-SHA1"
|
||||
msgstr ""
|
||||
|
1954
poetry.lock
generated
1954
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Stage 1: Build website
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/node:22 as web-builder
|
||||
FROM --platform=${BUILDPLATFORM} docker.io/node:21 as web-builder
|
||||
|
||||
ENV NODE_ENV=production
|
||||
WORKDIR /static
|
||||
|
@ -83,13 +83,13 @@ filterwarnings = [
|
||||
]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
authentik_client = "2024.4.1.post1714149882"
|
||||
argon2-cffi = "*"
|
||||
celery = "*"
|
||||
channels = { version = "*", extras = ["daphne"] }
|
||||
channels-redis = "*"
|
||||
codespell = "*"
|
||||
colorama = "*"
|
||||
cryptography = "*"
|
||||
dacite = "*"
|
||||
deepmerge = "*"
|
||||
defusedxml = "*"
|
||||
@ -102,7 +102,7 @@ django-redis = "*"
|
||||
django-storages = { extras = ["s3"], version = "*" }
|
||||
# See https://github.com/django-tenants/django-tenants/pull/997
|
||||
django-tenants = { git = "https://github.com/rissson/django-tenants.git", branch="authentik-fixes" }
|
||||
djangorestframework = "3.14.0"
|
||||
djangorestframework = "*"
|
||||
djangorestframework-guardian = "*"
|
||||
docker = "*"
|
||||
drf-spectacular = "*"
|
||||
@ -116,17 +116,24 @@ gunicorn = "*"
|
||||
jsonpatch = "*"
|
||||
kubernetes = "*"
|
||||
ldap3 = "*"
|
||||
lxml = "*"
|
||||
lxml = [
|
||||
# 5.0.0 works with libxml2 2.11.x, which is standard on brew
|
||||
{ version = "5.0.0", platform = "darwin" },
|
||||
# 4.9.x works with previous libxml2 versions, which is what we get on linux
|
||||
{ version = "4.9.4", platform = "linux" },
|
||||
]
|
||||
opencontainers = { extras = ["reggie"], version = "*" }
|
||||
packaging = "*"
|
||||
paramiko = "*"
|
||||
psycopg = { extras = ["c"], version = "*" }
|
||||
pycryptodome = "*"
|
||||
pydantic = "*"
|
||||
pydantic-scim = "*"
|
||||
pyjwt = "*"
|
||||
python = "~3.12"
|
||||
pyyaml = "*"
|
||||
requests-oauthlib = "*"
|
||||
restrictedpython = "*"
|
||||
scim2-filter-parser = "*"
|
||||
sentry-sdk = "*"
|
||||
service_identity = "*"
|
||||
|
@ -18,7 +18,7 @@ RUN --mount=type=cache,sharing=locked,target=/go/pkg/mod \
|
||||
go build -o /go/rac ./cmd/rac
|
||||
|
||||
# Stage 2: Run
|
||||
FROM ghcr.io/beryju/guacd:1.5.5
|
||||
FROM ghcr.io/beryju/guacd:1.5.3
|
||||
|
||||
ARG GIT_BUILD_HASH
|
||||
ENV GIT_BUILD_HASH=$GIT_BUILD_HASH
|
||||
|
34
schema.yml
34
schema.yml
@ -11852,6 +11852,10 @@ paths:
|
||||
name: execution_logging
|
||||
schema:
|
||||
type: boolean
|
||||
- in: query
|
||||
name: execution_user
|
||||
schema:
|
||||
type: integer
|
||||
- in: query
|
||||
name: expression
|
||||
schema:
|
||||
@ -17051,10 +17055,6 @@ paths:
|
||||
enum:
|
||||
- http://www.w3.org/2000/09/xmldsig#dsa-sha1
|
||||
- http://www.w3.org/2000/09/xmldsig#rsa-sha1
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha384
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha512
|
||||
@ -20914,10 +20914,6 @@ paths:
|
||||
enum:
|
||||
- http://www.w3.org/2000/09/xmldsig#dsa-sha1
|
||||
- http://www.w3.org/2000/09/xmldsig#rsa-sha1
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha384
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha512
|
||||
@ -30458,11 +30454,6 @@ components:
|
||||
- pending_user
|
||||
- pending_user_avatar
|
||||
- type
|
||||
AlgEnum:
|
||||
enum:
|
||||
- rsa
|
||||
- ecdsa
|
||||
type: string
|
||||
App:
|
||||
type: object
|
||||
description: Serialize Application info
|
||||
@ -32120,10 +32111,6 @@ components:
|
||||
type: string
|
||||
validity_days:
|
||||
type: integer
|
||||
alg:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AlgEnum'
|
||||
default: rsa
|
||||
required:
|
||||
- common_name
|
||||
- validity_days
|
||||
@ -33582,6 +33569,9 @@ components:
|
||||
readOnly: true
|
||||
expression:
|
||||
type: string
|
||||
execution_user:
|
||||
type: integer
|
||||
nullable: true
|
||||
required:
|
||||
- bound_to
|
||||
- component
|
||||
@ -33605,6 +33595,9 @@ components:
|
||||
expression:
|
||||
type: string
|
||||
minLength: 1
|
||||
execution_user:
|
||||
type: integer
|
||||
nullable: true
|
||||
required:
|
||||
- expression
|
||||
- name
|
||||
@ -38858,6 +38851,9 @@ components:
|
||||
expression:
|
||||
type: string
|
||||
minLength: 1
|
||||
execution_user:
|
||||
type: integer
|
||||
nullable: true
|
||||
PatchedFlowRequest:
|
||||
type: object
|
||||
description: Flow Serializer
|
||||
@ -43675,10 +43671,6 @@ components:
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha256
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha384
|
||||
- http://www.w3.org/2001/04/xmldsig-more#rsa-sha512
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha1
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha384
|
||||
- http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha512
|
||||
- http://www.w3.org/2000/09/xmldsig#dsa-sha1
|
||||
type: string
|
||||
Source:
|
||||
|
2447
tests/wdio/package-lock.json
generated
2447
tests/wdio/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
405
web/package-lock.json
generated
405
web/package-lock.json
generated
@ -11,13 +11,13 @@
|
||||
"dependencies": {
|
||||
"@codemirror/lang-html": "^6.4.9",
|
||||
"@codemirror/lang-javascript": "^6.2.2",
|
||||
"@codemirror/lang-python": "^6.1.6",
|
||||
"@codemirror/lang-python": "^6.1.5",
|
||||
"@codemirror/lang-xml": "^6.1.0",
|
||||
"@codemirror/legacy-modes": "^6.4.0",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@formatjs/intl-listformat": "^7.5.5",
|
||||
"@fortawesome/fontawesome-free": "^6.5.2",
|
||||
"@goauthentik/api": "^2024.4.1-1714655911",
|
||||
"@goauthentik/api": "^2024.4.1-1714149838",
|
||||
"@lit-labs/task": "^3.1.0",
|
||||
"@lit/context": "^1.1.1",
|
||||
"@lit/localize": "^0.12.1",
|
||||
@ -25,7 +25,8 @@
|
||||
"@open-wc/lit-helpers": "^0.7.0",
|
||||
"@patternfly/elements": "^3.0.1",
|
||||
"@patternfly/patternfly": "^4.224.2",
|
||||
"@sentry/browser": "^7.113.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.17.0",
|
||||
"@sentry/browser": "^7.112.2",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.4.2",
|
||||
@ -47,13 +48,13 @@
|
||||
"yaml": "^2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.5",
|
||||
"@babel/core": "^7.24.4",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/plugin-proposal-decorators": "^7.24.1",
|
||||
"@babel/plugin-transform-private-methods": "^7.24.1",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.24.5",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.24.1",
|
||||
"@babel/plugin-transform-runtime": "^7.24.3",
|
||||
"@babel/preset-env": "^7.24.5",
|
||||
"@babel/preset-env": "^7.24.4",
|
||||
"@babel/preset-typescript": "^7.24.1",
|
||||
"@hcaptcha/types": "^1.0.3",
|
||||
"@jeysal/storybook-addon-css-user-preferences": "^0.2.0",
|
||||
@ -111,9 +112,9 @@
|
||||
"@esbuild/darwin-arm64": "^0.20.1",
|
||||
"@esbuild/linux-amd64": "^0.18.11",
|
||||
"@esbuild/linux-arm64": "^0.20.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.17.2",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.17.2",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.17.2"
|
||||
"@rollup/rollup-darwin-arm64": "4.17.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.17.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
@ -185,21 +186,21 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/core": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.5.tgz",
|
||||
"integrity": "sha512-tVQRucExLQ02Boi4vdPp49svNGcfL2GhdTCT9aldhXgCJVAI21EtRfBettiuLUwce/7r6bFdgs6JFkcdTiFttA==",
|
||||
"version": "7.24.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.4.tgz",
|
||||
"integrity": "sha512-MBVlMXP+kkl5394RBLSxxk/iLTeVGuXTV3cIDXavPpMMqnSnt6apKgan/U8O3USWZCWZT/TbgfEpKa4uMgN4Dg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@ampproject/remapping": "^2.2.0",
|
||||
"@babel/code-frame": "^7.24.2",
|
||||
"@babel/generator": "^7.24.5",
|
||||
"@babel/generator": "^7.24.4",
|
||||
"@babel/helper-compilation-targets": "^7.23.6",
|
||||
"@babel/helper-module-transforms": "^7.24.5",
|
||||
"@babel/helpers": "^7.24.5",
|
||||
"@babel/parser": "^7.24.5",
|
||||
"@babel/helper-module-transforms": "^7.23.3",
|
||||
"@babel/helpers": "^7.24.4",
|
||||
"@babel/parser": "^7.24.4",
|
||||
"@babel/template": "^7.24.0",
|
||||
"@babel/traverse": "^7.24.5",
|
||||
"@babel/types": "^7.24.5",
|
||||
"@babel/traverse": "^7.24.1",
|
||||
"@babel/types": "^7.24.0",
|
||||
"convert-source-map": "^2.0.0",
|
||||
"debug": "^4.1.0",
|
||||
"gensync": "^1.0.0-beta.2",
|
||||
@ -215,12 +216,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/generator": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz",
|
||||
"integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==",
|
||||
"version": "7.24.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.4.tgz",
|
||||
"integrity": "sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.24.5",
|
||||
"@babel/types": "^7.24.0",
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.25",
|
||||
"jsesc": "^2.5.1"
|
||||
@ -272,19 +273,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-create-class-features-plugin": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.5.tgz",
|
||||
"integrity": "sha512-uRc4Cv8UQWnE4NXlYTIIdM7wfFkOqlFztcC/gVXDKohKoVB3OyonfelUBaJzSwpBntZ2KYGF/9S7asCHsXwW6g==",
|
||||
"version": "7.24.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.24.4.tgz",
|
||||
"integrity": "sha512-lG75yeuUSVu0pIcbhiYMXBXANHrpUPaOfu7ryAzskCgKUHuAxRQI5ssrtmF0X9UXldPlvT0XM/A4F44OXRt6iQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.22.5",
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-function-name": "^7.23.0",
|
||||
"@babel/helper-member-expression-to-functions": "^7.24.5",
|
||||
"@babel/helper-member-expression-to-functions": "^7.23.0",
|
||||
"@babel/helper-optimise-call-expression": "^7.22.5",
|
||||
"@babel/helper-replace-supers": "^7.24.1",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
|
||||
"@babel/helper-split-export-declaration": "^7.24.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"semver": "^6.3.1"
|
||||
},
|
||||
"engines": {
|
||||
@ -366,12 +367,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-member-expression-to-functions": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.5.tgz",
|
||||
"integrity": "sha512-4owRteeihKWKamtqg4JmWSsEZU445xpFRXPEwp44HbgbxdWlUV1b4Agg4lkA806Lil5XM/e+FJyS0vj5T6vmcA==",
|
||||
"version": "7.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz",
|
||||
"integrity": "sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.24.5"
|
||||
"@babel/types": "^7.23.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -390,16 +392,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-module-transforms": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.5.tgz",
|
||||
"integrity": "sha512-9GxeY8c2d2mdQUP1Dye0ks3VDyIMS98kt/llQ2nUId8IsWqTF0l1LkSX0/uP7l7MCDrzXS009Hyhe2gzTiGW8A==",
|
||||
"version": "7.23.3",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
|
||||
"integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-module-imports": "^7.24.3",
|
||||
"@babel/helper-simple-access": "^7.24.5",
|
||||
"@babel/helper-split-export-declaration": "^7.24.5",
|
||||
"@babel/helper-validator-identifier": "^7.24.5"
|
||||
"@babel/helper-module-imports": "^7.22.15",
|
||||
"@babel/helper-simple-access": "^7.22.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"@babel/helper-validator-identifier": "^7.22.20"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -422,10 +425,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-plugin-utils": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.5.tgz",
|
||||
"integrity": "sha512-xjNLDopRzW2o6ba0gKbkZq5YWEBaK3PCyTOY1K2P/O07LGMhMqlMXPxwN4S5/RhWuCobT8z0jrlKGlYmeR1OhQ==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.0.tgz",
|
||||
"integrity": "sha512-9cUznXMG0+FxRuJfvL82QlTqIzhVW9sL0KjMPHhAOOvpQGL8QtdxnBKILjBqxlHyliz0yCa1G903ZXI/FuHy2w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@ -465,12 +469,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-simple-access": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.5.tgz",
|
||||
"integrity": "sha512-uH3Hmf5q5n7n8mz7arjUlDOCbttY/DW4DYhE6FUsjKJ/oYC1kQQUvwEQWxRwUpX9qQKRXeqLwWxrqilMrf32sQ==",
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
|
||||
"integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.24.5"
|
||||
"@babel/types": "^7.22.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -490,31 +495,34 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-split-export-declaration": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz",
|
||||
"integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==",
|
||||
"version": "7.22.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
|
||||
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.24.5"
|
||||
"@babel/types": "^7.22.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
|
||||
"integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
|
||||
"version": "7.23.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz",
|
||||
"integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz",
|
||||
"integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==",
|
||||
"version": "7.22.20",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
|
||||
"integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
@ -544,14 +552,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helpers": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.5.tgz",
|
||||
"integrity": "sha512-CiQmBMMpMQHwM5m01YnrM6imUG1ebgYJ+fAIW4FZe6m4qHTPaRHti+R8cggAwkdz4oXhtO4/K9JWlh+8hIfR2Q==",
|
||||
"version": "7.24.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.4.tgz",
|
||||
"integrity": "sha512-FewdlZbSiwaVGlgT1DPANDuCHaDMiOo+D/IDYRFYjHOuv66xMSJ7fQwwODwRNAPkADIO/z1EoF/l2BCWlWABDw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/template": "^7.24.0",
|
||||
"@babel/traverse": "^7.24.5",
|
||||
"@babel/types": "^7.24.5"
|
||||
"@babel/traverse": "^7.24.1",
|
||||
"@babel/types": "^7.24.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -573,9 +581,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
|
||||
"integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
|
||||
"version": "7.24.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz",
|
||||
"integrity": "sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
@ -585,13 +593,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.5.tgz",
|
||||
"integrity": "sha512-LdXRi1wEMTrHVR4Zc9F8OewC3vdm5h4QB6L71zy6StmYeqGi1b3ttIO8UC+BfZKcH9jdr4aI249rBkm+3+YvHw==",
|
||||
"version": "7.24.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.24.4.tgz",
|
||||
"integrity": "sha512-qpl6vOOEEzTLLcsuqYYo8yDtrTocmu2xkGvgNebvPjT9DTtfFYGmgDqY+rBYXNlqL4s9qLDn6xkrJv4RxAPiTA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-plugin-utils": "^7.24.5"
|
||||
"@babel/helper-plugin-utils": "^7.24.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -1063,12 +1071,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-block-scoping": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.5.tgz",
|
||||
"integrity": "sha512-sMfBc3OxghjC95BkYrYocHL3NaOplrcaunblzwXhGmlPwpmfsxr4vK+mBBt49r+S240vahmv+kUxkeKgs+haCw==",
|
||||
"version": "7.24.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.24.4.tgz",
|
||||
"integrity": "sha512-nIFUZIpGKDf9O9ttyRXpHFpKC+X3Y5mtshZONuEUYBomAKoM4y029Jr+uB1bHGPhNmK8YXHevDtKDOLmtRrp6g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.24.5"
|
||||
"@babel/helper-plugin-utils": "^7.24.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -1111,18 +1119,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-classes": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.5.tgz",
|
||||
"integrity": "sha512-gWkLP25DFj2dwe9Ck8uwMOpko4YsqyfZJrOmqqcegeDYEbp7rmn4U6UQZNj08UF6MaX39XenSpKRCvpDRBtZ7Q==",
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.24.1.tgz",
|
||||
"integrity": "sha512-ZTIe3W7UejJd3/3R4p7ScyyOoafetUShSf4kCqV0O7F/RiHxVj/wRaRnQlrGwflvcehNA8M42HkAiEDYZu2F1Q==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.22.5",
|
||||
"@babel/helper-compilation-targets": "^7.23.6",
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-function-name": "^7.23.0",
|
||||
"@babel/helper-plugin-utils": "^7.24.5",
|
||||
"@babel/helper-plugin-utils": "^7.24.0",
|
||||
"@babel/helper-replace-supers": "^7.24.1",
|
||||
"@babel/helper-split-export-declaration": "^7.24.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -1149,12 +1157,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-destructuring": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.5.tgz",
|
||||
"integrity": "sha512-SZuuLyfxvsm+Ah57I/i1HVjveBENYK9ue8MJ7qkc7ndoNjqquJiElzA7f5yaAXjyW2hKojosOTAQQRX50bPSVg==",
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.1.tgz",
|
||||
"integrity": "sha512-ow8jciWqNxR3RYbSNVuF4U2Jx130nwnBnhRw6N6h1bOejNkABmcI5X5oz29K4alWX7vf1C+o6gtKXikzRKkVdw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.24.5"
|
||||
"@babel/helper-plugin-utils": "^7.24.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -1485,15 +1493,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-object-rest-spread": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.5.tgz",
|
||||
"integrity": "sha512-7EauQHszLGM3ay7a161tTQH7fj+3vVM/gThlz5HpFtnygTxjrlvoeq7MPVA1Vy9Q555OB8SnAOsMkLShNkkrHA==",
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.1.tgz",
|
||||
"integrity": "sha512-XjD5f0YqOtebto4HGISLNfiNMTTs6tbkFf2TOqJlYKYmbo+mN9Dnpl4SRoofiziuOWMIyq3sZEUqLo3hLITFEA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-compilation-targets": "^7.23.6",
|
||||
"@babel/helper-plugin-utils": "^7.24.5",
|
||||
"@babel/helper-plugin-utils": "^7.24.0",
|
||||
"@babel/plugin-syntax-object-rest-spread": "^7.8.3",
|
||||
"@babel/plugin-transform-parameters": "^7.24.5"
|
||||
"@babel/plugin-transform-parameters": "^7.24.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -1535,12 +1543,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-optional-chaining": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.5.tgz",
|
||||
"integrity": "sha512-xWCkmwKT+ihmA6l7SSTpk8e4qQl/274iNbSKRRS8mpqFR32ksy36+a+LWY8OXCCEefF8WFlnOHVsaDI2231wBg==",
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.1.tgz",
|
||||
"integrity": "sha512-n03wmDt+987qXwAgcBlnUUivrZBPZ8z1plL0YvgQalLm+ZE5BMhGm94jhxXtA1wzv1Cu2aaOv1BM9vbVttrzSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.24.5",
|
||||
"@babel/helper-plugin-utils": "^7.24.0",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.22.5",
|
||||
"@babel/plugin-syntax-optional-chaining": "^7.8.3"
|
||||
},
|
||||
@ -1552,12 +1560,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-parameters": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.5.tgz",
|
||||
"integrity": "sha512-9Co00MqZ2aoky+4j2jhofErthm6QVLKbpQrvz20c3CH9KQCLHyNB+t2ya4/UrRpQGR+Wrwjg9foopoeSdnHOkA==",
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.1.tgz",
|
||||
"integrity": "sha512-8Jl6V24g+Uw5OGPeWNKrKqXPDw2YDjLc53ojwfMcKwlEoETKU9rU0mHUtcg9JntWI/QYzGAXNWEcVHZ+fR+XXg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.24.5"
|
||||
"@babel/helper-plugin-utils": "^7.24.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -1583,14 +1591,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-private-property-in-object": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.5.tgz",
|
||||
"integrity": "sha512-JM4MHZqnWR04jPMujQDTBVRnqxpLLpx2tkn7iPn+Hmsc0Gnb79yvRWOkvqFOx3Z7P7VxiRIR22c4eGSNj87OBQ==",
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.1.tgz",
|
||||
"integrity": "sha512-pTHxDVa0BpUbvAgX3Gat+7cSciXqUcY9j2VZKTbSB6+VQGpNgNO9ailxTGHSXlqOnX1Hcx1Enme2+yv7VqP9bg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.22.5",
|
||||
"@babel/helper-create-class-features-plugin": "^7.24.5",
|
||||
"@babel/helper-plugin-utils": "^7.24.5",
|
||||
"@babel/helper-create-class-features-plugin": "^7.24.1",
|
||||
"@babel/helper-plugin-utils": "^7.24.0",
|
||||
"@babel/plugin-syntax-private-property-in-object": "^7.14.5"
|
||||
},
|
||||
"engines": {
|
||||
@ -1728,12 +1736,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-transform-typeof-symbol": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.5.tgz",
|
||||
"integrity": "sha512-UTGnhYVZtTAjdwOTzT+sCyXmTn8AhaxOS/MjG9REclZ6ULHWF9KoCZur0HSGU7hk8PdBFKKbYe6+gqdXWz84Jg==",
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.1.tgz",
|
||||
"integrity": "sha512-CBfU4l/A+KruSUoW+vTQthwcAdwuqbpRNB8HQKlZABwHRhsdHZ9fezp4Sn18PeAlYxTNiLMlx4xUBV3AWfg1BA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-plugin-utils": "^7.24.5"
|
||||
"@babel/helper-plugin-utils": "^7.24.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -1824,16 +1832,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/preset-env": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.5.tgz",
|
||||
"integrity": "sha512-UGK2ifKtcC8i5AI4cH+sbLLuLc2ktYSFJgBAXorKAsHUZmrQ1q6aQ6i3BvU24wWs2AAKqQB6kq3N9V9Gw1HiMQ==",
|
||||
"version": "7.24.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.24.4.tgz",
|
||||
"integrity": "sha512-7Kl6cSmYkak0FK/FXjSEnLJ1N9T/WA2RkMhu17gZ/dsxKJUuTYNIylahPTzqpLyJN4WhDif8X0XK1R8Wsguo/A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/compat-data": "^7.24.4",
|
||||
"@babel/helper-compilation-targets": "^7.23.6",
|
||||
"@babel/helper-plugin-utils": "^7.24.5",
|
||||
"@babel/helper-plugin-utils": "^7.24.0",
|
||||
"@babel/helper-validator-option": "^7.23.5",
|
||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.5",
|
||||
"@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.24.4",
|
||||
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.24.1",
|
||||
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.24.1",
|
||||
"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.24.1",
|
||||
@ -1860,12 +1868,12 @@
|
||||
"@babel/plugin-transform-async-generator-functions": "^7.24.3",
|
||||
"@babel/plugin-transform-async-to-generator": "^7.24.1",
|
||||
"@babel/plugin-transform-block-scoped-functions": "^7.24.1",
|
||||
"@babel/plugin-transform-block-scoping": "^7.24.5",
|
||||
"@babel/plugin-transform-block-scoping": "^7.24.4",
|
||||
"@babel/plugin-transform-class-properties": "^7.24.1",
|
||||
"@babel/plugin-transform-class-static-block": "^7.24.4",
|
||||
"@babel/plugin-transform-classes": "^7.24.5",
|
||||
"@babel/plugin-transform-classes": "^7.24.1",
|
||||
"@babel/plugin-transform-computed-properties": "^7.24.1",
|
||||
"@babel/plugin-transform-destructuring": "^7.24.5",
|
||||
"@babel/plugin-transform-destructuring": "^7.24.1",
|
||||
"@babel/plugin-transform-dotall-regex": "^7.24.1",
|
||||
"@babel/plugin-transform-duplicate-keys": "^7.24.1",
|
||||
"@babel/plugin-transform-dynamic-import": "^7.24.1",
|
||||
@ -1885,13 +1893,13 @@
|
||||
"@babel/plugin-transform-new-target": "^7.24.1",
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "^7.24.1",
|
||||
"@babel/plugin-transform-numeric-separator": "^7.24.1",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.24.5",
|
||||
"@babel/plugin-transform-object-rest-spread": "^7.24.1",
|
||||
"@babel/plugin-transform-object-super": "^7.24.1",
|
||||
"@babel/plugin-transform-optional-catch-binding": "^7.24.1",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.24.5",
|
||||
"@babel/plugin-transform-parameters": "^7.24.5",
|
||||
"@babel/plugin-transform-optional-chaining": "^7.24.1",
|
||||
"@babel/plugin-transform-parameters": "^7.24.1",
|
||||
"@babel/plugin-transform-private-methods": "^7.24.1",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.24.5",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.24.1",
|
||||
"@babel/plugin-transform-property-literals": "^7.24.1",
|
||||
"@babel/plugin-transform-regenerator": "^7.24.1",
|
||||
"@babel/plugin-transform-reserved-words": "^7.24.1",
|
||||
@ -1899,7 +1907,7 @@
|
||||
"@babel/plugin-transform-spread": "^7.24.1",
|
||||
"@babel/plugin-transform-sticky-regex": "^7.24.1",
|
||||
"@babel/plugin-transform-template-literals": "^7.24.1",
|
||||
"@babel/plugin-transform-typeof-symbol": "^7.24.5",
|
||||
"@babel/plugin-transform-typeof-symbol": "^7.24.1",
|
||||
"@babel/plugin-transform-unicode-escapes": "^7.24.1",
|
||||
"@babel/plugin-transform-unicode-property-regex": "^7.24.1",
|
||||
"@babel/plugin-transform-unicode-regex": "^7.24.1",
|
||||
@ -2155,19 +2163,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/traverse": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz",
|
||||
"integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==",
|
||||
"version": "7.24.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.1.tgz",
|
||||
"integrity": "sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.24.2",
|
||||
"@babel/generator": "^7.24.5",
|
||||
"@babel/code-frame": "^7.24.1",
|
||||
"@babel/generator": "^7.24.1",
|
||||
"@babel/helper-environment-visitor": "^7.22.20",
|
||||
"@babel/helper-function-name": "^7.23.0",
|
||||
"@babel/helper-hoist-variables": "^7.22.5",
|
||||
"@babel/helper-split-export-declaration": "^7.24.5",
|
||||
"@babel/parser": "^7.24.5",
|
||||
"@babel/types": "^7.24.5",
|
||||
"@babel/helper-split-export-declaration": "^7.22.6",
|
||||
"@babel/parser": "^7.24.1",
|
||||
"@babel/types": "^7.24.0",
|
||||
"debug": "^4.3.1",
|
||||
"globals": "^11.1.0"
|
||||
},
|
||||
@ -2176,13 +2184,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.24.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz",
|
||||
"integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==",
|
||||
"version": "7.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.0.tgz",
|
||||
"integrity": "sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.24.1",
|
||||
"@babel/helper-validator-identifier": "^7.24.5",
|
||||
"@babel/helper-string-parser": "^7.23.4",
|
||||
"@babel/helper-validator-identifier": "^7.22.20",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -2270,9 +2279,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-python": {
|
||||
"version": "6.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.6.tgz",
|
||||
"integrity": "sha512-ai+01WfZhWqM92UqjnvorkxosZ2aq2u28kHvr+N3gu012XqY2CThD67JPMHnGceRfXPDBmn1HnyqowdpF57bNg==",
|
||||
"version": "6.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-python/-/lang-python-6.1.5.tgz",
|
||||
"integrity": "sha512-hCm+8X6wrnXJCGf+QhmFu1AXkdTVG7dHy0Ly6SI1N3SRPptaMvwX6oNQonOXOMPvmcjiB0xq342KAxX3BYpijw==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.3.2",
|
||||
"@codemirror/language": "^6.8.0",
|
||||
@ -2663,9 +2672,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@goauthentik/api": {
|
||||
"version": "2024.4.1-1714655911",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.4.1-1714655911.tgz",
|
||||
"integrity": "sha512-x7ViXuDh928e7B4dbQlOJXCtFnWJGGmOQcGI4IG6eWafUcq9+jgDnFrd0qqkDGcipqjKiY52B4RSdRNRxRsucA=="
|
||||
"version": "2024.4.1-1714149838",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.4.1-1714149838.tgz",
|
||||
"integrity": "sha512-Diat0nFTRm7gDb57d5KnKLYTumXKegT0ifpB2YdWSHioP9XQWdbIGQyL7+A1xcQdhVJo3vAbpiq0XI3J+gaHJg=="
|
||||
},
|
||||
"node_modules/@hcaptcha/types": {
|
||||
"version": "1.0.3",
|
||||
@ -4027,9 +4036,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz",
|
||||
"integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==",
|
||||
"version": "4.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.0.tgz",
|
||||
"integrity": "sha512-Oj6Tp0unMpGTBjvNwbSRv3DopMNLu+mjBzhKTt2zLbDJ/45fB1pltr/rqrO4bE95LzuYwhYn127pop+x/pzf5w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -4067,9 +4076,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz",
|
||||
"integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==",
|
||||
"version": "4.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.0.tgz",
|
||||
"integrity": "sha512-zL5rBFtJ+2EGnMRm2TqKjdjgFqlotSU+ZJEN37nV+fiD3I6Gy0dUh3jBWN0wSlcXVDEJYW7YBe+/2j0N9unb2w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -4135,9 +4144,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.17.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz",
|
||||
"integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==",
|
||||
"version": "4.17.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.0.tgz",
|
||||
"integrity": "sha512-v6eiam/1w3HUfU/ZjzIDodencqgrSqzlNuNtiwH7PFJHYSo1ezL0/UIzmS2lpSJF1ORNaplXeKHYmmdt81vV2g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -4203,83 +4212,83 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@sentry-internal/feedback": {
|
||||
"version": "7.113.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.113.0.tgz",
|
||||
"integrity": "sha512-eEmL8QXauUnM3FXGv0GT29RpL0Jo0pkn/uMu3aqjhQo7JKNqUGVYIUxJxiGWbVMbDXqPQ7L66bjjMS3FR1GM2g==",
|
||||
"version": "7.112.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/feedback/-/feedback-7.112.2.tgz",
|
||||
"integrity": "sha512-z+XP8BwB8B3pa+i8xqbrPsbtDWUFUS6wo+FJbmOYUqOusJJbVFDAhBoEdKoo5ZjOcsAZG7XR6cA9zrhJynIWBA==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "7.113.0",
|
||||
"@sentry/types": "7.113.0",
|
||||
"@sentry/utils": "7.113.0"
|
||||
"@sentry/core": "7.112.2",
|
||||
"@sentry/types": "7.112.2",
|
||||
"@sentry/utils": "7.112.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry-internal/replay-canvas": {
|
||||
"version": "7.113.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-7.113.0.tgz",
|
||||
"integrity": "sha512-K8uA42aobNF/BAXf14el15iSAi9fonLBUrjZi6nPDq7zaA8rPvfcTL797hwCbqkETz2zDf52Jz7I3WFCshDoUw==",
|
||||
"version": "7.112.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/replay-canvas/-/replay-canvas-7.112.2.tgz",
|
||||
"integrity": "sha512-BCCCxrZ1wJvN6La5gg1JJbKitAhJI5MATCnhtklsZbUcHkHB9iZoj19J65+P56gwssvHz5xh63AjNiITaetIRg==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "7.113.0",
|
||||
"@sentry/replay": "7.113.0",
|
||||
"@sentry/types": "7.113.0",
|
||||
"@sentry/utils": "7.113.0"
|
||||
"@sentry/core": "7.112.2",
|
||||
"@sentry/replay": "7.112.2",
|
||||
"@sentry/types": "7.112.2",
|
||||
"@sentry/utils": "7.112.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry-internal/tracing": {
|
||||
"version": "7.113.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.113.0.tgz",
|
||||
"integrity": "sha512-8MDnYENRMnEfQjvN4gkFYFaaBSiMFSU/6SQZfY9pLI3V105z6JQ4D0PGMAUVowXilwNZVpKNYohE7XByuhEC7Q==",
|
||||
"version": "7.112.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.112.2.tgz",
|
||||
"integrity": "sha512-fT1Y46J4lfXZkgFkb03YMNeIEs2xS6jdKMoukMFQfRfVvL9fSWEbTgZpHPd/YTT8r2i082XzjtAoQNgklm/0Hw==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "7.113.0",
|
||||
"@sentry/types": "7.113.0",
|
||||
"@sentry/utils": "7.113.0"
|
||||
"@sentry/core": "7.112.2",
|
||||
"@sentry/types": "7.112.2",
|
||||
"@sentry/utils": "7.112.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/browser": {
|
||||
"version": "7.113.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.113.0.tgz",
|
||||
"integrity": "sha512-PdyVHPOprwoxGfKGsP2dXDWO0MBDW1eyP7EZlfZvM1A4hjk6ZRNfCv30g+TrqX4hiZDKzyqN3+AdP7N/J2IX0Q==",
|
||||
"version": "7.112.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.112.2.tgz",
|
||||
"integrity": "sha512-wULwavCch84+d0bueAdFm6CDm1u0TfOjN91VgY+sj/vxUV2vesvDgI8zRZfmbZEor3MYA90zerkZT3ehZQKbYw==",
|
||||
"dependencies": {
|
||||
"@sentry-internal/feedback": "7.113.0",
|
||||
"@sentry-internal/replay-canvas": "7.113.0",
|
||||
"@sentry-internal/tracing": "7.113.0",
|
||||
"@sentry/core": "7.113.0",
|
||||
"@sentry/integrations": "7.113.0",
|
||||
"@sentry/replay": "7.113.0",
|
||||
"@sentry/types": "7.113.0",
|
||||
"@sentry/utils": "7.113.0"
|
||||
"@sentry-internal/feedback": "7.112.2",
|
||||
"@sentry-internal/replay-canvas": "7.112.2",
|
||||
"@sentry-internal/tracing": "7.112.2",
|
||||
"@sentry/core": "7.112.2",
|
||||
"@sentry/integrations": "7.112.2",
|
||||
"@sentry/replay": "7.112.2",
|
||||
"@sentry/types": "7.112.2",
|
||||
"@sentry/utils": "7.112.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/core": {
|
||||
"version": "7.113.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.113.0.tgz",
|
||||
"integrity": "sha512-pg75y3C5PG2+ur27A0Re37YTCEnX0liiEU7EOxWDGutH17x3ySwlYqLQmZsFZTSnvzv7t3MGsNZ8nT5O0746YA==",
|
||||
"version": "7.112.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.112.2.tgz",
|
||||
"integrity": "sha512-gHPCcJobbMkk0VR18J65WYQTt3ED4qC6X9lHKp27Ddt63E+MDGkG6lvYBU1LS8cV7CdyBGC1XXDCfor61GvLsA==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "7.113.0",
|
||||
"@sentry/utils": "7.113.0"
|
||||
"@sentry/types": "7.112.2",
|
||||
"@sentry/utils": "7.112.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/integrations": {
|
||||
"version": "7.113.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.113.0.tgz",
|
||||
"integrity": "sha512-w0sspGBQ+6+V/9bgCkpuM3CGwTYoQEVeTW6iNebFKbtN7MrM3XsGAM9I2cW1jVxFZROqCBPFtd2cs5n0j14aAg==",
|
||||
"version": "7.112.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.112.2.tgz",
|
||||
"integrity": "sha512-ioC2yyU6DqtLkdmWnm87oNvdn2+9oKctJeA4t+jkS6JaJ10DcezjCwiLscX4rhB9aWJV3IWF7Op0O6K3w0t2Hg==",
|
||||
"dependencies": {
|
||||
"@sentry/core": "7.113.0",
|
||||
"@sentry/types": "7.113.0",
|
||||
"@sentry/utils": "7.113.0",
|
||||
"@sentry/core": "7.112.2",
|
||||
"@sentry/types": "7.112.2",
|
||||
"@sentry/utils": "7.112.2",
|
||||
"localforage": "^1.8.1"
|
||||
},
|
||||
"engines": {
|
||||
@ -4287,33 +4296,33 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/replay": {
|
||||
"version": "7.113.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.113.0.tgz",
|
||||
"integrity": "sha512-UD2IaphOWKFdeGR+ZiaNAQ+wFsnwbJK6PNwcW6cHmWKv9COlKufpFt06lviaqFZ8jmNrM4H+r+R8YVTrqCuxgg==",
|
||||
"version": "7.112.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.112.2.tgz",
|
||||
"integrity": "sha512-7Ns/8D54WPsht1nlVj93Inf6rXyve2AZoibYN0YfcM2w3lI4NO51gPPHJU0lFEfMwzwK4ZBJWzOeW9098a+uEg==",
|
||||
"dependencies": {
|
||||
"@sentry-internal/tracing": "7.113.0",
|
||||
"@sentry/core": "7.113.0",
|
||||
"@sentry/types": "7.113.0",
|
||||
"@sentry/utils": "7.113.0"
|
||||
"@sentry-internal/tracing": "7.112.2",
|
||||
"@sentry/core": "7.112.2",
|
||||
"@sentry/types": "7.112.2",
|
||||
"@sentry/utils": "7.112.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/types": {
|
||||
"version": "7.113.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.113.0.tgz",
|
||||
"integrity": "sha512-PJbTbvkcPu/LuRwwXB1He8m+GjDDLKBtu3lWg5xOZaF5IRdXQU2xwtdXXsjge4PZR00tF7MO7X8ZynTgWbYaew==",
|
||||
"version": "7.112.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.112.2.tgz",
|
||||
"integrity": "sha512-kCMLt7yhY5OkWE9MeowlTNmox9pqDxcpvqguMo4BDNZM5+v9SEb1AauAdR78E1a1V8TyCzjBD7JDfXWhvpYBcQ==",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@sentry/utils": {
|
||||
"version": "7.113.0",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.113.0.tgz",
|
||||
"integrity": "sha512-nzKsErwmze1mmEsbW2AwL2oB+I5v6cDEJY4sdfLekA4qZbYZ8pV5iWza6IRl4XfzGTE1qpkZmEjPU9eyo0yvYw==",
|
||||
"version": "7.112.2",
|
||||
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.112.2.tgz",
|
||||
"integrity": "sha512-OjLh0hx0t1EcL4ZIjf+4svlmmP+tHUDGcr5qpFWH78tjmkPW4+cqPuZCZfHSuWcDdeiaXi8TnYoVRqDcJKK/eQ==",
|
||||
"dependencies": {
|
||||
"@sentry/types": "7.113.0"
|
||||
"@sentry/types": "7.112.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
|
@ -14,8 +14,8 @@
|
||||
"build": "run-s build-locales esbuild:build",
|
||||
"build-proxy": "run-s build-locales esbuild:build-proxy",
|
||||
"watch": "run-s build-locales esbuild:watch",
|
||||
"lint": "cross-env NODE_OPTIONS='--max_old_space_size=65536' eslint . --max-warnings 0 --fix",
|
||||
"lint:precommit": "cross-env NODE_OPTIONS='--max_old_space_size=65536' node scripts/eslint-precommit.mjs",
|
||||
"lint": "cross-env NODE_OPTIONS='--max_old_space_size=16384' eslint . --max-warnings 0 --fix",
|
||||
"lint:precommit": "cross-env NODE_OPTIONS='--max_old_space_size=16384' node scripts/eslint-precommit.mjs",
|
||||
"lint:spelling": "node scripts/check-spelling.mjs",
|
||||
"lit-analyse": "lit-analyzer src",
|
||||
"precommit": "npm-run-all --parallel tsc lit-analyse lint:spelling --sequential lint:precommit prettier",
|
||||
@ -32,13 +32,13 @@
|
||||
"dependencies": {
|
||||
"@codemirror/lang-html": "^6.4.9",
|
||||
"@codemirror/lang-javascript": "^6.2.2",
|
||||
"@codemirror/lang-python": "^6.1.6",
|
||||
"@codemirror/lang-python": "^6.1.5",
|
||||
"@codemirror/lang-xml": "^6.1.0",
|
||||
"@codemirror/legacy-modes": "^6.4.0",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@formatjs/intl-listformat": "^7.5.5",
|
||||
"@fortawesome/fontawesome-free": "^6.5.2",
|
||||
"@goauthentik/api": "^2024.4.1-1714655911",
|
||||
"@goauthentik/api": "^2024.4.1-1714149838",
|
||||
"@lit-labs/task": "^3.1.0",
|
||||
"@lit/context": "^1.1.1",
|
||||
"@lit/localize": "^0.12.1",
|
||||
@ -46,7 +46,7 @@
|
||||
"@open-wc/lit-helpers": "^0.7.0",
|
||||
"@patternfly/elements": "^3.0.1",
|
||||
"@patternfly/patternfly": "^4.224.2",
|
||||
"@sentry/browser": "^7.113.0",
|
||||
"@sentry/browser": "^7.112.2",
|
||||
"@webcomponents/webcomponentsjs": "^2.8.0",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.4.2",
|
||||
@ -68,13 +68,13 @@
|
||||
"yaml": "^2.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.24.5",
|
||||
"@babel/core": "^7.24.4",
|
||||
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||
"@babel/plugin-proposal-decorators": "^7.24.1",
|
||||
"@babel/plugin-transform-private-methods": "^7.24.1",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.24.5",
|
||||
"@babel/plugin-transform-private-property-in-object": "^7.24.1",
|
||||
"@babel/plugin-transform-runtime": "^7.24.3",
|
||||
"@babel/preset-env": "^7.24.5",
|
||||
"@babel/preset-env": "^7.24.4",
|
||||
"@babel/preset-typescript": "^7.24.1",
|
||||
"@hcaptcha/types": "^1.0.3",
|
||||
"@jeysal/storybook-addon-css-user-preferences": "^0.2.0",
|
||||
@ -129,9 +129,9 @@
|
||||
"@esbuild/darwin-arm64": "^0.20.1",
|
||||
"@esbuild/linux-amd64": "^0.18.11",
|
||||
"@esbuild/linux-arm64": "^0.20.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.17.2",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.17.2",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.17.2"
|
||||
"@rollup/rollup-darwin-arm64": "4.17.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.17.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.17.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
|
@ -29,9 +29,5 @@ export const signatureAlgorithmOptions = toOptions([
|
||||
["RSA-SHA256", SignatureAlgorithmEnum._200104XmldsigMorersaSha256, true],
|
||||
["RSA-SHA384", SignatureAlgorithmEnum._200104XmldsigMorersaSha384],
|
||||
["RSA-SHA512", SignatureAlgorithmEnum._200104XmldsigMorersaSha512],
|
||||
["ECDSA-SHA1", SignatureAlgorithmEnum._200104XmldsigMoreecdsaSha1],
|
||||
["ECDSA-SHA256", SignatureAlgorithmEnum._200104XmldsigMoreecdsaSha256],
|
||||
["ECDSA-SHA384", SignatureAlgorithmEnum._200104XmldsigMoreecdsaSha384],
|
||||
["ECDSA-SHA512", SignatureAlgorithmEnum._200104XmldsigMoreecdsaSha512],
|
||||
["DSA-SHA1", SignatureAlgorithmEnum._200009XmldsigdsaSha1],
|
||||
]);
|
||||
|
@ -6,12 +6,7 @@ import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
|
||||
import {
|
||||
AlgEnum,
|
||||
CertificateGenerationRequest,
|
||||
CertificateKeyPair,
|
||||
CryptoApi,
|
||||
} from "@goauthentik/api";
|
||||
import { CertificateGenerationRequest, CertificateKeyPair, CryptoApi } from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-crypto-certificate-generate-form")
|
||||
export class CertificateKeyPairForm extends Form<CertificateGenerationRequest> {
|
||||
@ -45,29 +40,6 @@ export class CertificateKeyPairForm extends Form<CertificateGenerationRequest> {
|
||||
?required=${true}
|
||||
>
|
||||
<input class="pf-c-form-control" type="number" value="365" />
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Private key Algorithm")}
|
||||
?required=${true}
|
||||
name="alg"
|
||||
>
|
||||
<ak-radio
|
||||
.options=${[
|
||||
{
|
||||
label: msg("RSA"),
|
||||
value: AlgEnum.Rsa,
|
||||
default: true,
|
||||
},
|
||||
{
|
||||
label: msg("ECDSA"),
|
||||
value: AlgEnum.Ecdsa,
|
||||
},
|
||||
]}
|
||||
>
|
||||
</ak-radio>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Algorithm used to generate the private key.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal> `;
|
||||
</ak-form-element-horizontal>`;
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,13 @@ import { TemplateResult, html } from "lit";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import { ExpressionPolicy, PoliciesApi } from "@goauthentik/api";
|
||||
import {
|
||||
CoreApi,
|
||||
CoreUsersListRequest,
|
||||
ExpressionPolicy,
|
||||
PoliciesApi,
|
||||
User,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-policy-expression-form")
|
||||
export class ExpressionPolicyForm extends BasePolicyForm<ExpressionPolicy> {
|
||||
@ -92,6 +98,39 @@ export class ExpressionPolicyForm extends BasePolicyForm<ExpressionPolicy> {
|
||||
</a>
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${msg("Execution user")} name="executionUser">
|
||||
<ak-search-select
|
||||
.fetchObjects=${async (query?: string): Promise<User[]> => {
|
||||
const args: CoreUsersListRequest = {
|
||||
ordering: "username",
|
||||
};
|
||||
if (query !== undefined) {
|
||||
args.search = query;
|
||||
}
|
||||
const users = await new CoreApi(DEFAULT_CONFIG).coreUsersList(args);
|
||||
return users.results;
|
||||
}}
|
||||
.renderElement=${(user: User): string => {
|
||||
return user.username;
|
||||
}}
|
||||
.renderDescription=${(user: User): TemplateResult => {
|
||||
return html`${user.name}`;
|
||||
}}
|
||||
.value=${(user: User | undefined): number | undefined => {
|
||||
return user?.pk;
|
||||
}}
|
||||
.selected=${(user: User): boolean => {
|
||||
return this.instance?.executionUser === user.pk;
|
||||
}}
|
||||
blankable
|
||||
>
|
||||
</ak-search-select>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Configure which user the bundled API client authenticates as. When left empty, the API client will inherit the permissions of the user triggering the policy execution.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
</div>
|
||||
</ak-form-group>`;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ export function docLink(path: string): string {
|
||||
const ak = globalAK();
|
||||
// Default case or beta build which should always point to latest
|
||||
if (!ak || ak.build !== "") {
|
||||
return `https://goauthentik.io${path}`;
|
||||
return `https://docs.goauthentik.io${path}`;
|
||||
}
|
||||
return `https://${ak.versionSubdomain}.goauthentik.io${path}`;
|
||||
}
|
||||
|
@ -12,8 +12,4 @@ export const authentikEnterpriseContext = createContext<LicenseSummary>(
|
||||
|
||||
export const authentikBrandContext = createContext<CurrentBrand>(Symbol("authentik-brand-context"));
|
||||
|
||||
export const authentikLocalStoreContext = createContext<unknown>(
|
||||
Symbol("authentik-local-store-context"),
|
||||
);
|
||||
|
||||
export default authentikConfigContext;
|
||||
|
@ -1,31 +0,0 @@
|
||||
type TryFn<T> = () => T;
|
||||
type CatchFn<T> = (error: unknown) => T;
|
||||
|
||||
type TryCatchArgs<T> = {
|
||||
tryFn: TryFn<T>;
|
||||
catchFn?: CatchFn<T>;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const isTryCatchArgs = <T>(t: any): t is TryCatchArgs<T> =>
|
||||
typeof t === "object" && "tryFn" in t && "catchFn" in t;
|
||||
|
||||
export function tryCatch<T>({ tryFn, catchFn }: TryCatchArgs<T>): T;
|
||||
export function tryCatch<T>(tryFn: TryFn<T>): T;
|
||||
export function tryCatch<T>(tryFn: TryFn<T>, catchFn: CatchFn<T>): T;
|
||||
export function tryCatch<T>(tryFn: TryFn<T> | TryCatchArgs<T>, catchFn?: CatchFn<T>): T {
|
||||
if (isTryCatchArgs(tryFn)) {
|
||||
catchFn = tryFn.catchFn;
|
||||
tryFn = tryFn.tryFn;
|
||||
}
|
||||
|
||||
if (catchFn === undefined) {
|
||||
catchFn = () => null as T;
|
||||
}
|
||||
|
||||
try {
|
||||
return tryFn();
|
||||
} catch (error) {
|
||||
return catchFn(error);
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ import "@goauthentik/elements/EmptyState";
|
||||
import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult, PropertyValues, TemplateResult, css, html, nothing } from "lit";
|
||||
import { CSSResult, TemplateResult, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
@ -115,16 +115,14 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage<
|
||||
});
|
||||
}
|
||||
|
||||
updated(changedProperties: PropertyValues<this>) {
|
||||
if (changedProperties.has("challenge") && this.challenge !== undefined) {
|
||||
// convert certain members of the PublicKeyCredentialCreateOptions into
|
||||
// byte arrays as expected by the spec.
|
||||
this.publicKeyCredentialCreateOptions = transformCredentialCreateOptions(
|
||||
this.challenge?.registration as PublicKeyCredentialCreationOptions,
|
||||
this.challenge?.registration.user.id,
|
||||
);
|
||||
this.registerWrapper();
|
||||
}
|
||||
firstUpdated(): void {
|
||||
// convert certain members of the PublicKeyCredentialCreateOptions into
|
||||
// byte arrays as expected by the spec.
|
||||
this.publicKeyCredentialCreateOptions = transformCredentialCreateOptions(
|
||||
this.challenge?.registration as PublicKeyCredentialCreationOptions,
|
||||
this.challenge?.registration.user.id,
|
||||
);
|
||||
this.registerWrapper();
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
|
@ -1,95 +0,0 @@
|
||||
import { LayoutType } from "@goauthentik/common/ui/config";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
import PFEmptyState from "@patternfly/patternfly/components/EmptyState/empty-state.css";
|
||||
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import type { Application } from "@goauthentik/api";
|
||||
|
||||
import type { AppGroupEntry, AppGroupList } from "./types";
|
||||
|
||||
type Pair = [string, string];
|
||||
|
||||
// prettier-ignore
|
||||
const LAYOUTS = new Map<string, [string, string]>([
|
||||
[
|
||||
"row",
|
||||
["pf-m-12-col", "pf-m-all-6-col-on-sm pf-m-all-4-col-on-md pf-m-all-5-col-on-lg pf-m-all-2-col-on-xl"]],
|
||||
[
|
||||
"2-column",
|
||||
["pf-m-6-col", "pf-m-all-12-col-on-sm pf-m-all-12-col-on-md pf-m-all-4-col-on-lg pf-m-all-4-col-on-xl"],
|
||||
],
|
||||
[
|
||||
"3-column",
|
||||
["pf-m-4-col", "pf-m-all-12-col-on-sm pf-m-all-12-col-on-md pf-m-all-6-col-on-lg pf-m-all-6-col-on-xl"],
|
||||
],
|
||||
]);
|
||||
|
||||
@customElement("ak-library-application-cards")
|
||||
export class LibraryPageApplicationCards extends AKElement {
|
||||
static get styles() {
|
||||
return [
|
||||
PFBase,
|
||||
PFEmptyState,
|
||||
PFContent,
|
||||
PFGrid,
|
||||
css`
|
||||
.app-group-header {
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
@property({ attribute: true })
|
||||
layout = "row" as LayoutType;
|
||||
|
||||
@property({ attribute: true })
|
||||
background: string | undefined = undefined;
|
||||
|
||||
@property({ attribute: true })
|
||||
selected = "";
|
||||
|
||||
@property({ attribute: false })
|
||||
apps: AppGroupList = [];
|
||||
|
||||
get currentLayout(): Pair {
|
||||
const layout = LAYOUTS.get(this.layout);
|
||||
if (!layout) {
|
||||
console.warn(`Unrecognized layout: ${this.layout || "-undefined-"}`);
|
||||
return LAYOUTS.get("row") as Pair;
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
render() {
|
||||
const [groupClass, groupGrid] = this.currentLayout;
|
||||
|
||||
return html`<div class="pf-l-grid pf-m-gutter">
|
||||
${this.apps.map(([group, apps]: AppGroupEntry) => {
|
||||
return html`<div class="pf-l-grid__item ${groupClass}">
|
||||
<div class="pf-c-content app-group-header">
|
||||
<h2>${group}</h2>
|
||||
</div>
|
||||
<div class="pf-l-grid pf-m-gutter ${groupGrid}">
|
||||
${apps.map((app: Application) => {
|
||||
return html`<ak-library-app
|
||||
class="pf-l-grid__item"
|
||||
.application=${app}
|
||||
background=${ifDefined(this.background)}
|
||||
?selected=${app.slug === this.selected}
|
||||
></ak-library-app>`;
|
||||
})}
|
||||
</div>
|
||||
</div> `;
|
||||
})}
|
||||
</div>`;
|
||||
}
|
||||
}
|
@ -1,34 +1,48 @@
|
||||
import { PFSize } from "@goauthentik/common/enums.js";
|
||||
import { LayoutType } from "@goauthentik/common/ui/config";
|
||||
import { AKElement, rootInterface } from "@goauthentik/elements/Base";
|
||||
import { UserInterface } from "@goauthentik/user/UserInterface";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { css, html, nothing } from "lit";
|
||||
import { css, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { classMap } from "lit/directives/class-map.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
import PFEmptyState from "@patternfly/patternfly/components/EmptyState/empty-state.css";
|
||||
import PFTable from "@patternfly/patternfly/components/Table/table.css";
|
||||
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import type { Application } from "@goauthentik/api";
|
||||
|
||||
import type { AppGroupEntry, AppGroupList } from "./types";
|
||||
|
||||
type Pair = [string, string];
|
||||
|
||||
// prettier-ignore
|
||||
const LAYOUTS = new Map<string, [string, string]>([
|
||||
[
|
||||
"row",
|
||||
["pf-m-12-col", "pf-m-all-6-col-on-sm pf-m-all-4-col-on-md pf-m-all-5-col-on-lg pf-m-all-2-col-on-xl"]],
|
||||
[
|
||||
"2-column",
|
||||
["pf-m-6-col", "pf-m-all-12-col-on-sm pf-m-all-12-col-on-md pf-m-all-4-col-on-lg pf-m-all-4-col-on-xl"],
|
||||
],
|
||||
[
|
||||
"3-column",
|
||||
["pf-m-4-col", "pf-m-all-12-col-on-sm pf-m-all-12-col-on-md pf-m-all-6-col-on-lg pf-m-all-6-col-on-xl"],
|
||||
],
|
||||
]);
|
||||
|
||||
@customElement("ak-library-application-list")
|
||||
export class LibraryPageApplicationList extends AKElement {
|
||||
static get styles() {
|
||||
return [
|
||||
PFBase,
|
||||
PFTable,
|
||||
PFButton,
|
||||
PFEmptyState,
|
||||
PFContent,
|
||||
PFGrid,
|
||||
css`
|
||||
.app-row a {
|
||||
font-weight: bold;
|
||||
.app-group-header {
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1.2em;
|
||||
}
|
||||
`,
|
||||
];
|
||||
@ -46,110 +60,36 @@ export class LibraryPageApplicationList extends AKElement {
|
||||
@property({ attribute: false })
|
||||
apps: AppGroupList = [];
|
||||
|
||||
expanded = new Set<string>();
|
||||
get currentLayout(): Pair {
|
||||
const layout = LAYOUTS.get(this.layout);
|
||||
if (!layout) {
|
||||
console.warn(`Unrecognized layout: ${this.layout || "-undefined-"}`);
|
||||
return LAYOUTS.get("row") as Pair;
|
||||
}
|
||||
return layout;
|
||||
}
|
||||
|
||||
render() {
|
||||
const me = rootInterface<UserInterface>()?.me;
|
||||
const canEdit =
|
||||
rootInterface()?.uiConfig?.enabledFeatures.applicationEdit && me?.user.isSuperuser;
|
||||
const [groupClass, groupGrid] = this.currentLayout;
|
||||
|
||||
const toggleExpansion = (pk: string) => {
|
||||
if (this.expanded.has(pk)) {
|
||||
this.expanded.delete(pk);
|
||||
} else {
|
||||
this.expanded.add(pk);
|
||||
}
|
||||
this.requestUpdate();
|
||||
};
|
||||
|
||||
const expandedClass = (pk: string) => ({
|
||||
"pf-m-expanded": this.expanded.has(pk),
|
||||
});
|
||||
|
||||
const renderExpansionCell = (app: Application) =>
|
||||
app.metaDescription
|
||||
? html`<td class="pf-c-table__toggle" role="cell">
|
||||
<button
|
||||
class="pf-c-button pf-m-plain ${classMap(expandedClass(app.pk))}"
|
||||
@click=${() => toggleExpansion(app.pk)}
|
||||
>
|
||||
<div class="pf-c-table__toggle-icon">
|
||||
<i class="fas fa-angle-down" aria-hidden="true"></i>
|
||||
</div>
|
||||
</button>
|
||||
</td>`
|
||||
: nothing;
|
||||
|
||||
const renderAppIcon = (app: Application) =>
|
||||
html`<a
|
||||
href="${ifDefined(app.launchUrl ?? "")}"
|
||||
target="${ifDefined(app.openInNewTab ? "_blank" : undefined)}"
|
||||
>
|
||||
<ak-app-icon size=${PFSize.Small} .app=${app}></ak-app-icon>
|
||||
</a>`;
|
||||
|
||||
const renderAppUrl = (app: Application) =>
|
||||
app.launchUrl === "goauthentik.io://providers/rac/launch"
|
||||
? html`<ak-library-rac-endpoint-launch .app=${app}>
|
||||
<a slot="trigger"> ${app.name} </a>
|
||||
</ak-library-rac-endpoint-launch>`
|
||||
: html`<a
|
||||
href="${ifDefined(app.launchUrl ?? "")}"
|
||||
target="${ifDefined(app.openInNewTab ? "_blank" : undefined)}"
|
||||
>${app.name}</a
|
||||
>`;
|
||||
|
||||
const renderAppDescription = (app: Application) =>
|
||||
app.metaDescription
|
||||
? html` <tr
|
||||
class="pf-c-table__expandable-row ${classMap(expandedClass(app.pk))}"
|
||||
role="row"
|
||||
>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td colspan="3">${app.metaDescription}</td>
|
||||
</tr>`
|
||||
: nothing;
|
||||
|
||||
const renderGroup = ([group, apps]: AppGroupEntry) => html`
|
||||
${group
|
||||
? html`<tr>
|
||||
<td colspan="5"><h2>${group}</h2></td>
|
||||
</tr>`
|
||||
: nothing}
|
||||
${apps.map(
|
||||
(app: Application) =>
|
||||
html`<tr>
|
||||
<td>${renderExpansionCell(app)}</td>
|
||||
<td>${renderAppIcon(app)}</td>
|
||||
<td class="app-row">${renderAppUrl(app)}</td>
|
||||
<td>${app.metaPublisher ?? ""}</td>
|
||||
<td>
|
||||
<a
|
||||
class="pf-c-button pf-m-control pf-m-small pf-m-block"
|
||||
href="/if/admin/#/core/applications/${app?.slug}"
|
||||
>
|
||||
<i class="fas fa-edit"></i> ${msg("Edit")}
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
${this.expanded.has(app.pk) ? renderAppDescription(app) : nothing} `,
|
||||
)}
|
||||
`;
|
||||
|
||||
return html`<table class="pf-c-table pf-m-compact pf-m-grid-sm pf-m-expandable">
|
||||
<thead>
|
||||
<tr role="row">
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th>${msg("Application")}</th>
|
||||
<th>${msg("Publisher")}</th>
|
||||
${canEdit ? html`<th>${msg("Edit")}</th>` : nothing}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
${this.apps.map(renderGroup)}
|
||||
</tbody>
|
||||
</table> `;
|
||||
return html`<div class="pf-l-grid pf-m-gutter">
|
||||
${this.apps.map(([group, apps]: AppGroupEntry) => {
|
||||
return html`<div class="pf-l-grid__item ${groupClass}">
|
||||
<div class="pf-c-content app-group-header">
|
||||
<h2>${group}</h2>
|
||||
</div>
|
||||
<div class="pf-l-grid pf-m-gutter ${groupGrid}">
|
||||
${apps.map((app: Application) => {
|
||||
return html`<ak-library-app
|
||||
class="pf-l-grid__item"
|
||||
.application=${app}
|
||||
background=${ifDefined(this.background)}
|
||||
?selected=${app.slug === this.selected}
|
||||
></ak-library-app>`;
|
||||
})}
|
||||
</div>
|
||||
</div> `;
|
||||
})}
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
@ -34,30 +34,6 @@ export const styles = [PFBase, PFDisplay, PFEmptyState, PFPage, PFContent].conca
|
||||
.pf-c-page__main-section {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
#library-page-title {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
#library-page-title h1 {
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
#library-page-title i {
|
||||
display: inline-block;
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
#library-page-title i[checked] {
|
||||
border: 3px solid var(--pf-global--BorderColor--100);
|
||||
}
|
||||
|
||||
#library-page-title a,
|
||||
#library-page-title i {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
`);
|
||||
|
||||
export default styles;
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { groupBy } from "@goauthentik/common/utils";
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import "@goauthentik/elements/EmptyState";
|
||||
import { tryCatch } from "@goauthentik/elements/utils/tryCatch.js";
|
||||
import "@goauthentik/user/LibraryApplication";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
@ -13,7 +12,6 @@ import styles from "./LibraryPageImpl.css";
|
||||
|
||||
import type { Application } from "@goauthentik/api";
|
||||
|
||||
import "./ApplicationCards";
|
||||
import "./ApplicationEmptyState";
|
||||
import "./ApplicationList";
|
||||
import "./ApplicationSearch";
|
||||
@ -22,8 +20,6 @@ import { SEARCH_ITEM_SELECTED, SEARCH_UPDATED } from "./constants";
|
||||
import { isCustomEvent, loading } from "./helpers";
|
||||
import type { AppGroupList, PageUIConfig } from "./types";
|
||||
|
||||
const VIEW_KEY = "ak-library-page-view-preference";
|
||||
|
||||
/**
|
||||
* List of Applications available
|
||||
*
|
||||
@ -57,9 +53,6 @@ export class LibraryPage extends AKElement {
|
||||
@state()
|
||||
filteredApps: Application[] = [];
|
||||
|
||||
@property()
|
||||
viewPreference?: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.searchUpdated = this.searchUpdated.bind(this);
|
||||
@ -73,12 +66,6 @@ export class LibraryPage extends AKElement {
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.filteredApps = this.apps;
|
||||
this.viewPreference =
|
||||
this.viewPreference ??
|
||||
tryCatch(
|
||||
() => window.localStorage.getItem(VIEW_KEY) ?? undefined,
|
||||
(e) => "card",
|
||||
);
|
||||
if (this.filteredApps === undefined) {
|
||||
throw new Error(
|
||||
"Application.results should never be undefined when passed to the Library Page.",
|
||||
@ -123,13 +110,6 @@ export class LibraryPage extends AKElement {
|
||||
return groupBy(this.filteredApps.filter(appHasLaunchUrl), (app) => app.group || "");
|
||||
}
|
||||
|
||||
setView(view: string) {
|
||||
this.viewPreference = view;
|
||||
tryCatch(() => {
|
||||
window.localStorage.setItem(VIEW_KEY, view);
|
||||
});
|
||||
}
|
||||
|
||||
renderEmptyState() {
|
||||
return html`<ak-library-application-empty-list
|
||||
?isadmin=${this.isAdmin}
|
||||
@ -142,17 +122,12 @@ export class LibraryPage extends AKElement {
|
||||
const layout = this.uiConfig.layout as string;
|
||||
const background = this.uiConfig.background;
|
||||
|
||||
return this.viewPreference === "list"
|
||||
? html`<ak-library-application-list
|
||||
selected="${ifDefined(selected)}"
|
||||
.apps=${apps}
|
||||
></ak-library-application-list>`
|
||||
: html`<ak-library-application-cards
|
||||
layout="${layout}"
|
||||
background="${ifDefined(background)}"
|
||||
selected="${ifDefined(selected)}"
|
||||
.apps=${apps}
|
||||
></ak-library-application-cards>`;
|
||||
return html`<ak-library-application-list
|
||||
layout="${layout}"
|
||||
background="${ifDefined(background)}"
|
||||
selected="${ifDefined(selected)}"
|
||||
.apps=${apps}
|
||||
></ak-library-application-list>`;
|
||||
}
|
||||
|
||||
renderSearch() {
|
||||
@ -162,15 +137,9 @@ export class LibraryPage extends AKElement {
|
||||
render() {
|
||||
return html`<main role="main" class="pf-c-page__main" tabindex="-1" id="main-content">
|
||||
<div class="pf-c-content header">
|
||||
<div id="library-page-title">
|
||||
<h1 role="heading" aria-level="1">${msg("My applications")}</h1>
|
||||
<a id="card-view" @click=${() => this.setView("card")}
|
||||
><i ?checked=${this.viewPreference === "card"} class="fas fa-th-large"></i
|
||||
></a>
|
||||
<a id="list-view" @click=${() => this.setView("list")}
|
||||
><i ?checked=${this.viewPreference === "list"} class="fas fa-list"></i
|
||||
></a>
|
||||
</div>
|
||||
<h1 role="heading" aria-level="1" id="library-page-title">
|
||||
${msg("My applications")}
|
||||
</h1>
|
||||
${this.uiConfig.searchEnabled ? this.renderSearch() : html``}
|
||||
</div>
|
||||
<section class="pf-c-page__main-section">
|
||||
|
@ -6543,18 +6543,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -6812,18 +6812,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -6460,18 +6460,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -8608,18 +8608,6 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -8398,18 +8398,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -8242,18 +8242,6 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -6664,18 +6664,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -8514,16 +8514,4 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body></file></xliff>
|
||||
|
@ -6453,18 +6453,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -5371,18 +5371,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -8613,18 +8613,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -6501,18 +6501,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -8359,18 +8359,6 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s7bfbf84a8ad5883f">
|
||||
<source>Internal Service accounts are created and managed by authentik and cannot be created manually.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sb0680e5f8782db1e">
|
||||
<source>Private key Algorithm</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sa03cbf19feebd249">
|
||||
<source>RSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sfbfccbd3e395c147">
|
||||
<source>ECDSA</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sebea299e52db4242">
|
||||
<source>Algorithm used to generate the private key.</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
@ -1,26 +1,5 @@
|
||||
# YAML Tags
|
||||
|
||||
To use the custom tags with your preferred editor, you must make the editor aware of the custom tags.
|
||||
|
||||
For VS Code, for example, add these entries to your `settings.json`:
|
||||
|
||||
```
|
||||
{
|
||||
"yaml.customTags": [
|
||||
"!KeyOf scalar",
|
||||
"!Env scalar",
|
||||
"!Find sequence",
|
||||
"!Context scalar",
|
||||
"!Format sequence",
|
||||
"!If sequence",
|
||||
"!Condition sequence",
|
||||
"!Enumerate sequence",
|
||||
"!Index scalar",
|
||||
"!Value scalar"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### `!KeyOf`
|
||||
|
||||
Example:
|
||||
|
@ -26,6 +26,10 @@ If you use locally installed databases, the PostgreSQL credentials given to auth
|
||||
Depending on your platform, some native dependencies might be required. On macOS, run `brew install libxmlsec1 libpq`, and for the CLI tools `brew install postgresql redis node@20`
|
||||
:::
|
||||
|
||||
:::info
|
||||
As long as [this issue](https://github.com/xmlsec/python-xmlsec/issues/252) about `libxmlsec-1.3.0` is open, a workaround is required to install a compatible version of `libxmlsec1` with brew, see [this comment](https://github.com/xmlsec/python-xmlsec/issues/254#issuecomment-1612005910).
|
||||
:::
|
||||
|
||||
1. Create an isolated Python environment. To create the environment and install dependencies, run the following commands in the same directory as your local authentik git repository:
|
||||
|
||||
```shell
|
||||
|
@ -13,14 +13,12 @@ Depending on what kind of device you want to require the user to have:
|
||||
#### WebAuthn
|
||||
|
||||
```python
|
||||
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
|
||||
return WebAuthnDevice.objects.filter(user=request.context['pending_user'], confirmed=True).exists()
|
||||
```
|
||||
|
||||
#### Duo
|
||||
|
||||
```python
|
||||
from authentik.stages.authenticator_duo.models import DuoDevice
|
||||
return DuoDevice.objects.filter(user=request.context['pending_user'], confirmed=True).exists()
|
||||
```
|
||||
|
||||
|
@ -11,7 +11,6 @@ Newly created users can be created as inactive and can be assigned to a selected
|
||||
Starting with authentik 2022.5, users can be added to dynamic groups. To do so, simply set `groups` in the flow plan context before this stage is run, for example
|
||||
|
||||
```python
|
||||
from authentik.core.models import Group
|
||||
group, _ = Group.objects.get_or_create(name="some-group")
|
||||
# ["groups"] *must* be set to an array of Group objects, names alone are not enough.
|
||||
request.context["flow_plan"].context["groups"] = [group]
|
||||
|
@ -50,8 +50,8 @@ Run the following commands to generate a password and secret key and write them
|
||||
|
||||
{/* prettier-ignore */}
|
||||
```shell
|
||||
echo "PG_PASS=$(openssl rand 36 | base64)" >> .env
|
||||
echo "AUTHENTIK_SECRET_KEY=$(openssl rand 60 | base64)" >> .env
|
||||
echo "PG_PASS=$(openssl rand -base64 36)" >> .env
|
||||
echo "AUTHENTIK_SECRET_KEY=$(openssl rand -base64 60)" >> .env
|
||||
```
|
||||
|
||||
:::info
|
||||
|
@ -23,7 +23,7 @@ Start by generating passwords for the database and cache. You can use either of
|
||||
|
||||
```shell
|
||||
pwgen -s 50 1
|
||||
openssl rand 60 | base64
|
||||
openssl rand -base64 36
|
||||
```
|
||||
|
||||
### Set Values
|
||||
|
@ -51,7 +51,7 @@ authentik already provides some default _scopes_ with _claims_ inside them, such
|
||||
|
||||
##### Custom profile scope
|
||||
|
||||
If you do not need storage quota, group information, or to manage already existing users in Nextcloud [skip to the next step](#provider-and-application).
|
||||
If you do not need storage quota or group information in Nextcloud [skip to the next step](#provider-and-application).
|
||||
|
||||
However, if you want to be able to control how much storage users in Nextcloud can use, as well as which users are recognized as Nextcloud administrators, you would need to make this information available in Nextcloud. To achieve this you would need to create a custom `profile` scope. To do so, go to _Customization_ -> _Property mappings_. Create a _Scope mapping_ with the following parameters:
|
||||
|
||||
@ -74,10 +74,7 @@ return {
|
||||
"name": request.user.name,
|
||||
"groups": groups,
|
||||
# To set a quota set the "nextcloud_quota" property in the user's attributes
|
||||
"quota": user.group_attributes().get("nextcloud_quota", None),
|
||||
# To connect an already existing user, set the "nextcloud_user_id" property in the
|
||||
# user's attributes to the username of the corresponding user on Nextcloud.
|
||||
"user_id": user.attributes.get("nextcloud_user_id", user.uuid),
|
||||
"quota": user.group_attributes().get("nextcloud_quota", None)
|
||||
}
|
||||
```
|
||||
|
||||
@ -87,13 +84,6 @@ To set a quota set the "nextcloud_quota" property in the user's attributes. This
|
||||
If set to a value, for example `1 GB`, user(s) will have 1GB storage quota. If the attribute is not set, user(s) will have unlimited storage.
|
||||
:::
|
||||
|
||||
:::note
|
||||
To connect to an already existing Nextcloud user, set the "nextcloud_user_id" property in the user's attributes. This must be set for each individual user.
|
||||
|
||||
The value of `nextcloud_user_id` must match the field `username` of the user on the Nextcloud instance. On Nextcloud, go to _Users_ to see the username of the user you are trying to connect to (Under user's `Display name`).
|
||||
If set to a value, for example `goauthentik`, it will try to connect to the `goauthentik` user on the Nextcloud instance. Otherwise, the user's UUID will be used.
|
||||
:::
|
||||
|
||||
##### Provider and Application
|
||||
|
||||
Create a provider for Nextcloud. In the Admin Interface, go to _Applications_ -> _Providers_. Create an _OAuth2/OpenID Provider_ with the following parameters:
|
||||
@ -139,7 +129,7 @@ Add a new provider using the `+` button and set the following values:
|
||||
:::
|
||||
- Scope: `email`, `profile` (you can safely omit `openid` if you prefer)
|
||||
- Attribute mappings:
|
||||
- User ID mapping: sub (or `user_id` if you need to connect to an already existing Nextcloud user)
|
||||
- User ID mapping: sub
|
||||
- Display name mapping: name
|
||||
- Email mapping: email
|
||||
- Quota mapping: quota (leave empty if you have skipped the [custom profile scope](#custom-profile-scope) section)
|
||||
@ -147,9 +137,9 @@ Add a new provider using the `+` button and set the following values:
|
||||
:::tip
|
||||
You need to enable the "Use group provisioning" checkmark to be able to write to this field
|
||||
:::
|
||||
- Use unique user ID: If you only have one provider you can deselect this if you prefer. This will affect your Federated Cloud ID, which you can check under _Personal settings_ -> _Sharing_ -> _Federated Cloud_. If the box is selected, nextcloud will pick a hashed value here (`437218904321784903214789023@nextcloud.instance` for example). Otherwise, it will use the mapped user ID (`<authentik's sub or user_id>@nextcloud.instance`).
|
||||
- Use unique user ID: If you only have one provider you can uncheck this if you prefer.
|
||||
:::tip
|
||||
To avoid your federated cloud id being a hash value, deselect **Use unique user ID** and use `user_id` in the **User ID mapping** field.
|
||||
To avoid your group assignment being a hash value, deselect **Use unique user ID**.
|
||||
:::
|
||||
|
||||
At this stage you should be able to login with SSO.
|
||||
|
@ -19,7 +19,7 @@ The following placeholders will be used:
|
||||
|
||||

|
||||
|
||||
3. Give the User a password, generated using for example `pwgen 64 1` or `openssl rand 36 | base64`.
|
||||
3. Give the User a password, generated using for example `pwgen 64 1` or `openssl rand -base64 36`.
|
||||
|
||||
4. Open the Delegation of Control Wizard by right-clicking the domain and selecting "All Tasks".
|
||||
|
||||
|
@ -16,7 +16,7 @@ The following placeholders will be used:
|
||||
|
||||
1. Log into FreeIPA.
|
||||
|
||||
2. Create a user in FreeIPA, matching your naming scheme. Provide a strong password, example generation methods: `pwgen 64 1` or `openssl rand 36 | base64`. After you are done click **Add and Edit**.
|
||||
2. Create a user in FreeIPA, matching your naming scheme. Provide a strong password, example generation methods: `pwgen 64 1` or `openssl rand -base64 36`. Once done click `Add and Edit`.
|
||||
|
||||

|
||||
|
||||
|
Reference in New Issue
Block a user