Merge branch 'main' into dev
* main: (25 commits) root: fix readme (#9178) enterprise: fix audit middleware import (#9177) web: bump @spotlightjs/spotlight from 1.2.16 to 1.2.17 in /web in the sentry group (#9162) web: bump API Client version (#9174) stages/authenticator_webauthn: add MDS support (#9114) website/integrations: Update Nextcloud OIDC secret size limitation (#9139) translate: Updates for file web/xliff/en.xlf in zh_CN (#9170) translate: Updates for file web/xliff/en.xlf in zh-Hans (#9171) web: bump the rollup group in /web with 3 updates (#9164) web: bump @codemirror/legacy-modes from 6.3.3 to 6.4.0 in /web (#9166) web: bump ts-pattern from 5.1.0 to 5.1.1 in /web (#9167) core: bump github.com/go-ldap/ldap/v3 from 3.4.6 to 3.4.7 (#9168) core, web: update translations (#9156) root: fix redis username in lifecycle (#9158) web: ak-checkbox-group for short, static, multi-select events (#9138) root: fix startup (#9151) core: Bump golang.org/x/oauth2 from 0.18.0 to 0.19.0 (#9146) core: Bump twilio from 9.0.3 to 9.0.4 (#9143) web: Bump country-flag-icons from 1.5.10 to 1.5.11 in /web (#9144) web: Bump typescript from 5.4.3 to 5.4.4 in /web (#9145) ...
This commit is contained in:
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@ -1 +1 @@
|
||||
github: [BeryJu]
|
||||
custom: https://goauthentik.io/pricing/
|
||||
|
||||
37
.github/workflows/gen-update-webauthn-mds.yml
vendored
Normal file
37
.github/workflows/gen-update-webauthn-mds.yml
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
name: authentik-gen-update-webauthn-mds
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '30 1 1,15 * *'
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- id: generate_token
|
||||
uses: tibdex/github-app-token@v2
|
||||
with:
|
||||
app_id: ${{ secrets.GH_APP_ID }}
|
||||
private_key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
- name: Setup authentik env
|
||||
uses: ./.github/actions/setup
|
||||
- run: poetry run ak update_webauthn_mds
|
||||
- uses: peter-evans/create-pull-request@v6
|
||||
id: cpr
|
||||
with:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
branch: update-fido-mds-client
|
||||
commit-message: "stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs"
|
||||
title: "stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs"
|
||||
body: "stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs"
|
||||
delete-branch: true
|
||||
signoff: true
|
||||
# ID from https://api.github.com/users/authentik-automation[bot]
|
||||
author: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
|
||||
- uses: peter-evans/enable-pull-request-automerge@v3
|
||||
with:
|
||||
token: ${{ steps.generate_token.outputs.token }}
|
||||
pull-request-number: ${{ steps.cpr.outputs.pull-request-number }}
|
||||
merge-method: squash
|
||||
2
Makefile
2
Makefile
@ -65,7 +65,7 @@ lint-fix: ## Lint and automatically fix errors in the python source code. Repor
|
||||
codespell -w $(CODESPELL_ARGS)
|
||||
|
||||
lint: ## Lint the python and golang sources
|
||||
bandit -r $(PY_SOURCES) -x node_modules
|
||||
bandit -r $(PY_SOURCES) -x web/node_modules -x tests/wdio/node_modules -x website/node_modules
|
||||
golangci-lint run -v
|
||||
|
||||
core-install:
|
||||
|
||||
@ -25,10 +25,10 @@ For bigger setups, there is a Helm Chart [here](https://github.com/goauthentik/h
|
||||
|
||||
## Screenshots
|
||||
|
||||
| Light | Dark |
|
||||
| ------------------------------------------------------ | ----------------------------------------------------- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
| Light | Dark |
|
||||
| ----------------------------------------------------------- | ---------------------------------------------------------- |
|
||||
|  |  |
|
||||
|  |  |
|
||||
|
||||
## Development
|
||||
|
||||
|
||||
@ -4,12 +4,14 @@ from json import dumps
|
||||
from typing import Any
|
||||
|
||||
from django.core.management.base import BaseCommand, no_translations
|
||||
from django.db.models import Model
|
||||
from drf_jsonschema_serializer.convert import field_to_converter
|
||||
from django.db.models import Model, fields
|
||||
from drf_jsonschema_serializer.convert import converter, field_to_converter
|
||||
from rest_framework.fields import Field, JSONField, UUIDField
|
||||
from rest_framework.relations import PrimaryKeyRelatedField
|
||||
from rest_framework.serializers import Serializer
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik import __version__
|
||||
from authentik.blueprints.v1.common import BlueprintEntryDesiredState
|
||||
from authentik.blueprints.v1.importer import SERIALIZER_CONTEXT_BLUEPRINT, is_model_allowed
|
||||
from authentik.blueprints.v1.meta.registry import BaseMetaModel, registry
|
||||
@ -18,6 +20,23 @@ from authentik.lib.models import SerializerModel
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
@converter
|
||||
class PrimaryKeyRelatedFieldConverter:
|
||||
"""Custom primary key field converter which is aware of non-integer based PKs
|
||||
|
||||
This is not an exhaustive fix for other non-int PKs, however in authentik we either
|
||||
use UUIDs or ints"""
|
||||
|
||||
field_class = PrimaryKeyRelatedField
|
||||
|
||||
def convert(self, field: PrimaryKeyRelatedField):
|
||||
model: Model = field.queryset.model
|
||||
pk_field = model._meta.pk
|
||||
if isinstance(pk_field, fields.UUIDField):
|
||||
return {"type": "string", "format": "uuid"}
|
||||
return {"type": "integer"}
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""Generate JSON Schema for blueprints"""
|
||||
|
||||
@ -29,7 +48,7 @@ class Command(BaseCommand):
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"$id": "https://goauthentik.io/blueprints/schema.json",
|
||||
"type": "object",
|
||||
"title": "authentik Blueprint schema",
|
||||
"title": f"authentik {__version__} Blueprint schema",
|
||||
"required": ["version", "entries"],
|
||||
"properties": {
|
||||
"version": {
|
||||
|
||||
@ -556,7 +556,11 @@ class BlueprintDumper(SafeDumper):
|
||||
|
||||
def factory(items):
|
||||
final_dict = dict(items)
|
||||
# Remove internal state variables
|
||||
final_dict.pop("_state", None)
|
||||
# Future-proof to only remove the ID if we don't set a value
|
||||
if "id" in final_dict and final_dict.get("id") is None:
|
||||
final_dict.pop("id")
|
||||
return final_dict
|
||||
|
||||
data = asdict(data, dict_factory=factory)
|
||||
|
||||
@ -51,6 +51,7 @@ from authentik.policies.models import Policy, PolicyBindingModel
|
||||
from authentik.policies.reputation.models import Reputation
|
||||
from authentik.providers.oauth2.models import AccessToken, AuthorizationCode, RefreshToken
|
||||
from authentik.providers.scim.models import SCIMGroup, SCIMUser
|
||||
from authentik.stages.authenticator_webauthn.models import WebAuthnDeviceType
|
||||
from authentik.tenants.models import Tenant
|
||||
|
||||
# Context set when the serializer is created in a blueprint context
|
||||
@ -95,6 +96,7 @@ def excluded_models() -> list[type[Model]]:
|
||||
AccessToken,
|
||||
RefreshToken,
|
||||
Reputation,
|
||||
WebAuthnDeviceType,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -13,9 +13,9 @@ class AuthentikEnterpriseAuditConfig(EnterpriseConfig):
|
||||
verbose_name = "authentik Enterprise.Audit"
|
||||
default = True
|
||||
|
||||
@EnterpriseConfig.reconcile_global
|
||||
def install_middleware(self):
|
||||
def ready(self):
|
||||
"""Install enterprise audit middleware"""
|
||||
orig_import = "authentik.events.middleware.AuditMiddleware"
|
||||
new_import = "authentik.enterprise.audit.middleware.EnterpriseAuditMiddleware"
|
||||
settings.MIDDLEWARE = [new_import if x == orig_import else x for x in settings.MIDDLEWARE]
|
||||
return super().ready()
|
||||
|
||||
18
authentik/enterprise/audit/tests.py
Normal file
18
authentik/enterprise/audit/tests.py
Normal file
@ -0,0 +1,18 @@
|
||||
from django.apps import apps
|
||||
from django.conf import settings
|
||||
from django.test import TestCase
|
||||
|
||||
|
||||
class TestEnterpriseAudit(TestCase):
|
||||
|
||||
def test_import(self):
|
||||
"""Ensure middleware is imported when app.ready is called"""
|
||||
# Revert import swap
|
||||
orig_import = "authentik.events.middleware.AuditMiddleware"
|
||||
new_import = "authentik.enterprise.audit.middleware.EnterpriseAuditMiddleware"
|
||||
settings.MIDDLEWARE = [orig_import if x == new_import else x for x in settings.MIDDLEWARE]
|
||||
# Re-call ready()
|
||||
apps.get_app_config("authentik_enterprise_audit").ready()
|
||||
self.assertIn(
|
||||
"authentik.enterprise.audit.middleware.EnterpriseAuditMiddleware", settings.MIDDLEWARE
|
||||
)
|
||||
@ -2,11 +2,11 @@
|
||||
|
||||
from uuid import uuid4
|
||||
|
||||
from django.conf import settings
|
||||
from requests.sessions import PreparedRequest, Session
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik import get_full_version
|
||||
from authentik.lib.config import CONFIG
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
@ -35,6 +35,6 @@ class DebugSession(Session):
|
||||
|
||||
def get_http_session() -> Session:
|
||||
"""Get a requests session with common headers"""
|
||||
session = DebugSession() if settings.DEBUG else Session()
|
||||
session = DebugSession() if CONFIG.get_bool("debug") else Session()
|
||||
session.headers["User-Agent"] = authentik_user_agent()
|
||||
return session
|
||||
|
||||
@ -4,7 +4,7 @@ from django.urls import reverse
|
||||
from guardian.shortcuts import assign_perm
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
from authentik.core.models import Group, UserTypes
|
||||
from authentik.core.models import Group, User, UserTypes
|
||||
from authentik.core.tests.utils import create_test_admin_user, create_test_user
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.rbac.api.rbac_assigned_by_users import UserAssignedObjectPermissionSerializer
|
||||
@ -26,6 +26,7 @@ class TestRBACUserAPI(APITestCase):
|
||||
|
||||
def test_filter_assigned(self):
|
||||
"""Test UserAssignedPermissionViewSet's filters"""
|
||||
User.objects.filter(username="akadmin").delete()
|
||||
inv = Invitation.objects.create(
|
||||
name=generate_id(),
|
||||
created_by=self.superuser,
|
||||
|
||||
@ -163,6 +163,7 @@ def validate_challenge_webauthn(data: dict, stage_view: StageView, user: User) -
|
||||
stage=stage_view.executor.current_stage,
|
||||
device=device,
|
||||
device_class=DeviceClasses.WEBAUTHN.value,
|
||||
device_type=device.device_type,
|
||||
)
|
||||
raise ValidationError("Assertion failed") from exc
|
||||
|
||||
|
||||
@ -398,5 +398,6 @@ class AuthenticatorValidateStageView(ChallengeStageView):
|
||||
self.executor.plan.context[PLAN_CONTEXT_METHOD] = "auth_webauthn_pwl"
|
||||
self.executor.plan.context[PLAN_CONTEXT_METHOD_ARGS] = {
|
||||
"device": webauthn_device,
|
||||
"device_type": webauthn_device.device_type,
|
||||
}
|
||||
return self.set_valid_mfa_cookie(response.device)
|
||||
|
||||
0
authentik/stages/authenticator_webauthn/aaguid.py
Normal file
0
authentik/stages/authenticator_webauthn/aaguid.py
Normal file
27
authentik/stages/authenticator_webauthn/api/device_types.py
Normal file
27
authentik/stages/authenticator_webauthn/api/device_types.py
Normal file
@ -0,0 +1,27 @@
|
||||
"""WebAuthnDeviceType API Views"""
|
||||
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from authentik.flows.api.stages import StageSerializer
|
||||
from authentik.stages.authenticator_webauthn.models import WebAuthnDeviceType
|
||||
|
||||
|
||||
class WebAuthnDeviceTypeSerializer(StageSerializer):
|
||||
"""WebAuthnDeviceType Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = WebAuthnDeviceType
|
||||
fields = [
|
||||
"aaguid",
|
||||
"description",
|
||||
]
|
||||
|
||||
|
||||
class WebAuthnDeviceTypeViewSet(ReadOnlyModelViewSet):
|
||||
"""WebAuthnDeviceType Viewset"""
|
||||
|
||||
queryset = WebAuthnDeviceType.objects.all()
|
||||
serializer_class = WebAuthnDeviceTypeSerializer
|
||||
filterset_fields = "__all__"
|
||||
ordering = ["description"]
|
||||
search_fields = ["description", "aaguid"]
|
||||
@ -1,4 +1,4 @@
|
||||
"""AuthenticateWebAuthnStage API Views"""
|
||||
"""AuthenticatorWebAuthnStage API Views"""
|
||||
|
||||
from django_filters.rest_framework.backends import DjangoFilterBackend
|
||||
from rest_framework import mixins
|
||||
@ -9,41 +9,18 @@ from rest_framework.viewsets import GenericViewSet, ModelViewSet
|
||||
|
||||
from authentik.api.authorization import OwnerFilter, OwnerPermissions
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.flows.api.stages import StageSerializer
|
||||
from authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage, WebAuthnDevice
|
||||
|
||||
|
||||
class AuthenticateWebAuthnStageSerializer(StageSerializer):
|
||||
"""AuthenticateWebAuthnStage Serializer"""
|
||||
|
||||
class Meta:
|
||||
model = AuthenticateWebAuthnStage
|
||||
fields = StageSerializer.Meta.fields + [
|
||||
"configure_flow",
|
||||
"friendly_name",
|
||||
"user_verification",
|
||||
"authenticator_attachment",
|
||||
"resident_key_requirement",
|
||||
]
|
||||
|
||||
|
||||
class AuthenticateWebAuthnStageViewSet(UsedByMixin, ModelViewSet):
|
||||
"""AuthenticateWebAuthnStage Viewset"""
|
||||
|
||||
queryset = AuthenticateWebAuthnStage.objects.all()
|
||||
serializer_class = AuthenticateWebAuthnStageSerializer
|
||||
filterset_fields = "__all__"
|
||||
ordering = ["name"]
|
||||
search_fields = ["name"]
|
||||
from authentik.stages.authenticator_webauthn.api.device_types import WebAuthnDeviceTypeSerializer
|
||||
from authentik.stages.authenticator_webauthn.models import WebAuthnDevice
|
||||
|
||||
|
||||
class WebAuthnDeviceSerializer(ModelSerializer):
|
||||
"""Serializer for WebAuthn authenticator devices"""
|
||||
|
||||
device_type = WebAuthnDeviceTypeSerializer(read_only=True, allow_null=True)
|
||||
|
||||
class Meta:
|
||||
model = WebAuthnDevice
|
||||
fields = ["pk", "name", "created_on"]
|
||||
depth = 2
|
||||
fields = ["pk", "name", "created_on", "device_type"]
|
||||
|
||||
|
||||
class WebAuthnDeviceViewSet(
|
||||
38
authentik/stages/authenticator_webauthn/api/stages.py
Normal file
38
authentik/stages/authenticator_webauthn/api/stages.py
Normal file
@ -0,0 +1,38 @@
|
||||
"""AuthenticatorWebAuthnStage API Views"""
|
||||
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
||||
from authentik.core.api.used_by import UsedByMixin
|
||||
from authentik.flows.api.stages import StageSerializer
|
||||
from authentik.stages.authenticator_webauthn.api.device_types import WebAuthnDeviceTypeSerializer
|
||||
from authentik.stages.authenticator_webauthn.models import AuthenticatorWebAuthnStage
|
||||
|
||||
|
||||
class AuthenticatorWebAuthnStageSerializer(StageSerializer):
|
||||
"""AuthenticatorWebAuthnStage Serializer"""
|
||||
|
||||
device_type_restrictions_obj = WebAuthnDeviceTypeSerializer(
|
||||
source="device_type_restrictions", many=True, read_only=True
|
||||
)
|
||||
|
||||
class Meta:
|
||||
model = AuthenticatorWebAuthnStage
|
||||
fields = StageSerializer.Meta.fields + [
|
||||
"configure_flow",
|
||||
"friendly_name",
|
||||
"user_verification",
|
||||
"authenticator_attachment",
|
||||
"resident_key_requirement",
|
||||
"device_type_restrictions",
|
||||
"device_type_restrictions_obj",
|
||||
]
|
||||
|
||||
|
||||
class AuthenticatorWebAuthnStageViewSet(UsedByMixin, ModelViewSet):
|
||||
"""AuthenticatorWebAuthnStage Viewset"""
|
||||
|
||||
queryset = AuthenticatorWebAuthnStage.objects.all()
|
||||
serializer_class = AuthenticatorWebAuthnStageSerializer
|
||||
filterset_fields = "__all__"
|
||||
ordering = ["name"]
|
||||
search_fields = ["name"]
|
||||
@ -1,11 +1,22 @@
|
||||
"""authentik webauthn app config"""
|
||||
|
||||
from django.apps import AppConfig
|
||||
from authentik.blueprints.apps import ManagedAppConfig
|
||||
|
||||
|
||||
class AuthentikStageAuthenticatorWebAuthnConfig(AppConfig):
|
||||
class AuthentikStageAuthenticatorWebAuthnConfig(ManagedAppConfig):
|
||||
"""authentik webauthn config"""
|
||||
|
||||
name = "authentik.stages.authenticator_webauthn"
|
||||
label = "authentik_stages_authenticator_webauthn"
|
||||
verbose_name = "authentik Stages.Authenticator.WebAuthn"
|
||||
default = True
|
||||
|
||||
@ManagedAppConfig.reconcile_tenant
|
||||
def webauthn_device_types(self):
|
||||
from authentik.stages.authenticator_webauthn.tasks import (
|
||||
webauthn_aaguid_import,
|
||||
webauthn_mds_import,
|
||||
)
|
||||
|
||||
webauthn_mds_import.delay()
|
||||
webauthn_aaguid_import.delay()
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
from django.core.management.base import BaseCommand
|
||||
from fido2.mds3 import parse_blob
|
||||
from structlog.stdlib import get_logger
|
||||
|
||||
from authentik.lib.utils.http import get_http_session
|
||||
from authentik.stages.authenticator_webauthn.tasks import AAGUID_BLOB_PATH, MDS_BLOB_PATH, mds_ca
|
||||
|
||||
MDS3_URL = "https://mds3.fidoalliance.org/"
|
||||
AAGUID_URL = "https://passkeydeveloper.github.io/passkey-authenticator-aaguids/aaguid.json"
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""Update FIDO Alliances' MDS3 blob and validate it."""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.logger = get_logger()
|
||||
|
||||
def update_fido_mds(self):
|
||||
with open(MDS_BLOB_PATH, "w", encoding="utf-8") as _raw_file:
|
||||
_raw_file.write(get_http_session().get(MDS3_URL).text)
|
||||
self.logger.info("Updated MDS blob")
|
||||
with open(MDS_BLOB_PATH, mode="rb") as _raw_blob:
|
||||
parse_blob(_raw_blob.read(), mds_ca())
|
||||
self.logger.info("Successfully validated MDS blob")
|
||||
|
||||
def update_passkey_aaguids(self):
|
||||
with open(AAGUID_BLOB_PATH, "w", encoding="utf-8") as _raw_file:
|
||||
_raw_file.write(get_http_session().get(AAGUID_URL).text)
|
||||
self.logger.info("Updated AAGUID blob")
|
||||
|
||||
def handle(self, *args, **options):
|
||||
self.update_fido_mds()
|
||||
self.update_passkey_aaguids()
|
||||
115
authentik/stages/authenticator_webauthn/mds/aaguid.json
Normal file
115
authentik/stages/authenticator_webauthn/mds/aaguid.json
Normal file
File diff suppressed because one or more lines are too long
1
authentik/stages/authenticator_webauthn/mds/blob.jwt
Normal file
1
authentik/stages/authenticator_webauthn/mds/blob.jwt
Normal file
File diff suppressed because one or more lines are too long
BIN
authentik/stages/authenticator_webauthn/mds/root-r3.crt
Normal file
BIN
authentik/stages/authenticator_webauthn/mds/root-r3.crt
Normal file
Binary file not shown.
@ -0,0 +1,45 @@
|
||||
# Generated by Django 5.0.3 on 2024-04-02 23:38
|
||||
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("authentik_flows", "0027_auto_20231028_1424"),
|
||||
("authentik_stages_authenticator_webauthn", "0009_authenticatewebauthnstage_friendly_name"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name="WebAuthnDeviceType",
|
||||
fields=[
|
||||
("aaguid", models.UUIDField(primary_key=True, serialize=False, unique=True)),
|
||||
("description", models.TextField()),
|
||||
("icon", models.TextField(null=True)),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "WebAuthn Device type",
|
||||
"verbose_name_plural": "WebAuthn Device types",
|
||||
},
|
||||
),
|
||||
migrations.RenameModel("AuthenticateWebAuthnStage", "AuthenticatorWebAuthnStage"),
|
||||
migrations.AddField(
|
||||
model_name="webauthndevice",
|
||||
name="device_type",
|
||||
field=models.ForeignKey(
|
||||
default=None,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_DEFAULT,
|
||||
to="authentik_stages_authenticator_webauthn.webauthndevicetype",
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="authenticatorwebauthnstage",
|
||||
name="device_type_restrictions",
|
||||
field=models.ManyToManyField(
|
||||
blank=True, to="authentik_stages_authenticator_webauthn.webauthndevicetype"
|
||||
),
|
||||
),
|
||||
]
|
||||
@ -14,6 +14,8 @@ from authentik.flows.models import ConfigurableStage, FriendlyNamedStage, Stage
|
||||
from authentik.lib.models import SerializerModel
|
||||
from authentik.stages.authenticator.models import Device
|
||||
|
||||
UNKNOWN_DEVICE_TYPE_AAGUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
class UserVerification(models.TextChoices):
|
||||
"""The degree to which the Relying Party wishes to verify a user's identity.
|
||||
@ -65,7 +67,7 @@ class AuthenticatorAttachment(models.TextChoices):
|
||||
CROSS_PLATFORM = "cross-platform"
|
||||
|
||||
|
||||
class AuthenticateWebAuthnStage(ConfigurableStage, FriendlyNamedStage, Stage):
|
||||
class AuthenticatorWebAuthnStage(ConfigurableStage, FriendlyNamedStage, Stage):
|
||||
"""WebAuthn stage"""
|
||||
|
||||
user_verification = models.TextField(
|
||||
@ -80,11 +82,15 @@ class AuthenticateWebAuthnStage(ConfigurableStage, FriendlyNamedStage, Stage):
|
||||
choices=AuthenticatorAttachment.choices, default=None, null=True
|
||||
)
|
||||
|
||||
device_type_restrictions = models.ManyToManyField("WebAuthnDeviceType", blank=True)
|
||||
|
||||
@property
|
||||
def serializer(self) -> type[BaseSerializer]:
|
||||
from authentik.stages.authenticator_webauthn.api import AuthenticateWebAuthnStageSerializer
|
||||
from authentik.stages.authenticator_webauthn.api.stages import (
|
||||
AuthenticatorWebAuthnStageSerializer,
|
||||
)
|
||||
|
||||
return AuthenticateWebAuthnStageSerializer
|
||||
return AuthenticatorWebAuthnStageSerializer
|
||||
|
||||
@property
|
||||
def view(self) -> type[View]:
|
||||
@ -126,6 +132,10 @@ class WebAuthnDevice(SerializerModel, Device):
|
||||
created_on = models.DateTimeField(auto_now_add=True)
|
||||
last_t = models.DateTimeField(default=now)
|
||||
|
||||
device_type = models.ForeignKey(
|
||||
"WebAuthnDeviceType", on_delete=models.SET_DEFAULT, null=True, default=None
|
||||
)
|
||||
|
||||
@property
|
||||
def descriptor(self) -> PublicKeyCredentialDescriptor:
|
||||
"""Get a publickeydescriptor for this device"""
|
||||
@ -139,7 +149,7 @@ class WebAuthnDevice(SerializerModel, Device):
|
||||
|
||||
@property
|
||||
def serializer(self) -> Serializer:
|
||||
from authentik.stages.authenticator_webauthn.api import WebAuthnDeviceSerializer
|
||||
from authentik.stages.authenticator_webauthn.api.devices import WebAuthnDeviceSerializer
|
||||
|
||||
return WebAuthnDeviceSerializer
|
||||
|
||||
@ -149,3 +159,27 @@ class WebAuthnDevice(SerializerModel, Device):
|
||||
class Meta:
|
||||
verbose_name = _("WebAuthn Device")
|
||||
verbose_name_plural = _("WebAuthn Devices")
|
||||
|
||||
|
||||
class WebAuthnDeviceType(SerializerModel):
|
||||
"""WebAuthn device type, used to restrict which device types are allowed"""
|
||||
|
||||
aaguid = models.UUIDField(primary_key=True, unique=True)
|
||||
|
||||
description = models.TextField()
|
||||
icon = models.TextField(null=True)
|
||||
|
||||
@property
|
||||
def serializer(self) -> Serializer:
|
||||
from authentik.stages.authenticator_webauthn.api.device_types import (
|
||||
WebAuthnDeviceTypeSerializer,
|
||||
)
|
||||
|
||||
return WebAuthnDeviceTypeSerializer
|
||||
|
||||
class Meta:
|
||||
verbose_name = _("WebAuthn Device type")
|
||||
verbose_name_plural = _("WebAuthn Device types")
|
||||
|
||||
def __str__(self) -> str:
|
||||
return f"WebAuthn device type {self.description} ({self.aaguid})"
|
||||
|
||||
@ -1,15 +1,18 @@
|
||||
"""WebAuthn stage"""
|
||||
|
||||
from json import loads
|
||||
from uuid import UUID
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.http.request import QueryDict
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from rest_framework.fields import CharField
|
||||
from rest_framework.serializers import ValidationError
|
||||
from webauthn import options_to_json
|
||||
from webauthn.helpers.bytes_to_base64url import bytes_to_base64url
|
||||
from webauthn.helpers.exceptions import InvalidRegistrationResponse
|
||||
from webauthn.helpers.structs import (
|
||||
AttestationConveyancePreference,
|
||||
AuthenticatorAttachment,
|
||||
AuthenticatorSelectionCriteria,
|
||||
PublicKeyCredentialCreationOptions,
|
||||
@ -31,7 +34,12 @@ from authentik.flows.challenge import (
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage, WebAuthnDevice
|
||||
from authentik.stages.authenticator_webauthn.models import (
|
||||
UNKNOWN_DEVICE_TYPE_AAGUID,
|
||||
AuthenticatorWebAuthnStage,
|
||||
WebAuthnDevice,
|
||||
WebAuthnDeviceType,
|
||||
)
|
||||
from authentik.stages.authenticator_webauthn.utils import get_origin, get_rp_id
|
||||
|
||||
SESSION_KEY_WEBAUTHN_CHALLENGE = "authentik/stages/authenticator_webauthn/challenge"
|
||||
@ -74,6 +82,30 @@ class AuthenticatorWebAuthnChallengeResponse(ChallengeResponse):
|
||||
if credential_id_exists:
|
||||
raise ValidationError("Credential ID already exists.")
|
||||
|
||||
stage: AuthenticatorWebAuthnStage = self.stage.executor.current_stage
|
||||
aaguid = registration.aaguid
|
||||
allowed_aaguids = stage.device_type_restrictions.values_list("aaguid", flat=True)
|
||||
if allowed_aaguids.exists():
|
||||
invalid_error = ValidationError(
|
||||
_(
|
||||
"Invalid device type. Contact your {brand} administrator for help.".format(
|
||||
brand=self.stage.request.brand.branding_title
|
||||
)
|
||||
)
|
||||
)
|
||||
# If there are any restrictions set and we didn't get an aaguid, invalid
|
||||
if not aaguid:
|
||||
raise invalid_error
|
||||
# If one of the restrictions is the "special" unknown device type UUID
|
||||
# but we do have a device type for the given aaguid, invalid
|
||||
if (
|
||||
UUID(UNKNOWN_DEVICE_TYPE_AAGUID) in allowed_aaguids
|
||||
and not WebAuthnDeviceType.objects.filter(aaguid=aaguid).exists()
|
||||
):
|
||||
return registration
|
||||
# Otherwise just check if the given aaguid is in the allowed aaguids
|
||||
if UUID(aaguid) not in allowed_aaguids:
|
||||
raise invalid_error
|
||||
return registration
|
||||
|
||||
|
||||
@ -85,7 +117,7 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
|
||||
def get_challenge(self, *args, **kwargs) -> Challenge:
|
||||
# clear session variables prior to starting a new registration
|
||||
self.request.session.pop(SESSION_KEY_WEBAUTHN_CHALLENGE, None)
|
||||
stage: AuthenticateWebAuthnStage = self.executor.current_stage
|
||||
stage: AuthenticatorWebAuthnStage = self.executor.current_stage
|
||||
user = self.get_pending_user()
|
||||
|
||||
# library accepts none so we store null in the database, but if there is a value
|
||||
@ -105,6 +137,7 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
|
||||
user_verification=UserVerificationRequirement(str(stage.user_verification)),
|
||||
authenticator_attachment=authenticator_attachment,
|
||||
),
|
||||
attestation=AttestationConveyancePreference.DIRECT,
|
||||
)
|
||||
|
||||
self.request.session[SESSION_KEY_WEBAUTHN_CHALLENGE] = registration_options.challenge
|
||||
@ -129,13 +162,20 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
|
||||
credential_id=bytes_to_base64url(webauthn_credential.credential_id)
|
||||
).first()
|
||||
if not existing_device:
|
||||
name = "WebAuthn Device"
|
||||
device_type = WebAuthnDeviceType.objects.filter(
|
||||
aaguid=webauthn_credential.aaguid
|
||||
).first()
|
||||
if device_type and device_type.description:
|
||||
name = device_type.description
|
||||
WebAuthnDevice.objects.create(
|
||||
name=name,
|
||||
user=self.get_pending_user(),
|
||||
public_key=bytes_to_base64url(webauthn_credential.credential_public_key),
|
||||
credential_id=bytes_to_base64url(webauthn_credential.credential_id),
|
||||
sign_count=webauthn_credential.sign_count,
|
||||
rp_id=get_rp_id(self.request),
|
||||
name="WebAuthn Device",
|
||||
device_type=device_type,
|
||||
)
|
||||
else:
|
||||
return self.executor.stage_invalid("Device with Credential ID already exists.")
|
||||
|
||||
69
authentik/stages/authenticator_webauthn/tasks.py
Normal file
69
authentik/stages/authenticator_webauthn/tasks.py
Normal file
@ -0,0 +1,69 @@
|
||||
"""MDS Helpers"""
|
||||
|
||||
from functools import lru_cache
|
||||
from json import loads
|
||||
from pathlib import Path
|
||||
|
||||
from django.core.cache import cache
|
||||
from django.db.transaction import atomic
|
||||
from fido2.mds3 import filter_revoked, parse_blob
|
||||
|
||||
from authentik.root.celery import CELERY_APP
|
||||
from authentik.stages.authenticator_webauthn.models import (
|
||||
UNKNOWN_DEVICE_TYPE_AAGUID,
|
||||
WebAuthnDeviceType,
|
||||
)
|
||||
|
||||
CACHE_KEY_MDS_NO = "goauthentik.io/stages/authenticator_webauthn/mds_no"
|
||||
AAGUID_BLOB_PATH = Path(__file__).parent / "mds" / "aaguid.json"
|
||||
MDS_BLOB_PATH = Path(__file__).parent / "mds" / "blob.jwt"
|
||||
MDS_CA_PATH = Path(__file__).parent / "mds" / "root-r3.crt"
|
||||
|
||||
|
||||
@lru_cache
|
||||
def mds_ca() -> bytes:
|
||||
"""Cache MDS Signature CA, GlobalSign Root CA - R3"""
|
||||
with open(MDS_CA_PATH, mode="rb") as _raw_root:
|
||||
return _raw_root.read()
|
||||
|
||||
|
||||
@CELERY_APP.task()
|
||||
def webauthn_mds_import(force=False):
|
||||
"""Background task to import FIDO Alliance MDS blob into database"""
|
||||
with open(MDS_BLOB_PATH, mode="rb") as _raw_blob:
|
||||
blob = parse_blob(_raw_blob.read(), mds_ca())
|
||||
with atomic():
|
||||
WebAuthnDeviceType.objects.update_or_create(
|
||||
aaguid=UNKNOWN_DEVICE_TYPE_AAGUID,
|
||||
defaults={
|
||||
"description": "authentik: Unknown devices",
|
||||
},
|
||||
)
|
||||
if cache.get(CACHE_KEY_MDS_NO) == blob.no and not force:
|
||||
return
|
||||
for entry in blob.entries:
|
||||
aaguid = entry.aaguid
|
||||
if not aaguid:
|
||||
continue
|
||||
if not filter_revoked(entry):
|
||||
WebAuthnDeviceType.objects.filter(aaguid=str(aaguid)).delete()
|
||||
continue
|
||||
metadata = entry.metadata_statement
|
||||
WebAuthnDeviceType.objects.update_or_create(
|
||||
aaguid=str(aaguid),
|
||||
defaults={"description": metadata.description, "icon": metadata.icon},
|
||||
)
|
||||
cache.set(CACHE_KEY_MDS_NO, blob.no)
|
||||
|
||||
|
||||
@CELERY_APP.task()
|
||||
def webauthn_aaguid_import(force=False):
|
||||
"""Background task to import AAGUIDs into database"""
|
||||
with open(AAGUID_BLOB_PATH, mode="rb") as _raw_blob:
|
||||
entries = loads(_raw_blob.read())
|
||||
with atomic():
|
||||
for aaguid, details in entries.items():
|
||||
WebAuthnDeviceType.objects.update_or_create(
|
||||
aaguid=str(aaguid),
|
||||
defaults={"description": details.get("name"), "icon": details.get("icon_light")},
|
||||
)
|
||||
@ -12,15 +12,24 @@ from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlan
|
||||
from authentik.flows.tests import FlowTestCase
|
||||
from authentik.flows.views.executor import SESSION_KEY_PLAN
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage, WebAuthnDevice
|
||||
from authentik.stages.authenticator_webauthn.models import (
|
||||
UNKNOWN_DEVICE_TYPE_AAGUID,
|
||||
AuthenticatorWebAuthnStage,
|
||||
WebAuthnDevice,
|
||||
WebAuthnDeviceType,
|
||||
)
|
||||
from authentik.stages.authenticator_webauthn.stage import SESSION_KEY_WEBAUTHN_CHALLENGE
|
||||
from authentik.stages.authenticator_webauthn.tasks import (
|
||||
webauthn_aaguid_import,
|
||||
webauthn_mds_import,
|
||||
)
|
||||
|
||||
|
||||
class TestAuthenticatorWebAuthnStage(FlowTestCase):
|
||||
"""Test WebAuthn API"""
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.stage = AuthenticateWebAuthnStage.objects.create(
|
||||
self.stage = AuthenticatorWebAuthnStage.objects.create(
|
||||
name=generate_id(),
|
||||
)
|
||||
self.flow = create_test_flow()
|
||||
@ -46,10 +55,6 @@ class TestAuthenticatorWebAuthnStage(FlowTestCase):
|
||||
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
|
||||
session = self.client.session
|
||||
session[SESSION_KEY_PLAN] = plan
|
||||
session[SESSION_KEY_WEBAUTHN_CHALLENGE] = b64decode(
|
||||
b"o90Yh1osqW3mjGift+6WclWOya5lcdff/G0mqueN3hChacMUz"
|
||||
b"V4mxiDafuQ0x0e1d/fcPai0fx/jMBZ8/nG2qQ=="
|
||||
)
|
||||
session.save()
|
||||
|
||||
response = self.client.get(
|
||||
@ -87,6 +92,218 @@ class TestAuthenticatorWebAuthnStage(FlowTestCase):
|
||||
"requireResidentKey": False,
|
||||
"userVerification": "preferred",
|
||||
},
|
||||
"attestation": "none",
|
||||
"attestation": "direct",
|
||||
},
|
||||
)
|
||||
|
||||
def test_register(self):
|
||||
"""Test registration"""
|
||||
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
|
||||
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
|
||||
session = self.client.session
|
||||
session[SESSION_KEY_PLAN] = plan
|
||||
session[SESSION_KEY_WEBAUTHN_CHALLENGE] = b64decode(
|
||||
b"03Xodi54gKsfnP5I9VFfhaGXVVE2NUyZpBBXns/JI+x6V9RY2Tw2QmxRJkhh7174EkRazUntIwjMVY9bFG60Lw=="
|
||||
)
|
||||
session.save()
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
data={
|
||||
"component": "ak-stage-authenticator-webauthn",
|
||||
"response": {
|
||||
"id": "kqnmrVLnDG-OwsSNHkihYZaNz5s",
|
||||
"rawId": "kqnmrVLnDG-OwsSNHkihYZaNz5s",
|
||||
"type": "public-key",
|
||||
"registrationClientExtensions": "{}",
|
||||
"response": {
|
||||
"clientDataJSON": (
|
||||
"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmd"
|
||||
"lIjoiMDNYb2RpNTRnS3NmblA1STlWRmZoYUdYVlZFMk5VeV"
|
||||
"pwQkJYbnNfSkkteDZWOVJZMlR3MlFteFJKa2hoNzE3NEVrU"
|
||||
"mF6VW50SXdqTVZZOWJGRzYwTHciLCJvcmlnaW4iOiJodHRw"
|
||||
"Oi8vbG9jYWxob3N0OjkwMDAiLCJjcm9zc09yaWdpbiI6ZmFsc2V9"
|
||||
),
|
||||
"attestationObject": (
|
||||
"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYSZYN5Yg"
|
||||
"OjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NdAAAAAPv8MA"
|
||||
"cVTk7MjAtuAgVX170AFJKp5q1S5wxvjsLEjR5IoWGWjc-bp"
|
||||
"QECAyYgASFYIKtcZHPumH37XHs0IM1v3pUBRIqHVV_SE-Lq"
|
||||
"2zpJAOVXIlgg74Fg_WdB0kuLYqCKbxogkEPaVtR_iR3IyQFIJAXBzds"
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
SERVER_NAME="localhost",
|
||||
SERVER_PORT="9000",
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
self.assertTrue(WebAuthnDevice.objects.filter(user=self.user).exists())
|
||||
|
||||
def test_register_restricted_device_type_deny(self):
|
||||
"""Test registration with restricted devices (fail)"""
|
||||
webauthn_mds_import(force=True)
|
||||
webauthn_aaguid_import()
|
||||
self.stage.device_type_restrictions.set(
|
||||
WebAuthnDeviceType.objects.filter(
|
||||
description="Android Authenticator with SafetyNet Attestation"
|
||||
)
|
||||
)
|
||||
|
||||
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
|
||||
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
|
||||
session = self.client.session
|
||||
session[SESSION_KEY_PLAN] = plan
|
||||
session[SESSION_KEY_WEBAUTHN_CHALLENGE] = b64decode(
|
||||
b"03Xodi54gKsfnP5I9VFfhaGXVVE2NUyZpBBXns/JI+x6V9RY2Tw2QmxRJkhh7174EkRazUntIwjMVY9bFG60Lw=="
|
||||
)
|
||||
session.save()
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
data={
|
||||
"component": "ak-stage-authenticator-webauthn",
|
||||
"response": {
|
||||
"id": "kqnmrVLnDG-OwsSNHkihYZaNz5s",
|
||||
"rawId": "kqnmrVLnDG-OwsSNHkihYZaNz5s",
|
||||
"type": "public-key",
|
||||
"registrationClientExtensions": "{}",
|
||||
"response": {
|
||||
"clientDataJSON": (
|
||||
"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmd"
|
||||
"lIjoiMDNYb2RpNTRnS3NmblA1STlWRmZoYUdYVlZFMk5VeV"
|
||||
"pwQkJYbnNfSkkteDZWOVJZMlR3MlFteFJKa2hoNzE3NEVrU"
|
||||
"mF6VW50SXdqTVZZOWJGRzYwTHciLCJvcmlnaW4iOiJodHRw"
|
||||
"Oi8vbG9jYWxob3N0OjkwMDAiLCJjcm9zc09yaWdpbiI6ZmFsc2V9"
|
||||
),
|
||||
"attestationObject": (
|
||||
"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYSZYN5Yg"
|
||||
"OjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NdAAAAAPv8MA"
|
||||
"cVTk7MjAtuAgVX170AFJKp5q1S5wxvjsLEjR5IoWGWjc-bp"
|
||||
"QECAyYgASFYIKtcZHPumH37XHs0IM1v3pUBRIqHVV_SE-Lq"
|
||||
"2zpJAOVXIlgg74Fg_WdB0kuLYqCKbxogkEPaVtR_iR3IyQFIJAXBzds"
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
SERVER_NAME="localhost",
|
||||
SERVER_PORT="9000",
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
flow=self.flow,
|
||||
component="ak-stage-authenticator-webauthn",
|
||||
response_errors={
|
||||
"response": [
|
||||
{
|
||||
"string": (
|
||||
"Invalid device type. Contact your authentik administrator for help."
|
||||
),
|
||||
"code": "invalid",
|
||||
}
|
||||
]
|
||||
},
|
||||
)
|
||||
self.assertFalse(WebAuthnDevice.objects.filter(user=self.user).exists())
|
||||
|
||||
def test_register_restricted_device_type_allow(self):
|
||||
"""Test registration with restricted devices (allow)"""
|
||||
webauthn_mds_import(force=True)
|
||||
webauthn_aaguid_import()
|
||||
self.stage.device_type_restrictions.set(
|
||||
WebAuthnDeviceType.objects.filter(description="iCloud Keychain")
|
||||
)
|
||||
|
||||
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
|
||||
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
|
||||
session = self.client.session
|
||||
session[SESSION_KEY_PLAN] = plan
|
||||
session[SESSION_KEY_WEBAUTHN_CHALLENGE] = b64decode(
|
||||
b"03Xodi54gKsfnP5I9VFfhaGXVVE2NUyZpBBXns/JI+x6V9RY2Tw2QmxRJkhh7174EkRazUntIwjMVY9bFG60Lw=="
|
||||
)
|
||||
session.save()
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
data={
|
||||
"component": "ak-stage-authenticator-webauthn",
|
||||
"response": {
|
||||
"id": "kqnmrVLnDG-OwsSNHkihYZaNz5s",
|
||||
"rawId": "kqnmrVLnDG-OwsSNHkihYZaNz5s",
|
||||
"type": "public-key",
|
||||
"registrationClientExtensions": "{}",
|
||||
"response": {
|
||||
"clientDataJSON": (
|
||||
"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmd"
|
||||
"lIjoiMDNYb2RpNTRnS3NmblA1STlWRmZoYUdYVlZFMk5VeV"
|
||||
"pwQkJYbnNfSkkteDZWOVJZMlR3MlFteFJKa2hoNzE3NEVrU"
|
||||
"mF6VW50SXdqTVZZOWJGRzYwTHciLCJvcmlnaW4iOiJodHRw"
|
||||
"Oi8vbG9jYWxob3N0OjkwMDAiLCJjcm9zc09yaWdpbiI6ZmFsc2V9"
|
||||
),
|
||||
"attestationObject": (
|
||||
"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYSZYN5Yg"
|
||||
"OjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NdAAAAAPv8MA"
|
||||
"cVTk7MjAtuAgVX170AFJKp5q1S5wxvjsLEjR5IoWGWjc-bp"
|
||||
"QECAyYgASFYIKtcZHPumH37XHs0IM1v3pUBRIqHVV_SE-Lq"
|
||||
"2zpJAOVXIlgg74Fg_WdB0kuLYqCKbxogkEPaVtR_iR3IyQFIJAXBzds"
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
SERVER_NAME="localhost",
|
||||
SERVER_PORT="9000",
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
self.assertTrue(WebAuthnDevice.objects.filter(user=self.user).exists())
|
||||
|
||||
def test_register_restricted_device_type_allow_unknown(self):
|
||||
"""Test registration with restricted devices (allow, unknown device type)"""
|
||||
webauthn_mds_import(force=True)
|
||||
webauthn_aaguid_import()
|
||||
WebAuthnDeviceType.objects.filter(description="iCloud Keychain").delete()
|
||||
self.stage.device_type_restrictions.set(
|
||||
WebAuthnDeviceType.objects.filter(aaguid=UNKNOWN_DEVICE_TYPE_AAGUID)
|
||||
)
|
||||
|
||||
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
|
||||
plan.context[PLAN_CONTEXT_PENDING_USER] = self.user
|
||||
session = self.client.session
|
||||
session[SESSION_KEY_PLAN] = plan
|
||||
session[SESSION_KEY_WEBAUTHN_CHALLENGE] = b64decode(
|
||||
b"03Xodi54gKsfnP5I9VFfhaGXVVE2NUyZpBBXns/JI+x6V9RY2Tw2QmxRJkhh7174EkRazUntIwjMVY9bFG60Lw=="
|
||||
)
|
||||
session.save()
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
data={
|
||||
"component": "ak-stage-authenticator-webauthn",
|
||||
"response": {
|
||||
"id": "kqnmrVLnDG-OwsSNHkihYZaNz5s",
|
||||
"rawId": "kqnmrVLnDG-OwsSNHkihYZaNz5s",
|
||||
"type": "public-key",
|
||||
"registrationClientExtensions": "{}",
|
||||
"response": {
|
||||
"clientDataJSON": (
|
||||
"eyJ0eXBlIjoid2ViYXV0aG4uY3JlYXRlIiwiY2hhbGxlbmd"
|
||||
"lIjoiMDNYb2RpNTRnS3NmblA1STlWRmZoYUdYVlZFMk5VeV"
|
||||
"pwQkJYbnNfSkkteDZWOVJZMlR3MlFteFJKa2hoNzE3NEVrU"
|
||||
"mF6VW50SXdqTVZZOWJGRzYwTHciLCJvcmlnaW4iOiJodHRw"
|
||||
"Oi8vbG9jYWxob3N0OjkwMDAiLCJjcm9zc09yaWdpbiI6ZmFsc2V9"
|
||||
),
|
||||
"attestationObject": (
|
||||
"o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YViYSZYN5Yg"
|
||||
"OjGh0NBcPZHZgW4_krrmihjLHmVzzuoMdl2NdAAAAAPv8MA"
|
||||
"cVTk7MjAtuAgVX170AFJKp5q1S5wxvjsLEjR5IoWGWjc-bp"
|
||||
"QECAyYgASFYIKtcZHPumH37XHs0IM1v3pUBRIqHVV_SE-Lq"
|
||||
"2zpJAOVXIlgg74Fg_WdB0kuLYqCKbxogkEPaVtR_iR3IyQFIJAXBzds"
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
SERVER_NAME="localhost",
|
||||
SERVER_PORT="9000",
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
print(response.content)
|
||||
self.assertStageRedirects(response, reverse("authentik_core:root-redirect"))
|
||||
self.assertTrue(WebAuthnDevice.objects.filter(user=self.user).exists())
|
||||
|
||||
@ -1,13 +1,15 @@
|
||||
"""API URLs"""
|
||||
|
||||
from authentik.stages.authenticator_webauthn.api import (
|
||||
AuthenticateWebAuthnStageViewSet,
|
||||
from authentik.stages.authenticator_webauthn.api.device_types import WebAuthnDeviceTypeViewSet
|
||||
from authentik.stages.authenticator_webauthn.api.devices import (
|
||||
WebAuthnAdminDeviceViewSet,
|
||||
WebAuthnDeviceViewSet,
|
||||
)
|
||||
from authentik.stages.authenticator_webauthn.api.stages import AuthenticatorWebAuthnStageViewSet
|
||||
|
||||
api_urlpatterns = [
|
||||
("stages/authenticator/webauthn", AuthenticateWebAuthnStageViewSet),
|
||||
("stages/authenticator/webauthn", AuthenticatorWebAuthnStageViewSet),
|
||||
("stages/authenticator/webauthn_device_types", WebAuthnDeviceTypeViewSet),
|
||||
(
|
||||
"authenticators/admin/webauthn",
|
||||
WebAuthnAdminDeviceViewSet,
|
||||
|
||||
@ -17,7 +17,7 @@ entries:
|
||||
identifiers:
|
||||
name: default-authenticator-webauthn-setup
|
||||
id: default-authenticator-webauthn-setup
|
||||
model: authentik_stages_authenticator_webauthn.authenticatewebauthnstage
|
||||
model: authentik_stages_authenticator_webauthn.authenticatorwebauthnstage
|
||||
- identifiers:
|
||||
order: 0
|
||||
stage: !KeyOf default-authenticator-webauthn-setup
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"$schema": "http://json-schema.org/draft-07/schema",
|
||||
"$id": "https://goauthentik.io/blueprints/schema.json",
|
||||
"type": "object",
|
||||
"title": "authentik Blueprint schema",
|
||||
"title": "authentik 2024.2.2 Blueprint schema",
|
||||
"required": [
|
||||
"version",
|
||||
"entries"
|
||||
@ -1566,7 +1566,7 @@
|
||||
],
|
||||
"properties": {
|
||||
"model": {
|
||||
"const": "authentik_stages_authenticator_webauthn.authenticatewebauthnstage"
|
||||
"const": "authentik_stages_authenticator_webauthn.authenticatorwebauthnstage"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
@ -1588,10 +1588,10 @@
|
||||
}
|
||||
},
|
||||
"attrs": {
|
||||
"$ref": "#/$defs/model_authentik_stages_authenticator_webauthn.authenticatewebauthnstage"
|
||||
"$ref": "#/$defs/model_authentik_stages_authenticator_webauthn.authenticatorwebauthnstage"
|
||||
},
|
||||
"identifiers": {
|
||||
"$ref": "#/$defs/model_authentik_stages_authenticator_webauthn.authenticatewebauthnstage"
|
||||
"$ref": "#/$defs/model_authentik_stages_authenticator_webauthn.authenticatorwebauthnstage"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -2872,7 +2872,8 @@
|
||||
"title": "Is primary"
|
||||
},
|
||||
"tenant": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Tenant"
|
||||
}
|
||||
},
|
||||
@ -2994,11 +2995,13 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"target": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Target"
|
||||
},
|
||||
"stage": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Stage"
|
||||
},
|
||||
"evaluate_on_plan": {
|
||||
@ -3058,12 +3061,14 @@
|
||||
"description": "Can be in the format of 'unix://<path>' when connecting to a local docker daemon, or 'https://<hostname>:2376' when connecting to a remote system."
|
||||
},
|
||||
"tls_verification": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Tls verification",
|
||||
"description": "CA which the endpoint's Certificate is verified against. Can be left empty for no validation."
|
||||
},
|
||||
"tls_authentication": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Tls authentication",
|
||||
"description": "Certificate/Key used for authentication. Can be left empty for no authentication."
|
||||
}
|
||||
@ -3123,7 +3128,8 @@
|
||||
"title": "Providers"
|
||||
},
|
||||
"service_connection": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Service connection",
|
||||
"description": "Select Service-Connection authentik should use to manage this outpost. Leave empty if authentik should not handle the deployment."
|
||||
},
|
||||
@ -3348,7 +3354,7 @@
|
||||
"authentik_stages_authenticator_totp.authenticatortotpstage",
|
||||
"authentik_stages_authenticator_totp.totpdevice",
|
||||
"authentik_stages_authenticator_validate.authenticatorvalidatestage",
|
||||
"authentik_stages_authenticator_webauthn.authenticatewebauthnstage",
|
||||
"authentik_stages_authenticator_webauthn.authenticatorwebauthnstage",
|
||||
"authentik_stages_authenticator_webauthn.webauthndevice",
|
||||
"authentik_stages_captcha.captchastage",
|
||||
"authentik_stages_consent.consentstage",
|
||||
@ -3557,11 +3563,13 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"policy": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Policy"
|
||||
},
|
||||
"group": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Group"
|
||||
},
|
||||
"user": {
|
||||
@ -3569,7 +3577,8 @@
|
||||
"title": "User"
|
||||
},
|
||||
"target": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Target"
|
||||
},
|
||||
"negate": {
|
||||
@ -3611,19 +3620,22 @@
|
||||
"title": "Name"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||
},
|
||||
"authorization_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authorization flow",
|
||||
"description": "Flow used when authorizing this provider."
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
@ -3634,12 +3646,14 @@
|
||||
"description": "DN under which objects are accessible."
|
||||
},
|
||||
"search_group": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Search group",
|
||||
"description": "Users in this group can do search queries. If not set, every user can execute search queries."
|
||||
},
|
||||
"certificate": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Certificate"
|
||||
},
|
||||
"tls_server_name": {
|
||||
@ -3729,19 +3743,22 @@
|
||||
"title": "Name"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||
},
|
||||
"authorization_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authorization flow",
|
||||
"description": "Flow used when authorizing this provider."
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
@ -3789,7 +3806,8 @@
|
||||
"description": "Include User claims from scopes in the id_token, for applications that don't access the userinfo endpoint."
|
||||
},
|
||||
"signing_key": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Signing Key",
|
||||
"description": "Key used to sign the tokens. Only required when JWT Algorithm is set to RS256."
|
||||
},
|
||||
@ -3840,19 +3858,22 @@
|
||||
"title": "Name"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||
},
|
||||
"authorization_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authorization flow",
|
||||
"description": "Flow used when authorizing this provider."
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
@ -3871,7 +3892,8 @@
|
||||
"description": "Validate SSL Certificates of upstream servers"
|
||||
},
|
||||
"certificate": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Certificate"
|
||||
},
|
||||
"skip_path_regex": {
|
||||
@ -3945,19 +3967,22 @@
|
||||
"title": "Name"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||
},
|
||||
"authorization_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authorization flow",
|
||||
"description": "Flow used when authorizing this provider."
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
@ -3990,19 +4015,22 @@
|
||||
"title": "Name"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||
},
|
||||
"authorization_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authorization flow",
|
||||
"description": "Flow used when authorizing this provider."
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
@ -4069,12 +4097,14 @@
|
||||
"title": "Signature algorithm"
|
||||
},
|
||||
"signing_kp": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Signing Keypair",
|
||||
"description": "Keypair used to sign outgoing Responses going to the Service Provider."
|
||||
},
|
||||
"verification_kp": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Verification Certificate",
|
||||
"description": "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
|
||||
},
|
||||
@ -4143,14 +4173,16 @@
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
"property_mappings_group": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Property mappings used for group creation/updating."
|
||||
},
|
||||
"title": "Property mappings group",
|
||||
@ -4173,7 +4205,8 @@
|
||||
"title": "Exclude users service account"
|
||||
},
|
||||
"filter_group": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Filter group"
|
||||
}
|
||||
},
|
||||
@ -4238,12 +4271,14 @@
|
||||
"title": "Enabled"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow to use when authenticating existing users."
|
||||
},
|
||||
"enrollment_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Enrollment flow",
|
||||
"description": "Flow to use when enrolling new users."
|
||||
},
|
||||
@ -4283,12 +4318,14 @@
|
||||
"title": "Server URI"
|
||||
},
|
||||
"peer_certificate": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Peer certificate",
|
||||
"description": "Optionally verify the LDAP Server's Certificate against the CA Chain in this keypair."
|
||||
},
|
||||
"client_certificate": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Client certificate",
|
||||
"description": "Client certificate to authenticate against the LDAP Server's Certificate."
|
||||
},
|
||||
@ -4366,20 +4403,23 @@
|
||||
"title": "Sync groups"
|
||||
},
|
||||
"sync_parent_group": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Sync parent group"
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
"property_mappings_group": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Property mappings used for group creation/updating."
|
||||
},
|
||||
"title": "Property mappings group",
|
||||
@ -4440,12 +4480,14 @@
|
||||
"title": "Enabled"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow to use when authenticating existing users."
|
||||
},
|
||||
"enrollment_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Enrollment flow",
|
||||
"description": "Flow to use when enrolling new users."
|
||||
},
|
||||
@ -4619,12 +4661,14 @@
|
||||
"title": "Enabled"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow to use when authenticating existing users."
|
||||
},
|
||||
"enrollment_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Enrollment flow",
|
||||
"description": "Flow to use when enrolling new users."
|
||||
},
|
||||
@ -4731,12 +4775,14 @@
|
||||
"title": "Enabled"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow to use when authenticating existing users."
|
||||
},
|
||||
"enrollment_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Enrollment flow",
|
||||
"description": "Flow to use when enrolling new users."
|
||||
},
|
||||
@ -4771,7 +4817,8 @@
|
||||
"title": "Icon"
|
||||
},
|
||||
"pre_authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Pre authentication flow",
|
||||
"description": "Flow used before authentication."
|
||||
},
|
||||
@ -4825,12 +4872,14 @@
|
||||
"title": "Binding type"
|
||||
},
|
||||
"verification_kp": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Verification Certificate",
|
||||
"description": "When selected, incoming assertion's Signatures will be validated against this certificate. To allow unsigned Requests, leave on default."
|
||||
},
|
||||
"signing_kp": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Signing Keypair",
|
||||
"description": "Keypair used to sign outgoing Responses going to the Identity Provider."
|
||||
},
|
||||
@ -4975,7 +5024,8 @@
|
||||
"title": "Flow set"
|
||||
},
|
||||
"configure_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Configure flow",
|
||||
"description": "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
},
|
||||
@ -5117,7 +5167,8 @@
|
||||
"title": "Flow set"
|
||||
},
|
||||
"configure_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Configure flow",
|
||||
"description": "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
},
|
||||
@ -5281,7 +5332,8 @@
|
||||
"title": "Flow set"
|
||||
},
|
||||
"configure_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Configure flow",
|
||||
"description": "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
},
|
||||
@ -5412,7 +5464,8 @@
|
||||
"title": "Flow set"
|
||||
},
|
||||
"configure_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Configure flow",
|
||||
"description": "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
},
|
||||
@ -5566,7 +5619,8 @@
|
||||
"configuration_stages": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Stages used to configure Authenticator when user doesn't have any compatible devices. After this configuration Stage passes, the user is not prompted again."
|
||||
},
|
||||
"title": "Configuration stages",
|
||||
@ -5591,7 +5645,7 @@
|
||||
},
|
||||
"required": []
|
||||
},
|
||||
"model_authentik_stages_authenticator_webauthn.authenticatewebauthnstage": {
|
||||
"model_authentik_stages_authenticator_webauthn.authenticatorwebauthnstage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
@ -5682,7 +5736,8 @@
|
||||
"title": "Flow set"
|
||||
},
|
||||
"configure_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Configure flow",
|
||||
"description": "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
},
|
||||
@ -5723,6 +5778,13 @@
|
||||
"required"
|
||||
],
|
||||
"title": "Resident key requirement"
|
||||
},
|
||||
"device_type_restrictions": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
},
|
||||
"title": "Device type restrictions"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
@ -6004,7 +6066,8 @@
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Groups"
|
||||
},
|
||||
@ -6587,17 +6650,20 @@
|
||||
"description": "When a valid username/email has been entered, and this option is enabled, the user's username and avatar will be shown. Otherwise, the text that the user entered will be shown"
|
||||
},
|
||||
"enrollment_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Enrollment flow",
|
||||
"description": "Optional enrollment flow, which is linked at the bottom of the page."
|
||||
},
|
||||
"recovery_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Recovery flow",
|
||||
"description": "Optional recovery flow, which is linked at the bottom of the page."
|
||||
},
|
||||
"passwordless_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Passwordless flow",
|
||||
"description": "Optional passwordless flow, which is linked at the bottom of the page."
|
||||
},
|
||||
@ -6746,7 +6812,8 @@
|
||||
"description": "When enabled, the invitation will be deleted after usage."
|
||||
},
|
||||
"flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Flow",
|
||||
"description": "When set, only the configured flow can use this invitation."
|
||||
}
|
||||
@ -6858,7 +6925,8 @@
|
||||
"description": "Selection of backends to test the password against."
|
||||
},
|
||||
"configure_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Configure flow",
|
||||
"description": "Flow used by an authenticated user to configure this Stage. If empty, user will not be able to configure this stage."
|
||||
},
|
||||
@ -7142,14 +7210,16 @@
|
||||
"fields": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Fields"
|
||||
},
|
||||
"validation_policies": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Validation policies"
|
||||
}
|
||||
@ -7579,7 +7649,8 @@
|
||||
"description": "When set, newly created users are inactive and cannot login."
|
||||
},
|
||||
"create_users_group": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Create users group",
|
||||
"description": "Optionally add newly created users to this group."
|
||||
},
|
||||
@ -7629,31 +7700,38 @@
|
||||
"title": "Branding favicon"
|
||||
},
|
||||
"flow_authentication": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Flow authentication"
|
||||
},
|
||||
"flow_invalidation": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Flow invalidation"
|
||||
},
|
||||
"flow_recovery": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Flow recovery"
|
||||
},
|
||||
"flow_unenrollment": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Flow unenrollment"
|
||||
},
|
||||
"flow_user_settings": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Flow user settings"
|
||||
},
|
||||
"flow_device_code": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Flow device code"
|
||||
},
|
||||
"web_certificate": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Web certificate",
|
||||
"description": "Web Certificate used by the authentik Core webserver."
|
||||
},
|
||||
@ -7708,7 +7786,8 @@
|
||||
"description": "Users added to this group will be superusers."
|
||||
},
|
||||
"parent": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Parent"
|
||||
},
|
||||
"users": {
|
||||
@ -7726,7 +7805,8 @@
|
||||
"roles": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Roles"
|
||||
}
|
||||
@ -7763,7 +7843,8 @@
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Groups"
|
||||
},
|
||||
@ -7943,19 +8024,22 @@
|
||||
"title": "Name"
|
||||
},
|
||||
"authentication_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authentication flow",
|
||||
"description": "Flow used for authentication when the associated application is accessed by an un-authenticated user."
|
||||
},
|
||||
"authorization_flow": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Authorization flow",
|
||||
"description": "Flow used when authorizing this provider."
|
||||
},
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
@ -8012,7 +8096,8 @@
|
||||
"property_mappings": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer"
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"title": "Property mappings"
|
||||
},
|
||||
@ -8368,7 +8453,8 @@
|
||||
"transports": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Select which transports should be used to notify the user. If none are selected, the notification will only be shown in the authentik UI."
|
||||
},
|
||||
"title": "Transports",
|
||||
@ -8385,7 +8471,8 @@
|
||||
"description": "Controls which severity level the created notifications will have."
|
||||
},
|
||||
"group": {
|
||||
"type": "integer",
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"title": "Group",
|
||||
"description": "Define which group of users this notification should be sent and shown to. If left empty, Notification won't ben sent."
|
||||
}
|
||||
|
||||
8
go.mod
8
go.mod
@ -9,7 +9,7 @@ require (
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
github.com/getsentry/sentry-go v0.27.0
|
||||
github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1
|
||||
github.com/go-ldap/ldap/v3 v3.4.6
|
||||
github.com/go-ldap/ldap/v3 v3.4.7
|
||||
github.com/go-openapi/runtime v0.28.0
|
||||
github.com/go-openapi/strfmt v0.23.0
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
@ -32,8 +32,8 @@ require (
|
||||
github.com/wwt/guac v1.3.2
|
||||
goauthentik.io/api/v3 v3.2024022.7
|
||||
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
|
||||
golang.org/x/oauth2 v0.18.0
|
||||
golang.org/x/sync v0.6.0
|
||||
golang.org/x/oauth2 v0.19.0
|
||||
golang.org/x/sync v0.7.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
|
||||
)
|
||||
@ -59,7 +59,6 @@ require (
|
||||
github.com/go-openapi/spec v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-openapi/validate v0.24.0 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
@ -79,7 +78,6 @@ require (
|
||||
golang.org/x/net v0.22.0 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.5.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
|
||||
55
go.sum
55
go.sum
@ -37,8 +37,8 @@ github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA=
|
||||
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
|
||||
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI=
|
||||
github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
@ -84,8 +84,8 @@ github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27 h1:O6yi4xa9b2D
|
||||
github.com/go-http-utils/fresh v0.0.0-20161124030543-7231e26a4b27/go.mod h1:AYvN8omj7nKLmbcXS2dyABYU6JB1Lz1bHmkkq1kf4I4=
|
||||
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a h1:v6zMvHuY9yue4+QkG/HQ/W67wvtQmWJ4SDo9aK/GIno=
|
||||
github.com/go-http-utils/headers v0.0.0-20181008091004-fed159eddc2a/go.mod h1:I79BieaU4fxrw4LMXby6q5OS9XnoR9UIKLOzDFjUmuw=
|
||||
github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A=
|
||||
github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc=
|
||||
github.com/go-ldap/ldap/v3 v3.4.7 h1:3Hbd7mIB1qjd3Ra59fI3JYea/t5kykFu2CVHBca9koE=
|
||||
github.com/go-ldap/ldap/v3 v3.4.7/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
|
||||
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
@ -137,9 +137,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
@ -149,7 +146,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
@ -165,7 +161,6 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
@ -174,18 +169,35 @@ github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyE
|
||||
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
|
||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
|
||||
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8=
|
||||
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8=
|
||||
github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo=
|
||||
github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM=
|
||||
github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg=
|
||||
github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o=
|
||||
github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8=
|
||||
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
|
||||
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0 h1:6lqVJ8X3ZaUwvzENqPAobDsXNExfUJd61u++uW8a3LE=
|
||||
github.com/jellydator/ttlcache/v3 v3.2.0/go.mod h1:hi7MGFdMAwZna5n2tuvh63DvFLzVKySzCVW6+0gA2n4=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
@ -248,6 +260,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
@ -255,6 +268,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/wwt/guac v1.3.2 h1:sH6OFGa/1tBs7ieWBVlZe7t6F5JAOWBry/tqQL/Vup4=
|
||||
@ -289,7 +303,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@ -355,7 +370,9 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@ -364,8 +381,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI=
|
||||
golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8=
|
||||
golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg=
|
||||
golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -376,8 +393,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -411,14 +428,15 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
|
||||
golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -427,7 +445,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@ -501,8 +518,6 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||
@ -554,8 +569,6 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
||||
@ -39,8 +39,10 @@ def check_redis():
|
||||
if CONFIG.get_bool("redis.tls", False):
|
||||
REDIS_PROTOCOL_PREFIX = "rediss://"
|
||||
REDIS_URL = (
|
||||
f"{REDIS_PROTOCOL_PREFIX}:"
|
||||
f"{quote_plus(CONFIG.get('redis.password'))}@{quote_plus(CONFIG.get('redis.host'))}:"
|
||||
f"{REDIS_PROTOCOL_PREFIX}"
|
||||
f"{quote_plus(CONFIG.get('redis.username'))}:"
|
||||
f"{quote_plus(CONFIG.get('redis.password'))}@"
|
||||
f"{quote_plus(CONFIG.get('redis.host'))}:"
|
||||
f"{CONFIG.get_int('redis.port')}/{CONFIG.get('redis.db')}"
|
||||
)
|
||||
while True:
|
||||
|
||||
25
poetry.lock
generated
25
poetry.lock
generated
@ -1431,6 +1431,23 @@ files = [
|
||||
[package.dependencies]
|
||||
requests = "*"
|
||||
|
||||
[[package]]
|
||||
name = "fido2"
|
||||
version = "1.1.3"
|
||||
description = "FIDO2/WebAuthn library for implementing clients and servers."
|
||||
optional = false
|
||||
python-versions = ">=3.8,<4.0"
|
||||
files = [
|
||||
{file = "fido2-1.1.3-py3-none-any.whl", hash = "sha256:6be34c0b9fe85e4911fd2d103cce7ae8ce2f064384a7a2a3bd970b3ef7702931"},
|
||||
{file = "fido2-1.1.3.tar.gz", hash = "sha256:26100f226d12ced621ca6198528ce17edf67b78df4287aee1285fee3cd5aa9fc"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
cryptography = ">=2.6,<35 || >35,<45"
|
||||
|
||||
[package.extras]
|
||||
pcsc = ["pyscard (>=1.9,<3)"]
|
||||
|
||||
[[package]]
|
||||
name = "flower"
|
||||
version = "2.0.1"
|
||||
@ -3918,13 +3935,13 @@ wsproto = ">=0.14"
|
||||
|
||||
[[package]]
|
||||
name = "twilio"
|
||||
version = "9.0.3"
|
||||
version = "9.0.4"
|
||||
description = "Twilio API client and TwiML generator"
|
||||
optional = false
|
||||
python-versions = ">=3.7.0"
|
||||
files = [
|
||||
{file = "twilio-9.0.3-py2.py3-none-any.whl", hash = "sha256:c21fd70d8518823831143999a38cc86c40dad45fab5a6b5ecfee85672e9e5cb2"},
|
||||
{file = "twilio-9.0.3.tar.gz", hash = "sha256:c13973415966e93b70651a58733fa76317df64621c74e0e4896613f10a368438"},
|
||||
{file = "twilio-9.0.4-py2.py3-none-any.whl", hash = "sha256:086abae1a575a0ee89a72c0792d814ee349fe55c8df76b563ecfc49463c3c533"},
|
||||
{file = "twilio-9.0.4.tar.gz", hash = "sha256:d493d5bde6361bb713dffec00b9465ff84978b71334dd75002152e79604688ba"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -4636,4 +4653,4 @@ files = [
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "~3.12"
|
||||
content-hash = "c5a36b528980277b07f80200da251a2bea31cc2b7d5438250706f23a825f3628"
|
||||
content-hash = "4544b2a0b0065aa9e13d9a3b5a951fb5212921fe72f0fe259069e2e9205e9830"
|
||||
|
||||
@ -108,6 +108,7 @@ drf-spectacular = "*"
|
||||
dumb-init = "*"
|
||||
duo-client = "*"
|
||||
facebook-sdk = "*"
|
||||
fido2 = "*"
|
||||
flower = "*"
|
||||
geoip2 = "*"
|
||||
gunicorn = "*"
|
||||
|
||||
461
schema.yml
461
schema.yml
@ -18405,7 +18405,7 @@ paths:
|
||||
- authentik_stages_authenticator_totp.authenticatortotpstage
|
||||
- authentik_stages_authenticator_totp.totpdevice
|
||||
- authentik_stages_authenticator_validate.authenticatorvalidatestage
|
||||
- authentik_stages_authenticator_webauthn.authenticatewebauthnstage
|
||||
- authentik_stages_authenticator_webauthn.authenticatorwebauthnstage
|
||||
- authentik_stages_authenticator_webauthn.webauthndevice
|
||||
- authentik_stages_captcha.captchastage
|
||||
- authentik_stages_consent.consentstage
|
||||
@ -18619,7 +18619,7 @@ paths:
|
||||
- authentik_stages_authenticator_totp.authenticatortotpstage
|
||||
- authentik_stages_authenticator_totp.totpdevice
|
||||
- authentik_stages_authenticator_validate.authenticatorvalidatestage
|
||||
- authentik_stages_authenticator_webauthn.authenticatewebauthnstage
|
||||
- authentik_stages_authenticator_webauthn.authenticatorwebauthnstage
|
||||
- authentik_stages_authenticator_webauthn.webauthndevice
|
||||
- authentik_stages_captcha.captchastage
|
||||
- authentik_stages_consent.consentstage
|
||||
@ -24007,7 +24007,7 @@ paths:
|
||||
/stages/authenticator/webauthn/:
|
||||
get:
|
||||
operationId: stages_authenticator_webauthn_list
|
||||
description: AuthenticateWebAuthnStage Viewset
|
||||
description: AuthenticatorWebAuthnStage Viewset
|
||||
parameters:
|
||||
- in: query
|
||||
name: authenticator_attachment
|
||||
@ -24022,6 +24022,15 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: device_type_restrictions
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
explode: true
|
||||
style: form
|
||||
- in: query
|
||||
name: friendly_name
|
||||
schema:
|
||||
@ -24084,7 +24093,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PaginatedAuthenticateWebAuthnStageList'
|
||||
$ref: '#/components/schemas/PaginatedAuthenticatorWebAuthnStageList'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
@ -24100,14 +24109,14 @@ paths:
|
||||
description: ''
|
||||
post:
|
||||
operationId: stages_authenticator_webauthn_create
|
||||
description: AuthenticateWebAuthnStage Viewset
|
||||
description: AuthenticatorWebAuthnStage Viewset
|
||||
tags:
|
||||
- stages
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuthenticateWebAuthnStageRequest'
|
||||
$ref: '#/components/schemas/AuthenticatorWebAuthnStageRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
@ -24116,7 +24125,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuthenticateWebAuthnStage'
|
||||
$ref: '#/components/schemas/AuthenticatorWebAuthnStage'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
@ -24133,7 +24142,7 @@ paths:
|
||||
/stages/authenticator/webauthn/{stage_uuid}/:
|
||||
get:
|
||||
operationId: stages_authenticator_webauthn_retrieve
|
||||
description: AuthenticateWebAuthnStage Viewset
|
||||
description: AuthenticatorWebAuthnStage Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: stage_uuid
|
||||
@ -24151,7 +24160,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuthenticateWebAuthnStage'
|
||||
$ref: '#/components/schemas/AuthenticatorWebAuthnStage'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
@ -24167,7 +24176,7 @@ paths:
|
||||
description: ''
|
||||
put:
|
||||
operationId: stages_authenticator_webauthn_update
|
||||
description: AuthenticateWebAuthnStage Viewset
|
||||
description: AuthenticatorWebAuthnStage Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: stage_uuid
|
||||
@ -24182,7 +24191,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuthenticateWebAuthnStageRequest'
|
||||
$ref: '#/components/schemas/AuthenticatorWebAuthnStageRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
@ -24191,7 +24200,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuthenticateWebAuthnStage'
|
||||
$ref: '#/components/schemas/AuthenticatorWebAuthnStage'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
@ -24207,7 +24216,7 @@ paths:
|
||||
description: ''
|
||||
patch:
|
||||
operationId: stages_authenticator_webauthn_partial_update
|
||||
description: AuthenticateWebAuthnStage Viewset
|
||||
description: AuthenticatorWebAuthnStage Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: stage_uuid
|
||||
@ -24222,7 +24231,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PatchedAuthenticateWebAuthnStageRequest'
|
||||
$ref: '#/components/schemas/PatchedAuthenticatorWebAuthnStageRequest'
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
@ -24230,7 +24239,7 @@ paths:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/AuthenticateWebAuthnStage'
|
||||
$ref: '#/components/schemas/AuthenticatorWebAuthnStage'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
@ -24246,7 +24255,7 @@ paths:
|
||||
description: ''
|
||||
delete:
|
||||
operationId: stages_authenticator_webauthn_destroy
|
||||
description: AuthenticateWebAuthnStage Viewset
|
||||
description: AuthenticatorWebAuthnStage Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: stage_uuid
|
||||
@ -24311,6 +24320,106 @@ paths:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/stages/authenticator/webauthn_device_types/:
|
||||
get:
|
||||
operationId: stages_authenticator_webauthn_device_types_list
|
||||
description: WebAuthnDeviceType Viewset
|
||||
parameters:
|
||||
- in: query
|
||||
name: aaguid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
- in: query
|
||||
name: description
|
||||
schema:
|
||||
type: string
|
||||
- in: query
|
||||
name: icon
|
||||
schema:
|
||||
type: string
|
||||
- name: ordering
|
||||
required: false
|
||||
in: query
|
||||
description: Which field to use when ordering the results.
|
||||
schema:
|
||||
type: string
|
||||
- name: page
|
||||
required: false
|
||||
in: query
|
||||
description: A page number within the paginated result set.
|
||||
schema:
|
||||
type: integer
|
||||
- name: page_size
|
||||
required: false
|
||||
in: query
|
||||
description: Number of results to return per page.
|
||||
schema:
|
||||
type: integer
|
||||
- name: search
|
||||
required: false
|
||||
in: query
|
||||
description: A search term.
|
||||
schema:
|
||||
type: string
|
||||
tags:
|
||||
- stages
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PaginatedWebAuthnDeviceTypeList'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/stages/authenticator/webauthn_device_types/{aaguid}/:
|
||||
get:
|
||||
operationId: stages_authenticator_webauthn_device_types_retrieve
|
||||
description: WebAuthnDeviceType Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
name: aaguid
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
description: A UUID string identifying this WebAuthn Device type.
|
||||
required: true
|
||||
tags:
|
||||
- stages
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/WebAuthnDeviceType'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/stages/captcha/:
|
||||
get:
|
||||
operationId: stages_captcha_list
|
||||
@ -29738,92 +29847,6 @@ components:
|
||||
- basic
|
||||
- bearer
|
||||
type: string
|
||||
AuthenticateWebAuthnStage:
|
||||
type: object
|
||||
description: AuthenticateWebAuthnStage Serializer
|
||||
properties:
|
||||
pk:
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
title: Stage uuid
|
||||
name:
|
||||
type: string
|
||||
component:
|
||||
type: string
|
||||
description: Get object type so that we know how to edit the object
|
||||
readOnly: true
|
||||
verbose_name:
|
||||
type: string
|
||||
description: Return object's verbose_name
|
||||
readOnly: true
|
||||
verbose_name_plural:
|
||||
type: string
|
||||
description: Return object's plural verbose_name
|
||||
readOnly: true
|
||||
meta_model_name:
|
||||
type: string
|
||||
description: Return internal model name
|
||||
readOnly: true
|
||||
flow_set:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FlowSet'
|
||||
configure_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Flow used by an authenticated user to configure this Stage.
|
||||
If empty, user will not be able to configure this stage.
|
||||
friendly_name:
|
||||
type: string
|
||||
nullable: true
|
||||
user_verification:
|
||||
$ref: '#/components/schemas/UserVerificationEnum'
|
||||
authenticator_attachment:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AuthenticatorAttachmentEnum'
|
||||
nullable: true
|
||||
resident_key_requirement:
|
||||
$ref: '#/components/schemas/ResidentKeyRequirementEnum'
|
||||
required:
|
||||
- component
|
||||
- meta_model_name
|
||||
- name
|
||||
- pk
|
||||
- verbose_name
|
||||
- verbose_name_plural
|
||||
AuthenticateWebAuthnStageRequest:
|
||||
type: object
|
||||
description: AuthenticateWebAuthnStage Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
flow_set:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FlowSetRequest'
|
||||
configure_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Flow used by an authenticated user to configure this Stage.
|
||||
If empty, user will not be able to configure this stage.
|
||||
friendly_name:
|
||||
type: string
|
||||
nullable: true
|
||||
minLength: 1
|
||||
user_verification:
|
||||
$ref: '#/components/schemas/UserVerificationEnum'
|
||||
authenticator_attachment:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AuthenticatorAttachmentEnum'
|
||||
nullable: true
|
||||
resident_key_requirement:
|
||||
$ref: '#/components/schemas/ResidentKeyRequirementEnum'
|
||||
required:
|
||||
- name
|
||||
AuthenticatedSession:
|
||||
type: object
|
||||
description: AuthenticatedSession Serializer
|
||||
@ -30738,6 +30761,108 @@ components:
|
||||
additionalProperties: {}
|
||||
required:
|
||||
- response
|
||||
AuthenticatorWebAuthnStage:
|
||||
type: object
|
||||
description: AuthenticatorWebAuthnStage Serializer
|
||||
properties:
|
||||
pk:
|
||||
type: string
|
||||
format: uuid
|
||||
readOnly: true
|
||||
title: Stage uuid
|
||||
name:
|
||||
type: string
|
||||
component:
|
||||
type: string
|
||||
description: Get object type so that we know how to edit the object
|
||||
readOnly: true
|
||||
verbose_name:
|
||||
type: string
|
||||
description: Return object's verbose_name
|
||||
readOnly: true
|
||||
verbose_name_plural:
|
||||
type: string
|
||||
description: Return object's plural verbose_name
|
||||
readOnly: true
|
||||
meta_model_name:
|
||||
type: string
|
||||
description: Return internal model name
|
||||
readOnly: true
|
||||
flow_set:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FlowSet'
|
||||
configure_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Flow used by an authenticated user to configure this Stage.
|
||||
If empty, user will not be able to configure this stage.
|
||||
friendly_name:
|
||||
type: string
|
||||
nullable: true
|
||||
user_verification:
|
||||
$ref: '#/components/schemas/UserVerificationEnum'
|
||||
authenticator_attachment:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AuthenticatorAttachmentEnum'
|
||||
nullable: true
|
||||
resident_key_requirement:
|
||||
$ref: '#/components/schemas/ResidentKeyRequirementEnum'
|
||||
device_type_restrictions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
device_type_restrictions_obj:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/WebAuthnDeviceType'
|
||||
readOnly: true
|
||||
required:
|
||||
- component
|
||||
- device_type_restrictions_obj
|
||||
- meta_model_name
|
||||
- name
|
||||
- pk
|
||||
- verbose_name
|
||||
- verbose_name_plural
|
||||
AuthenticatorWebAuthnStageRequest:
|
||||
type: object
|
||||
description: AuthenticatorWebAuthnStage Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
flow_set:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FlowSetRequest'
|
||||
configure_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Flow used by an authenticated user to configure this Stage.
|
||||
If empty, user will not be able to configure this stage.
|
||||
friendly_name:
|
||||
type: string
|
||||
nullable: true
|
||||
minLength: 1
|
||||
user_verification:
|
||||
$ref: '#/components/schemas/UserVerificationEnum'
|
||||
authenticator_attachment:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AuthenticatorAttachmentEnum'
|
||||
nullable: true
|
||||
resident_key_requirement:
|
||||
$ref: '#/components/schemas/ResidentKeyRequirementEnum'
|
||||
device_type_restrictions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
required:
|
||||
- name
|
||||
AutoSubmitChallengeResponseRequest:
|
||||
type: object
|
||||
description: Pseudo class for autosubmit response
|
||||
@ -34706,7 +34831,7 @@ components:
|
||||
- authentik_stages_authenticator_totp.authenticatortotpstage
|
||||
- authentik_stages_authenticator_totp.totpdevice
|
||||
- authentik_stages_authenticator_validate.authenticatorvalidatestage
|
||||
- authentik_stages_authenticator_webauthn.authenticatewebauthnstage
|
||||
- authentik_stages_authenticator_webauthn.authenticatorwebauthnstage
|
||||
- authentik_stages_authenticator_webauthn.webauthndevice
|
||||
- authentik_stages_captcha.captchastage
|
||||
- authentik_stages_consent.consentstage
|
||||
@ -35673,18 +35798,6 @@ components:
|
||||
required:
|
||||
- pagination
|
||||
- results
|
||||
PaginatedAuthenticateWebAuthnStageList:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: '#/components/schemas/Pagination'
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AuthenticateWebAuthnStage'
|
||||
required:
|
||||
- pagination
|
||||
- results
|
||||
PaginatedAuthenticatedSessionList:
|
||||
type: object
|
||||
properties:
|
||||
@ -35757,6 +35870,18 @@ components:
|
||||
required:
|
||||
- pagination
|
||||
- results
|
||||
PaginatedAuthenticatorWebAuthnStageList:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: '#/components/schemas/Pagination'
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/AuthenticatorWebAuthnStage'
|
||||
required:
|
||||
- pagination
|
||||
- results
|
||||
PaginatedBlueprintInstanceList:
|
||||
type: object
|
||||
properties:
|
||||
@ -36825,6 +36950,18 @@ components:
|
||||
required:
|
||||
- pagination
|
||||
- results
|
||||
PaginatedWebAuthnDeviceTypeList:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: '#/components/schemas/Pagination'
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/WebAuthnDeviceType'
|
||||
required:
|
||||
- pagination
|
||||
- results
|
||||
Pagination:
|
||||
type: object
|
||||
properties:
|
||||
@ -37230,35 +37367,6 @@ components:
|
||||
$ref: '#/components/schemas/PolicyEngineMode'
|
||||
group:
|
||||
type: string
|
||||
PatchedAuthenticateWebAuthnStageRequest:
|
||||
type: object
|
||||
description: AuthenticateWebAuthnStage Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
flow_set:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FlowSetRequest'
|
||||
configure_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Flow used by an authenticated user to configure this Stage.
|
||||
If empty, user will not be able to configure this stage.
|
||||
friendly_name:
|
||||
type: string
|
||||
nullable: true
|
||||
minLength: 1
|
||||
user_verification:
|
||||
$ref: '#/components/schemas/UserVerificationEnum'
|
||||
authenticator_attachment:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AuthenticatorAttachmentEnum'
|
||||
nullable: true
|
||||
resident_key_requirement:
|
||||
$ref: '#/components/schemas/ResidentKeyRequirementEnum'
|
||||
PatchedAuthenticatorDuoStageRequest:
|
||||
type: object
|
||||
description: AuthenticatorDuoStage Serializer
|
||||
@ -37428,6 +37536,40 @@ components:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/UserVerificationEnum'
|
||||
description: Enforce user verification for WebAuthn devices.
|
||||
PatchedAuthenticatorWebAuthnStageRequest:
|
||||
type: object
|
||||
description: AuthenticatorWebAuthnStage Serializer
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
minLength: 1
|
||||
flow_set:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/FlowSetRequest'
|
||||
configure_flow:
|
||||
type: string
|
||||
format: uuid
|
||||
nullable: true
|
||||
description: Flow used by an authenticated user to configure this Stage.
|
||||
If empty, user will not be able to configure this stage.
|
||||
friendly_name:
|
||||
type: string
|
||||
nullable: true
|
||||
minLength: 1
|
||||
user_verification:
|
||||
$ref: '#/components/schemas/UserVerificationEnum'
|
||||
authenticator_attachment:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/AuthenticatorAttachmentEnum'
|
||||
nullable: true
|
||||
resident_key_requirement:
|
||||
$ref: '#/components/schemas/ResidentKeyRequirementEnum'
|
||||
device_type_restrictions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
PatchedBlueprintInstanceRequest:
|
||||
type: object
|
||||
description: Info about a single blueprint instance file
|
||||
@ -44133,8 +44275,14 @@ components:
|
||||
type: string
|
||||
format: date-time
|
||||
readOnly: true
|
||||
device_type:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/WebAuthnDeviceType'
|
||||
readOnly: true
|
||||
nullable: true
|
||||
required:
|
||||
- created_on
|
||||
- device_type
|
||||
- name
|
||||
- pk
|
||||
WebAuthnDeviceRequest:
|
||||
@ -44147,6 +44295,31 @@ components:
|
||||
maxLength: 200
|
||||
required:
|
||||
- name
|
||||
WebAuthnDeviceType:
|
||||
type: object
|
||||
description: WebAuthnDeviceType Serializer
|
||||
properties:
|
||||
aaguid:
|
||||
type: string
|
||||
format: uuid
|
||||
description:
|
||||
type: string
|
||||
required:
|
||||
- aaguid
|
||||
- description
|
||||
WebAuthnDeviceTypeRequest:
|
||||
type: object
|
||||
description: WebAuthnDeviceType Serializer
|
||||
properties:
|
||||
aaguid:
|
||||
type: string
|
||||
format: uuid
|
||||
description:
|
||||
type: string
|
||||
minLength: 1
|
||||
required:
|
||||
- aaguid
|
||||
- description
|
||||
Workers:
|
||||
type: object
|
||||
properties:
|
||||
|
||||
8
tests/wdio/package-lock.json
generated
8
tests/wdio/package-lock.json
generated
@ -22,7 +22,7 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.2.5",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.3",
|
||||
"typescript": "^5.4.4",
|
||||
"wdio-wait-for": "^3.0.11"
|
||||
},
|
||||
"engines": {
|
||||
@ -8620,9 +8620,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
||||
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
||||
"version": "5.4.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz",
|
||||
"integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"prettier": "^3.2.5",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.4.3",
|
||||
"typescript": "^5.4.4",
|
||||
"wdio-wait-for": "^3.0.11"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
79
web/package-lock.json
generated
79
web/package-lock.json
generated
@ -13,11 +13,11 @@
|
||||
"@codemirror/lang-javascript": "^6.2.2",
|
||||
"@codemirror/lang-python": "^6.1.5",
|
||||
"@codemirror/lang-xml": "^6.1.0",
|
||||
"@codemirror/legacy-modes": "^6.3.3",
|
||||
"@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.2.2-1712238004",
|
||||
"@goauthentik/api": "^2024.2.2-1712571709",
|
||||
"@lit-labs/task": "^3.1.0",
|
||||
"@lit/context": "^1.1.0",
|
||||
"@lit/localize": "^0.12.1",
|
||||
@ -33,7 +33,7 @@
|
||||
"codemirror": "^6.0.1",
|
||||
"construct-style-sheets-polyfill": "^3.1.0",
|
||||
"core-js": "^3.36.1",
|
||||
"country-flag-icons": "^1.5.10",
|
||||
"country-flag-icons": "^1.5.11",
|
||||
"fuse.js": "^7.0.0",
|
||||
"guacamole-common-js": "^1.5.0",
|
||||
"lit": "^3.1.2",
|
||||
@ -42,7 +42,7 @@
|
||||
"rapidoc": "^9.3.4",
|
||||
"showdown": "^2.1.0",
|
||||
"style-mod": "^4.1.2",
|
||||
"ts-pattern": "^5.1.0",
|
||||
"ts-pattern": "^5.1.1",
|
||||
"webcomponent-qr-code": "^1.2.0",
|
||||
"yaml": "^2.4.1"
|
||||
},
|
||||
@ -59,7 +59,7 @@
|
||||
"@jeysal/storybook-addon-css-user-preferences": "^0.2.0",
|
||||
"@lit/localize-tools": "^0.7.2",
|
||||
"@rollup/plugin-replace": "^5.0.5",
|
||||
"@spotlightjs/spotlight": "^1.2.16",
|
||||
"@spotlightjs/spotlight": "^1.2.17",
|
||||
"@storybook/addon-essentials": "^7.6.17",
|
||||
"@storybook/addon-links": "^7.6.17",
|
||||
"@storybook/api": "^7.6.17",
|
||||
@ -101,7 +101,7 @@
|
||||
"ts-lit-plugin": "^2.0.2",
|
||||
"tslib": "^2.6.2",
|
||||
"turnstile-types": "^1.2.0",
|
||||
"typescript": "^5.4.3",
|
||||
"typescript": "^5.4.4",
|
||||
"vite-tsconfig-paths": "^4.3.2"
|
||||
},
|
||||
"engines": {
|
||||
@ -111,9 +111,9 @@
|
||||
"@esbuild/darwin-arm64": "^0.20.1",
|
||||
"@esbuild/linux-amd64": "^0.18.11",
|
||||
"@esbuild/linux-arm64": "^0.20.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.14.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.14.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.14.0"
|
||||
"@rollup/rollup-darwin-arm64": "4.14.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.14.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.14.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
@ -2218,8 +2218,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/legacy-modes": {
|
||||
"version": "6.3.3",
|
||||
"license": "MIT",
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/legacy-modes/-/legacy-modes-6.4.0.tgz",
|
||||
"integrity": "sha512-5m/K+1A6gYR0e+h/dEde7LoGimMjRtWXZFg4Lo70cc8HzjSdHe3fLwjWMR0VRl5KFT1SxalSap7uMgPKF28wBA==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0"
|
||||
}
|
||||
@ -2839,9 +2840,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@goauthentik/api": {
|
||||
"version": "2024.2.2-1712238004",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.2.2-1712238004.tgz",
|
||||
"integrity": "sha512-Y1wNhIYN3/CwpcCKGm8JT0Vkkqjfh3Og91IvzLRVJ61qBQ3/hc016YBjdAEnXzzDOmylRalI0Umfl2nl2NXdHQ=="
|
||||
"version": "2024.2.2-1712571709",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2024.2.2-1712571709.tgz",
|
||||
"integrity": "sha512-+uS+d13aCDC7W3bZk8j3RnqvDq8iivXnP98GHFEoB9pUuMJ1LK7sgJwr2JHmJe5KiFMl0oxycY8VutsBnYmjog=="
|
||||
},
|
||||
"node_modules/@hcaptcha/types": {
|
||||
"version": "1.0.3",
|
||||
@ -4247,9 +4248,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.0.tgz",
|
||||
"integrity": "sha512-BcnSPRM76/cD2gQC+rQNGBN6GStBs2pl/FpweW8JYuz5J/IEa0Fr4AtrPv766DB/6b2MZ/AfSIOSGw3nEIP8SA==",
|
||||
"version": "4.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.14.1.tgz",
|
||||
"integrity": "sha512-+kecg3FY84WadgcuSVm6llrABOdQAEbNdnpi5X3UwWiFVhZIZvKgGrF7kmLguvxHNQy+UuRV66cLVl3S+Rkt+Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -4287,9 +4288,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.0.tgz",
|
||||
"integrity": "sha512-x+uJ6MAYRlHGe9wi4HQjxpaKHPM3d3JjqqCkeC5gpnnI6OWovLdXTpfa8trjxPLnWKyBsSi5kne+146GAxFt4A==",
|
||||
"version": "4.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.14.1.tgz",
|
||||
"integrity": "sha512-p9rGKYkHdFMzhckOTFubfxgyIO1vw//7IIjBBRVzyZebWlzRLeNhqxuSaZ7kCEKVkm/kuC9fVRW9HkC/zNRG2w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -4355,9 +4356,9 @@
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.0.tgz",
|
||||
"integrity": "sha512-C6y6z2eCNCfhZxT9u+jAM2Fup89ZjiG5pIzZIDycs1IwESviLxwkQcFRGLjnDrP+PT+v5i4YFvlcfAs+LnreXg==",
|
||||
"version": "4.14.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.14.1.tgz",
|
||||
"integrity": "sha512-9Q7DGjZN+hTdJomaQ3Iub4m6VPu1r94bmK2z3UeWP3dGUecRC54tmVu9vKHTm1bOt3ASoYtEz6JSRLFzrysKlA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -4530,9 +4531,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@spotlightjs/overlay": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/@spotlightjs/overlay/-/overlay-1.8.2.tgz",
|
||||
"integrity": "sha512-g3pzaJFKK67pBIl72qSNoFJIfP/dmdFoSPWZZQW6MKAdU7IOY5yf3BB52xEc6iSfeLGG/KpYNThefpobX3hb7Q==",
|
||||
"version": "1.8.3",
|
||||
"resolved": "https://registry.npmjs.org/@spotlightjs/overlay/-/overlay-1.8.3.tgz",
|
||||
"integrity": "sha512-6b5tBspOOEd6Gj0l4xgdUwR4Ydn2dNX9lqJ/WSzIu1lqkI96w2lqf69IGzEo6jb9aPtfTtu8nx5K2SD6JXH2SA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@spotlightjs/sidecar": {
|
||||
@ -4544,12 +4545,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@spotlightjs/spotlight": {
|
||||
"version": "1.2.16",
|
||||
"resolved": "https://registry.npmjs.org/@spotlightjs/spotlight/-/spotlight-1.2.16.tgz",
|
||||
"integrity": "sha512-grqK7Qwzz0zJKaM4+u/0DS81gEGKkUsKwXGY1kA07rXsbp6ilT62JWI1tQDgYHb1i3MbR2ch0EuMT476CAtA+A==",
|
||||
"version": "1.2.17",
|
||||
"resolved": "https://registry.npmjs.org/@spotlightjs/spotlight/-/spotlight-1.2.17.tgz",
|
||||
"integrity": "sha512-91qtnLspMl2e1olBTeWoZcupwwTzQs8clQgTF8wv2Ib18zce7YYLvWpnDhNIVNQlbKIjGhYum6UY/KCfUCXQYg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@spotlightjs/overlay": "1.8.2",
|
||||
"@spotlightjs/overlay": "1.8.3",
|
||||
"@spotlightjs/sidecar": "1.4.0"
|
||||
},
|
||||
"bin": {
|
||||
@ -8620,9 +8621,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/country-flag-icons": {
|
||||
"version": "1.5.10",
|
||||
"resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.5.10.tgz",
|
||||
"integrity": "sha512-x3elaK+ZY23W1YtFsNQknRdURzkV7g3Z93AoA7SHZJUEXbVjRsNh4h9Uf09+OjWF/4u8tXeAt37gezGRdwR/2g=="
|
||||
"version": "1.5.11",
|
||||
"resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.5.11.tgz",
|
||||
"integrity": "sha512-B+mvFywunkRJs270k7kCBjhogvIA0uNn6GAXv6m2cPn3rrwqZzZVr2gBWcz+Cz7OGVWlcbERlYRIX0S6OGr8Bw=="
|
||||
},
|
||||
"node_modules/crelt": {
|
||||
"version": "1.0.6",
|
||||
@ -16940,9 +16941,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ts-pattern": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.1.0.tgz",
|
||||
"integrity": "sha512-sULbgZDTXrcr6WMeuR8gPb+dvNN/fNpxE8GHfosFHPJRPuxHVNtGcEiiNuQa6nxu40/dY6xYdTJmc7MG3w8B5g=="
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.1.1.tgz",
|
||||
"integrity": "sha512-i+owkHr5RYdQxj8olUgRrqpiWH9x27PuWVfXwDmJ/n/CoF/SAa7WW1i2oUpPDMQpJ4U+bGRUcZkVq7i1m3zFCg=="
|
||||
},
|
||||
"node_modules/ts-simple-type": {
|
||||
"version": "2.0.0-next.0",
|
||||
@ -17128,9 +17129,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
||||
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
||||
"version": "5.4.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz",
|
||||
"integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
|
||||
@ -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=8192' eslint . --max-warnings 0 --fix",
|
||||
"lint:precommit": "cross-env NODE_OPTIONS='--max_old_space_size=8192' 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",
|
||||
@ -34,11 +34,11 @@
|
||||
"@codemirror/lang-javascript": "^6.2.2",
|
||||
"@codemirror/lang-python": "^6.1.5",
|
||||
"@codemirror/lang-xml": "^6.1.0",
|
||||
"@codemirror/legacy-modes": "^6.3.3",
|
||||
"@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.2.2-1712238004",
|
||||
"@goauthentik/api": "^2024.2.2-1712571709",
|
||||
"@lit-labs/task": "^3.1.0",
|
||||
"@lit/context": "^1.1.0",
|
||||
"@lit/localize": "^0.12.1",
|
||||
@ -54,7 +54,7 @@
|
||||
"codemirror": "^6.0.1",
|
||||
"construct-style-sheets-polyfill": "^3.1.0",
|
||||
"core-js": "^3.36.1",
|
||||
"country-flag-icons": "^1.5.10",
|
||||
"country-flag-icons": "^1.5.11",
|
||||
"fuse.js": "^7.0.0",
|
||||
"guacamole-common-js": "^1.5.0",
|
||||
"lit": "^3.1.2",
|
||||
@ -63,7 +63,7 @@
|
||||
"rapidoc": "^9.3.4",
|
||||
"showdown": "^2.1.0",
|
||||
"style-mod": "^4.1.2",
|
||||
"ts-pattern": "^5.1.0",
|
||||
"ts-pattern": "^5.1.1",
|
||||
"webcomponent-qr-code": "^1.2.0",
|
||||
"yaml": "^2.4.1"
|
||||
},
|
||||
@ -80,7 +80,7 @@
|
||||
"@jeysal/storybook-addon-css-user-preferences": "^0.2.0",
|
||||
"@lit/localize-tools": "^0.7.2",
|
||||
"@rollup/plugin-replace": "^5.0.5",
|
||||
"@spotlightjs/spotlight": "^1.2.16",
|
||||
"@spotlightjs/spotlight": "^1.2.17",
|
||||
"@storybook/addon-essentials": "^7.6.17",
|
||||
"@storybook/addon-links": "^7.6.17",
|
||||
"@storybook/api": "^7.6.17",
|
||||
@ -122,16 +122,16 @@
|
||||
"ts-lit-plugin": "^2.0.2",
|
||||
"tslib": "^2.6.2",
|
||||
"turnstile-types": "^1.2.0",
|
||||
"typescript": "^5.4.3",
|
||||
"typescript": "^5.4.4",
|
||||
"vite-tsconfig-paths": "^4.3.2"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/darwin-arm64": "^0.20.1",
|
||||
"@esbuild/linux-amd64": "^0.18.11",
|
||||
"@esbuild/linux-arm64": "^0.20.1",
|
||||
"@rollup/rollup-darwin-arm64": "4.14.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.14.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.14.0"
|
||||
"@rollup/rollup-darwin-arm64": "4.14.1",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.14.1",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.14.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
|
||||
@ -75,6 +75,9 @@ export class EnterpriseLicenseListPage extends TablePage<License> {
|
||||
.pf-m-no-padding-bottom {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.install-id {
|
||||
word-break: break-all;
|
||||
}
|
||||
`,
|
||||
);
|
||||
}
|
||||
@ -255,7 +258,7 @@ export class EnterpriseLicenseListPage extends TablePage<License> {
|
||||
>
|
||||
</div>
|
||||
<div class="pf-c-card__title">${msg("Your Install ID")}</div>
|
||||
<div class="pf-c-card__body">${installID}</div>
|
||||
<div class="pf-c-card__body install-id">${installID}</div>
|
||||
`;
|
||||
|
||||
return html`<div class="pf-l-grid__item pf-c-card">
|
||||
|
||||
@ -18,7 +18,7 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
import { EventsApi } from "@goauthentik/api";
|
||||
import { EventToJSON, EventsApi } from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-event-view")
|
||||
export class EventViewPage extends AKElement {
|
||||
@ -143,7 +143,7 @@ export class EventViewPage extends AKElement {
|
||||
<div class="pf-c-card pf-l-grid__item pf-m-12-col">
|
||||
<div class="pf-c-card__title">${msg("Raw event info")}</div>
|
||||
<div class="pf-c-card__body">
|
||||
<pre>${JSON.stringify(this.event, null, 4)}</pre>
|
||||
<pre>${JSON.stringify(EventToJSON(this.event), null, 4)}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -5,7 +5,7 @@ import "@goauthentik/admin/stages/authenticator_sms/AuthenticatorSMSStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_static/AuthenticatorStaticStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_totp/AuthenticatorTOTPStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_validate/AuthenticatorValidateStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_webauthn/AuthenticatorWebAuthnStageForm";
|
||||
import "@goauthentik/admin/stages/captcha/CaptchaStageForm";
|
||||
import "@goauthentik/admin/stages/consent/ConsentStageForm";
|
||||
import "@goauthentik/admin/stages/deny/DenyStageForm";
|
||||
|
||||
@ -5,7 +5,7 @@ import "@goauthentik/admin/stages/authenticator_sms/AuthenticatorSMSStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_static/AuthenticatorStaticStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_totp/AuthenticatorTOTPStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_validate/AuthenticatorValidateStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_webauthn/AuthenticateWebAuthnStageForm";
|
||||
import "@goauthentik/admin/stages/authenticator_webauthn/AuthenticatorWebAuthnStageForm";
|
||||
import "@goauthentik/admin/stages/captcha/CaptchaStageForm";
|
||||
import "@goauthentik/admin/stages/consent/ConsentStageForm";
|
||||
import "@goauthentik/admin/stages/deny/DenyStageForm";
|
||||
|
||||
@ -63,6 +63,14 @@ export class AuthenticatorValidateStageForm extends BaseStageForm<AuthenticatorV
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
const authenticators = [
|
||||
[DeviceClassesEnum.Static, msg("Static Tokens")],
|
||||
[DeviceClassesEnum.Totp, msg("TOTP Authenticators")],
|
||||
[DeviceClassesEnum.Webauthn, msg("WebAuthn Authenticators")],
|
||||
[DeviceClassesEnum.Duo, msg("Duo Authenticators")],
|
||||
[DeviceClassesEnum.Sms, msg("SMS-based Authenticators")],
|
||||
];
|
||||
|
||||
return html` <span>
|
||||
${msg(
|
||||
"Stage used to validate any authenticator. This stage should be used during authentication or authorization flows.",
|
||||
@ -84,44 +92,19 @@ export class AuthenticatorValidateStageForm extends BaseStageForm<AuthenticatorV
|
||||
?required=${true}
|
||||
name="deviceClasses"
|
||||
>
|
||||
<select name="users" class="pf-c-form-control" multiple>
|
||||
<option
|
||||
value=${DeviceClassesEnum.Static}
|
||||
?selected=${this.isDeviceClassSelected(DeviceClassesEnum.Static)}
|
||||
>
|
||||
${msg("Static Tokens")}
|
||||
</option>
|
||||
<option
|
||||
value=${DeviceClassesEnum.Totp}
|
||||
?selected=${this.isDeviceClassSelected(DeviceClassesEnum.Totp)}
|
||||
>
|
||||
${msg("TOTP Authenticators")}
|
||||
</option>
|
||||
<option
|
||||
value=${DeviceClassesEnum.Webauthn}
|
||||
?selected=${this.isDeviceClassSelected(DeviceClassesEnum.Webauthn)}
|
||||
>
|
||||
${msg("WebAuthn Authenticators")}
|
||||
</option>
|
||||
<option
|
||||
value=${DeviceClassesEnum.Duo}
|
||||
?selected=${this.isDeviceClassSelected(DeviceClassesEnum.Duo)}
|
||||
>
|
||||
${msg("Duo Authenticators")}
|
||||
</option>
|
||||
<option
|
||||
value=${DeviceClassesEnum.Sms}
|
||||
?selected=${this.isDeviceClassSelected(DeviceClassesEnum.Sms)}
|
||||
>
|
||||
${msg("SMS-based Authenticators")}
|
||||
</option>
|
||||
</select>
|
||||
<ak-checkbox-group
|
||||
name="users"
|
||||
class="user-field-select"
|
||||
.options=${authenticators}
|
||||
.value=${authenticators
|
||||
.map((authenticator) => authenticator[0])
|
||||
.filter((name) =>
|
||||
this.isDeviceClassSelected(name as DeviceClassesEnum),
|
||||
)}
|
||||
></ak-checkbox-group>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Device classes which can be used to authenticate.")}
|
||||
</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Hold control/command to select multiple items.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Last validation threshold")}
|
||||
|
||||
@ -1,7 +1,12 @@
|
||||
import { RenderFlowOption } from "@goauthentik/admin/flows/utils";
|
||||
import { BaseStageForm } from "@goauthentik/admin/stages/BaseStageForm";
|
||||
import {
|
||||
DataProvision,
|
||||
DualSelectPair,
|
||||
} from "@goauthentik/authentik/elements/ak-dual-select/types";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { first } from "@goauthentik/common/utils";
|
||||
import "@goauthentik/elements/ak-dual-select/ak-dual-select-provider";
|
||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
import "@goauthentik/elements/forms/Radio";
|
||||
import "@goauthentik/elements/forms/SearchSelect";
|
||||
@ -11,8 +16,8 @@ import { TemplateResult, html } from "lit";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
|
||||
import {
|
||||
AuthenticateWebAuthnStage,
|
||||
AuthenticatorAttachmentEnum,
|
||||
AuthenticatorWebAuthnStage,
|
||||
Flow,
|
||||
FlowsApi,
|
||||
FlowsInstancesListDesignationEnum,
|
||||
@ -20,28 +25,39 @@ import {
|
||||
ResidentKeyRequirementEnum,
|
||||
StagesApi,
|
||||
UserVerificationEnum,
|
||||
WebAuthnDeviceType,
|
||||
} from "@goauthentik/api";
|
||||
|
||||
@customElement("ak-stage-authenticator-webauthn-form")
|
||||
export class AuthenticateWebAuthnStageForm extends BaseStageForm<AuthenticateWebAuthnStage> {
|
||||
loadInstance(pk: string): Promise<AuthenticateWebAuthnStage> {
|
||||
export class AuthenticatorWebAuthnStageForm extends BaseStageForm<AuthenticatorWebAuthnStage> {
|
||||
deviceTypeRestrictionPair(item: WebAuthnDeviceType): DualSelectPair {
|
||||
const label = item.description ? item.description : item.aaguid;
|
||||
return [
|
||||
item.aaguid,
|
||||
html`<div class="selection-main">${label}</div>
|
||||
<div class="selection-desc">${item.aaguid}</div>`,
|
||||
label,
|
||||
];
|
||||
}
|
||||
|
||||
loadInstance(pk: string): Promise<AuthenticatorWebAuthnStage> {
|
||||
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorWebauthnRetrieve({
|
||||
stageUuid: pk,
|
||||
});
|
||||
}
|
||||
|
||||
async send(data: AuthenticateWebAuthnStage): Promise<AuthenticateWebAuthnStage> {
|
||||
async send(data: AuthenticatorWebAuthnStage): Promise<AuthenticatorWebAuthnStage> {
|
||||
if (data.authenticatorAttachment?.toString() === "") {
|
||||
data.authenticatorAttachment = null;
|
||||
}
|
||||
if (this.instance) {
|
||||
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorWebauthnUpdate({
|
||||
stageUuid: this.instance.pk || "",
|
||||
authenticateWebAuthnStageRequest: data,
|
||||
authenticatorWebAuthnStageRequest: data,
|
||||
});
|
||||
} else {
|
||||
return new StagesApi(DEFAULT_CONFIG).stagesAuthenticatorWebauthnCreate({
|
||||
authenticateWebAuthnStageRequest: data,
|
||||
authenticatorWebAuthnStageRequest: data,
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -164,6 +180,38 @@ export class AuthenticateWebAuthnStageForm extends BaseStageForm<AuthenticateWeb
|
||||
>
|
||||
</ak-radio>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Device type restrictions")}
|
||||
name="deviceTypeRestrictions"
|
||||
>
|
||||
<ak-dual-select-provider
|
||||
.provider=${(page: number, search?: string): Promise<DataProvision> => {
|
||||
return new StagesApi(DEFAULT_CONFIG)
|
||||
.stagesAuthenticatorWebauthnDeviceTypesList({
|
||||
page: page,
|
||||
search: search,
|
||||
})
|
||||
.then((results) => {
|
||||
return {
|
||||
pagination: results.pagination,
|
||||
options: results.results.map(
|
||||
this.deviceTypeRestrictionPair,
|
||||
),
|
||||
};
|
||||
});
|
||||
}}
|
||||
.selected=${(this.instance?.deviceTypeRestrictionsObj ?? []).map(
|
||||
this.deviceTypeRestrictionPair,
|
||||
)}
|
||||
available-label="${msg("Available Device types")}"
|
||||
selected-label="${msg("Selected Device types")}"
|
||||
></ak-dual-select-provider>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Optionally restrict which WebAuthn device types may be used. When no device types are selected, all devices are allowed.",
|
||||
)}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal
|
||||
label=${msg("Configuration flow")}
|
||||
name="configureFlow"
|
||||
@ -2,12 +2,13 @@ import "@goauthentik/admin/common/ak-flow-search/ak-flow-search";
|
||||
import { BaseStageForm } from "@goauthentik/admin/stages/BaseStageForm";
|
||||
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
|
||||
import { first, groupBy } from "@goauthentik/common/utils";
|
||||
import "@goauthentik/elements/ak-checkbox-group/ak-checkbox-group.js";
|
||||
import "@goauthentik/elements/forms/FormGroup";
|
||||
import "@goauthentik/elements/forms/HorizontalFormElement";
|
||||
import "@goauthentik/elements/forms/SearchSelect";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, html } from "lit";
|
||||
import { TemplateResult, css, html } from "lit";
|
||||
import { customElement } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
@ -24,6 +25,17 @@ import {
|
||||
|
||||
@customElement("ak-stage-identification-form")
|
||||
export class IdentificationStageForm extends BaseStageForm<IdentificationStage> {
|
||||
static get styles() {
|
||||
return [
|
||||
...super.styles,
|
||||
css`
|
||||
ak-checkbox-group::part(checkbox-group) {
|
||||
padding-top: var(--pf-c-form--m-horizontal__group-label--md--PaddingTop);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
loadInstance(pk: string): Promise<IdentificationStage> {
|
||||
return new StagesApi(DEFAULT_CONFIG).stagesIdentificationRetrieve({
|
||||
stageUuid: pk,
|
||||
@ -60,6 +72,12 @@ export class IdentificationStageForm extends BaseStageForm<IdentificationStage>
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
const userSelectFields = [
|
||||
{ name: UserFieldsEnum.Username, label: msg("Username") },
|
||||
{ name: UserFieldsEnum.Email, label: msg("Email") },
|
||||
{ name: UserFieldsEnum.Upn, label: msg("UPN") },
|
||||
];
|
||||
|
||||
return html`<span>
|
||||
${msg("Let the user identify themselves with their username or Email address.")}
|
||||
</span>
|
||||
@ -75,34 +93,18 @@ export class IdentificationStageForm extends BaseStageForm<IdentificationStage>
|
||||
<span slot="header"> ${msg("Stage-specific settings")} </span>
|
||||
<div slot="body" class="pf-c-form">
|
||||
<ak-form-element-horizontal label=${msg("User fields")} name="userFields">
|
||||
<select class="pf-c-form-control" multiple>
|
||||
<option
|
||||
value=${UserFieldsEnum.Username}
|
||||
?selected=${this.isUserFieldSelected(UserFieldsEnum.Username)}
|
||||
>
|
||||
${msg("Username")}
|
||||
</option>
|
||||
<option
|
||||
value=${UserFieldsEnum.Email}
|
||||
?selected=${this.isUserFieldSelected(UserFieldsEnum.Email)}
|
||||
>
|
||||
${msg("Email")}
|
||||
</option>
|
||||
<option
|
||||
value=${UserFieldsEnum.Upn}
|
||||
?selected=${this.isUserFieldSelected(UserFieldsEnum.Upn)}
|
||||
>
|
||||
${msg("UPN")}
|
||||
</option>
|
||||
</select>
|
||||
<ak-checkbox-group
|
||||
class="user-field-select"
|
||||
.options=${userSelectFields}
|
||||
.value=${userSelectFields
|
||||
.map(({ name }) => name)
|
||||
.filter((name) => this.isUserFieldSelected(name))}
|
||||
></ak-checkbox-group>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg(
|
||||
"Fields a user can identify themselves with. If no fields are selected, the user will only be able to use sources.",
|
||||
)}
|
||||
</p>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Hold control/command to select multiple items.")}
|
||||
</p>
|
||||
</ak-form-element-horizontal>
|
||||
<ak-form-element-horizontal label=${msg("Password stage")} name="passwordStage">
|
||||
<ak-search-select
|
||||
|
||||
@ -54,6 +54,21 @@ export class PasswordStageForm extends BaseStageForm<PasswordStage> {
|
||||
}
|
||||
|
||||
renderForm(): TemplateResult {
|
||||
const backends = [
|
||||
{
|
||||
name: BackendsEnum.CoreAuthInbuiltBackend,
|
||||
label: msg("User database + standard password"),
|
||||
},
|
||||
{
|
||||
name: BackendsEnum.CoreAuthTokenBackend,
|
||||
label: msg("User database + app passwords"),
|
||||
},
|
||||
{
|
||||
name: BackendsEnum.SourcesLdapAuthLdapBackend,
|
||||
label: msg("User database + LDAP password"),
|
||||
},
|
||||
];
|
||||
|
||||
return html` <span>
|
||||
${msg("Validate the user's password against the selected backend(s).")}
|
||||
</span>
|
||||
@ -73,32 +88,13 @@ export class PasswordStageForm extends BaseStageForm<PasswordStage> {
|
||||
?required=${true}
|
||||
name="backends"
|
||||
>
|
||||
<select name="users" class="pf-c-form-control" multiple>
|
||||
<option
|
||||
value=${BackendsEnum.CoreAuthInbuiltBackend}
|
||||
?selected=${this.isBackendSelected(
|
||||
BackendsEnum.CoreAuthInbuiltBackend,
|
||||
)}
|
||||
>
|
||||
${msg("User database + standard password")}
|
||||
</option>
|
||||
<option
|
||||
value=${BackendsEnum.CoreAuthTokenBackend}
|
||||
?selected=${this.isBackendSelected(
|
||||
BackendsEnum.CoreAuthTokenBackend,
|
||||
)}
|
||||
>
|
||||
${msg("User database + app passwords")}
|
||||
</option>
|
||||
<option
|
||||
value=${BackendsEnum.SourcesLdapAuthLdapBackend}
|
||||
?selected=${this.isBackendSelected(
|
||||
BackendsEnum.SourcesLdapAuthLdapBackend,
|
||||
)}
|
||||
>
|
||||
${msg("User database + LDAP password")}
|
||||
</option>
|
||||
</select>
|
||||
<ak-checkbox-group
|
||||
class="user-field-select"
|
||||
.options=${backends}
|
||||
.value=${backends
|
||||
.map(({ name }) => name)
|
||||
.filter((name) => this.isBackendSelected(name))}
|
||||
></ak-checkbox-group>
|
||||
<p class="pf-c-form__helper-text">
|
||||
${msg("Selection of backends to test the password against.")}
|
||||
</p>
|
||||
|
||||
112
web/src/elements/ak-checkbox-group/ak-checkbox-group.stories.ts
Normal file
112
web/src/elements/ak-checkbox-group/ak-checkbox-group.stories.ts
Normal file
@ -0,0 +1,112 @@
|
||||
import "@goauthentik/elements/messages/MessageContainer";
|
||||
import { Meta } from "@storybook/web-components";
|
||||
|
||||
import { TemplateResult, html } from "lit";
|
||||
|
||||
import "./ak-checkbox-group";
|
||||
import { CheckboxGroup as AkCheckboxGroup } from "./ak-checkbox-group";
|
||||
|
||||
const metadata: Meta<AkCheckboxGroup> = {
|
||||
title: "Elements / Checkbox Group",
|
||||
component: "ak-checkbox-group",
|
||||
parameters: {
|
||||
docs: {
|
||||
description: {
|
||||
component: "A stylized value control for check buttons",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default metadata;
|
||||
|
||||
const container = (testItem: TemplateResult) =>
|
||||
html` <div style="background: #fff; padding: 2em">
|
||||
<style>
|
||||
li {
|
||||
display: block;
|
||||
}
|
||||
p {
|
||||
margin-top: 1em;
|
||||
}
|
||||
</style>
|
||||
|
||||
${testItem}
|
||||
|
||||
<ul id="check-message-pad" style="margin-top: 1em"></ul>
|
||||
</div>`;
|
||||
|
||||
const testOptions = [
|
||||
{ label: "Option One: funky", name: "funky" },
|
||||
{ label: "Option Two: invalid", name: "invalid" },
|
||||
{ label: "Option Three: weird", name: "weird" },
|
||||
];
|
||||
|
||||
export const CheckboxGroup = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const displayChange = (ev: any) => {
|
||||
document.getElementById("check-message-pad")!.innerHTML = `
|
||||
<p>Values selected on target: ${ev.target.value.join(", ")}</p>
|
||||
<p>Values sent in event: ${ev.detail.join(", ")}</p>
|
||||
<p>Values present as data-ak-control: <kbd>${JSON.stringify(ev.target.json, null)}</kbd></p>`;
|
||||
};
|
||||
|
||||
return container(
|
||||
html` <p style="max-width: 50ch; padding-bottom: 1rem;">
|
||||
Evented example. Intercept the <kbd>input</kbd> event and display the value seen in
|
||||
the event target.
|
||||
</p>
|
||||
|
||||
<ak-checkbox-group
|
||||
@change=${displayChange}
|
||||
name="ak-test-check-input"
|
||||
.options=${testOptions}
|
||||
></ak-checkbox-group>`,
|
||||
);
|
||||
};
|
||||
|
||||
type FDType = [string, string | FormDataEntryValue];
|
||||
|
||||
export const FormCheckboxGroup = () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const displayChange = (ev: any) => {
|
||||
ev.preventDefault();
|
||||
const formData = new FormData(ev.target);
|
||||
|
||||
const valList = Array.from(formData)
|
||||
.map(([_key, val]: FDType) => val)
|
||||
.join(", ");
|
||||
|
||||
const fdList = Array.from(formData)
|
||||
.map(
|
||||
([key, val]: FDType) =>
|
||||
`${encodeURIComponent(key)}=${encodeURIComponent(val as string)}`,
|
||||
)
|
||||
.join("&");
|
||||
|
||||
document.getElementById("check-message-pad")!.innerHTML = `
|
||||
<p>Values as seen in \`form.formData\`: ${valList}</p>
|
||||
<p>Values as seen in x-form-encoded format: <kbd>${fdList}</kbd></p>`;
|
||||
};
|
||||
|
||||
return container(
|
||||
html`<p style="max-width: 50ch; padding-bottom: 1rem;">
|
||||
FormData example. This variant emits the same events and exhibits the same behavior
|
||||
as the above, but instead of monitoring for 'change' events on the checkbox group,
|
||||
we monitor for the user pressing the 'submit' button. What is displayed is the
|
||||
values as understood by the <form> object, via its internal \`formData\`
|
||||
field, to demonstrate that this component works with forms as if it were a native
|
||||
form element.
|
||||
</p>
|
||||
|
||||
<form @submit=${displayChange}>
|
||||
<ak-checkbox-group
|
||||
name="ak-test-checkgroup-input"
|
||||
.options=${testOptions}
|
||||
></ak-checkbox-group>
|
||||
<button type="submit" style="margin-top: 2em">
|
||||
<em><strong>Submit</strong></em>
|
||||
</button>
|
||||
</form>`,
|
||||
);
|
||||
};
|
||||
212
web/src/elements/ak-checkbox-group/ak-checkbox-group.ts
Normal file
212
web/src/elements/ak-checkbox-group/ak-checkbox-group.ts
Normal file
@ -0,0 +1,212 @@
|
||||
import { AKElement } from "@goauthentik/elements/Base";
|
||||
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
|
||||
|
||||
import { msg } from "@lit/localize";
|
||||
import { TemplateResult, css, html } from "lit";
|
||||
import { customElement, property, queryAll } from "lit/decorators.js";
|
||||
import { map } from "lit/directives/map.js";
|
||||
|
||||
import PFCheck from "@patternfly/patternfly/components/Check/check.css";
|
||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||
import PFBase from "@patternfly/patternfly/patternfly-base.css";
|
||||
|
||||
type CheckboxKv = { name: string; label: string | TemplateResult };
|
||||
type CheckboxPr = [string, string | TemplateResult];
|
||||
export type CheckboxPair = CheckboxKv | CheckboxPr;
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const isCheckboxPr = (t: any): t is CheckboxPr => Array.isArray(t);
|
||||
function* kvToPairs(items: CheckboxPair[]): Iterable<CheckboxPr> {
|
||||
for (const item of items) {
|
||||
yield isCheckboxPr(item) ? item : [item.name, item.label];
|
||||
}
|
||||
}
|
||||
|
||||
const AkElementWithCustomEvents = CustomEmitterElement(AKElement);
|
||||
|
||||
/**
|
||||
* @element ak-checkbox-group
|
||||
*
|
||||
* @class CheckboxGroup
|
||||
*
|
||||
* @description
|
||||
* CheckboxGroup renders a collection of checkboxes in a linear list. Multiple
|
||||
* checkboxes may be picked.
|
||||
*
|
||||
* @attr {options} - An array of either `[string, string | TemplateResult]` or
|
||||
* `{ name: string, label: string | TemplateResult }`. The first value or
|
||||
* `name` field must be a valid HTML identifier compatible with the HTML
|
||||
* `name` attribute.
|
||||
*
|
||||
* @attr {value} - An array of `name` values corresponding to the options that
|
||||
* are selected when the element is rendered.
|
||||
*
|
||||
* @attr {name} - The name of this element as it will appear in any <form>
|
||||
* transaction
|
||||
*
|
||||
* @attr {required} - If true, and if name is set, and no values are chosen,
|
||||
* will automatically fail a form `submit` event, providing a warning
|
||||
* message for any labeling. Note: if `name` is not set, this has no effect,
|
||||
* and a warn() will appear on the console.
|
||||
*
|
||||
* @event {input} - Fired when the component's value has changed. Current value
|
||||
* as an array of `name` will be in the `Event.detail` field.
|
||||
*
|
||||
* @event {change} - Fired when the component's value has changed. Current value
|
||||
* as an array of `name` will be in the `Event.detail` field.
|
||||
*
|
||||
* @csspart checkbox - The div containing the checkbox item and the label
|
||||
* @csspart label - the label
|
||||
* @csspart input - the input item
|
||||
* @csspart checkbox-group - the wrapper div with flexbox control
|
||||
*
|
||||
* ## Bigger hit area
|
||||
*
|
||||
* Providing properly formatted names for selections allows the element to
|
||||
* associate the label with the event, so the entire horizontal area from
|
||||
* checkbox to end-of-label will be the hit area.
|
||||
*
|
||||
* ## FormAssociated compliance
|
||||
*
|
||||
* If a <form> component is a parent, this component will correctly send its
|
||||
* values to the form for `x-form-encoded` data; multiples will appear in the
|
||||
* form of `name=value1&name=value2` format, and must be unpacked into an array
|
||||
* correctly on the server side according to the CGI (common gateway interface)
|
||||
* protocol.
|
||||
*
|
||||
*/
|
||||
|
||||
@customElement("ak-checkbox-group")
|
||||
export class CheckboxGroup extends AkElementWithCustomEvents {
|
||||
static get styles() {
|
||||
return [
|
||||
PFBase,
|
||||
PFForm,
|
||||
PFCheck,
|
||||
css`
|
||||
.pf-c-form__group-control {
|
||||
padding-top: calc(
|
||||
var(--pf-c-form--m-horizontal__group-label--md--PaddingTop) * 1.3
|
||||
);
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
||||
static get formAssociated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@property({ type: Array })
|
||||
options: CheckboxPair[] = [];
|
||||
|
||||
@property({ type: Array })
|
||||
value: string[] = [];
|
||||
|
||||
@property({ type: String })
|
||||
name?: string;
|
||||
|
||||
@property({ type: Boolean })
|
||||
required = false;
|
||||
|
||||
@queryAll('input[type="checkbox"]')
|
||||
checkboxes!: NodeListOf<HTMLInputElement>;
|
||||
|
||||
internals?: ElementInternals;
|
||||
|
||||
get json() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private get formValue() {
|
||||
if (this.name === undefined) {
|
||||
throw new Error("This cannot be called without having the name set.");
|
||||
}
|
||||
const name = this.name;
|
||||
const entries = new FormData();
|
||||
this.value.forEach((v) => entries.append(name, v));
|
||||
return entries;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.onClick = this.onClick.bind(this);
|
||||
this.dataset.akControl = "true";
|
||||
}
|
||||
|
||||
onClick(ev: Event) {
|
||||
ev.stopPropagation();
|
||||
this.value = Array.from(this.checkboxes)
|
||||
.filter((checkbox) => checkbox.checked)
|
||||
.map((checkbox) => checkbox.name);
|
||||
this.dispatchCustomEvent("change", this.value);
|
||||
this.dispatchCustomEvent("input", this.value);
|
||||
if (this.internals) {
|
||||
this.internals.setValidity({});
|
||||
if (this.required && this.value.length === 0) {
|
||||
this.internals.setValidity(
|
||||
{
|
||||
valueMissing: true,
|
||||
},
|
||||
msg("A selection is required"),
|
||||
this,
|
||||
);
|
||||
}
|
||||
this.internals.setFormValue(this.formValue);
|
||||
}
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
if (this.name && !this.internals) {
|
||||
this.internals = this.attachInternals();
|
||||
}
|
||||
if (this.internals && this.name) {
|
||||
this.internals.ariaRequired = this.required ? "true" : "false";
|
||||
}
|
||||
if (this.required && !this.internals) {
|
||||
console.warn(
|
||||
"Setting `required` on ak-checkbox-group has no effect when the `name` attribute is unset",
|
||||
);
|
||||
}
|
||||
// These are necessary to prevent the input components' own events from
|
||||
// leaking out. This helps maintain the illusion that this component
|
||||
// behaves similarly to the multiple selection behavior of, well,
|
||||
// <select multiple>.
|
||||
this.addEventListener("input", (ev) => {
|
||||
ev.stopPropagation();
|
||||
});
|
||||
this.addEventListener("change", (ev) => {
|
||||
ev.stopPropagation();
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const renderOne = ([name, label]: CheckboxPr) => {
|
||||
const selected = this.value.includes(name);
|
||||
const blockFwd = (e: Event) => {
|
||||
e.stopImmediatePropagation();
|
||||
};
|
||||
|
||||
return html` <div part="checkbox" class="pf-c-check" @click=${this.onClick}>
|
||||
<input
|
||||
part="input"
|
||||
@change=${blockFwd}
|
||||
@input=${blockFwd}
|
||||
name="${name}"
|
||||
class="pf-c-check__input"
|
||||
type="checkbox"
|
||||
?checked=${selected}
|
||||
id="ak-check-${name}"
|
||||
/>
|
||||
<label part="label" class="pf-c-check__label" for="ak-check-${name}"
|
||||
>${label}</label
|
||||
>
|
||||
</div>`;
|
||||
};
|
||||
|
||||
return html`<div part="checkbox-group" class="pf-c-form__group-control pf-m-stack">
|
||||
${map(kvToPairs(this.options), renderOne)}
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,7 @@ import { BaseStage } from "@goauthentik/flow/stages/base";
|
||||
import { msg, str } from "@lit/localize";
|
||||
import { CSSResult, TemplateResult, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { ifDefined } from "lit/directives/if-defined.js";
|
||||
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFForm from "@patternfly/patternfly/components/Form/form.css";
|
||||
@ -130,6 +131,17 @@ export class WebAuthnAuthenticatorRegisterStage extends BaseStage<
|
||||
</header>
|
||||
<div class="pf-c-login__main-body">
|
||||
<form class="pf-c-form">
|
||||
<ak-form-static
|
||||
class="pf-c-form__group"
|
||||
userAvatar="${this.challenge.pendingUserAvatar}"
|
||||
user=${this.challenge.pendingUser}
|
||||
>
|
||||
<div slot="link">
|
||||
<a href="${ifDefined(this.challenge.flowInfo?.cancelUrl)}"
|
||||
>${msg("Not you?")}</a
|
||||
>
|
||||
</div>
|
||||
</ak-form-static>
|
||||
<ak-empty-state
|
||||
?loading="${this.registerRunning}"
|
||||
header=${this.registerRunning
|
||||
|
||||
@ -6472,6 +6472,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -6741,6 +6741,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -6388,6 +6388,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -8501,6 +8501,9 @@ Les liaisons avec les groupes/utilisateurs sont vérifiées par rapport à l'uti
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -8329,6 +8329,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -8172,6 +8172,9 @@ Bindingen naar groepen/gebruikers worden gecontroleerd tegen de gebruiker van de
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -6593,6 +6593,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -8445,4 +8445,7 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body></file></xliff>
|
||||
|
||||
@ -6381,6 +6381,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -5299,6 +5299,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0"?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<?xml version="1.0" ?><xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
|
||||
<file target-language="zh-Hans" source-language="en" original="lit-localize-inputs" datatype="plaintext">
|
||||
<body>
|
||||
<trans-unit id="s4caed5b7a7e5d89b">
|
||||
@ -596,9 +596,9 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="saa0e2675da69651b">
|
||||
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
|
||||
<target>未找到 URL "
|
||||
<x id="0" equiv-text="${this.url}"/>"。</target>
|
||||
<source>The URL "<x id="0" equiv-text="${this.url}"/>" was not found.</source>
|
||||
<target>未找到 URL "
|
||||
<x id="0" equiv-text="${this.url}"/>"。</target>
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s58cd9c2fe836d9c6">
|
||||
@ -1040,8 +1040,8 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="sa8384c9c26731f83">
|
||||
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
|
||||
<target>要允许任何重定向 URI,请将此值设置为 ".*"。请注意这可能带来的安全影响。</target>
|
||||
<source>To allow any redirect URI, set this value to ".*". Be aware of the possible security implications this can have.</source>
|
||||
<target>要允许任何重定向 URI,请将此值设置为 ".*"。请注意这可能带来的安全影响。</target>
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s55787f4dfcdce52b">
|
||||
@ -1782,8 +1782,8 @@
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="sa90b7809586c35ce">
|
||||
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
|
||||
<target>输入完整 URL、相对路径,或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。</target>
|
||||
<source>Either input a full URL, a relative path, or use 'fa://fa-test' to use the Font Awesome icon "fa-test".</source>
|
||||
<target>输入完整 URL、相对路径,或者使用 'fa://fa-test' 来使用 Font Awesome 图标 "fa-test"。</target>
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s0410779cb47de312">
|
||||
@ -2961,8 +2961,8 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s76768bebabb7d543">
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
|
||||
<target>包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
|
||||
<source>Field which contains members of a group. Note that if using the "memberUid" field, the value is assumed to contain a relative distinguished name. e.g. 'memberUid=some-user' instead of 'memberUid=cn=some-user,ou=groups,...'</source>
|
||||
<target>包含组成员的字段。请注意,如果使用 "memberUid" 字段,则假定该值包含相对可分辨名称。例如,'memberUid=some-user' 而不是 'memberUid=cn=some-user,ou=groups,...'</target>
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s026555347e589f0e">
|
||||
@ -3739,8 +3739,8 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s7b1fba26d245cb1c">
|
||||
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
|
||||
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。</target>
|
||||
<source>When using an external logging solution for archiving, this can be set to "minutes=5".</source>
|
||||
<target>使用外部日志记录解决方案进行存档时,可以将其设置为 "minutes=5"。</target>
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s44536d20bb5c8257">
|
||||
@ -3916,10 +3916,10 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="sa95a538bfbb86111">
|
||||
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
|
||||
<source>Are you sure you want to update <x id="0" equiv-text="${this.objectLabel}"/> "<x id="1" equiv-text="${this.obj?.name}"/>"?</source>
|
||||
<target>您确定要更新
|
||||
<x id="0" equiv-text="${this.objectLabel}"/>"
|
||||
<x id="1" equiv-text="${this.obj?.name}"/>" 吗?</target>
|
||||
<x id="0" equiv-text="${this.objectLabel}"/>"
|
||||
<x id="1" equiv-text="${this.obj?.name}"/>" 吗?</target>
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="sc92d7cfb6ee1fec6">
|
||||
@ -5000,7 +5000,7 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="sdf1d8edef27236f0">
|
||||
<source>A "roaming" authenticator, like a YubiKey</source>
|
||||
<source>A "roaming" authenticator, like a YubiKey</source>
|
||||
<target>像 YubiKey 这样的“漫游”身份验证器</target>
|
||||
|
||||
</trans-unit>
|
||||
@ -5335,10 +5335,10 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s2d5f69929bb7221d">
|
||||
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
|
||||
<source><x id="0" equiv-text="${prompt.name}"/> ("<x id="1" equiv-text="${prompt.fieldKey}"/>", of type <x id="2" equiv-text="${prompt.type}"/>)</source>
|
||||
<target>
|
||||
<x id="0" equiv-text="${prompt.name}"/>("
|
||||
<x id="1" equiv-text="${prompt.fieldKey}"/>",类型为
|
||||
<x id="0" equiv-text="${prompt.name}"/>("
|
||||
<x id="1" equiv-text="${prompt.fieldKey}"/>",类型为
|
||||
<x id="2" equiv-text="${prompt.type}"/>)</target>
|
||||
|
||||
</trans-unit>
|
||||
@ -5387,7 +5387,7 @@ doesn't pass when either or both of the selected options are equal or above the
|
||||
|
||||
</trans-unit>
|
||||
<trans-unit id="s1608b2f94fa0dbd4">
|
||||
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
|
||||
<source>If set to a duration above 0, the user will have the option to choose to "stay signed in", which will extend their session by the time specified here.</source>
|
||||
<target>如果设置时长大于 0,用户可以选择“保持登录”选项,这将使用户的会话延长此处设置的时间。</target>
|
||||
|
||||
</trans-unit>
|
||||
@ -7839,7 +7839,7 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<target>成功创建用户并添加到组 <x id="0" equiv-text="${this.group.name}"/></target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s824e0943a7104668">
|
||||
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
|
||||
<source>This user will be added to the group "<x id="0" equiv-text="${this.targetGroup.name}"/>".</source>
|
||||
<target>此用户将会被添加到组 &quot;<x id="0" equiv-text="${this.targetGroup.name}"/>&quot;。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="s62e7f6ed7d9cb3ca">
|
||||
@ -8519,7 +8519,11 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
<target>将 OAuth 或 SAML 源注入到流程执行过程中。这允许额外的用户验证,或者基于不同的用户标识符(用户名、电子邮件地址等)动态访问不同的源。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
<target>需要进行选择</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
||||
@ -6429,6 +6429,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -8519,6 +8519,10 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
<target>将 OAuth 或 SAML 源注入到流程执行过程中。这允许额外的用户验证,或者基于不同的用户标识符(用户名、电子邮件地址等)动态访问不同的源。</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
<target>需要进行选择</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -8290,6 +8290,9 @@ Bindings to groups/users are checked against the user of the event.</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="s02160dc6adba3456">
|
||||
<source>Inject an OAuth or SAML Source into the flow execution. This allows for additional user verification, or to dynamically access different sources for different user identifiers (username, email address, etc).</source>
|
||||
</trans-unit>
|
||||
<trans-unit id="sc7d071fb5cc1f6bf">
|
||||
<source>A selection is required</source>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
|
||||
@ -4,4 +4,26 @@ title: WebAuthn authenticator setup stage
|
||||
|
||||
This stage configures a WebAuthn-based Authenticator. This can either be a browser, biometrics or a Security stick like a YubiKey.
|
||||
|
||||
There are no stage-specific settings.
|
||||
### `User verification`
|
||||
|
||||
Configure if authentik should require, prefer or discourage user verification for the authenticator. For example when using a virtual authenticator like Windows Hello, this setting controls if a PIN is required.
|
||||
|
||||
### `Resident key requirement`
|
||||
|
||||
Configure if the created authenticator is stored in the encrypted memory on the device or in persistent memory. When configuring [passwordless login](../identification/index.md#passwordless-flow), this should be set to either _Preferred_ or _Required_, otherwise the authenticator cannot be used for passwordless authentication.
|
||||
|
||||
### `Authenticator Attachment`
|
||||
|
||||
Configure if authentik will require either a removable device (like a YubiKey, Google Titan, etc) or a non-removable device (like Windows Hello, TouchID or password managers), or not send a requirement.
|
||||
|
||||
### `Device type restrictions`
|
||||
|
||||
:::info
|
||||
Requires authentik 2024.4
|
||||
:::
|
||||
|
||||
Optionally restrict the types of devices allowed to be enrolled. This option can be used to ensure users are only able to enroll FIPS-compliant devices for example.
|
||||
|
||||
When no restrictions are selected, all device types are allowed.
|
||||
|
||||
As authentik does not know of all possible device types, it is possible to select the special option `authentik: Unknown devices` to allow unknown devices.
|
||||
|
||||
@ -104,8 +104,8 @@ Create a provider for Nextcloud. In the Admin Interface, go to _Applications_ ->
|
||||
|
||||
Before continuing, make sure to take note of your `client ID` and `secret ID`. Don't worry you can go back to see/change them at any time.
|
||||
|
||||
:::warning
|
||||
Currently there is a bug in the Nextcloud OIDC app, that is [limiting the size of the secret ID](https://github.com/nextcloud/user_oidc/issues/405) token to 64 characters. Since authentik uses 128 characters for a secret ID by default, you will need to trim it down to 64 characters in order to be able to set it in Nextcloud. Don't worry, 64 characters is still sufficiently long and should not compromise security.
|
||||
:::note
|
||||
There were an issue in the Nextcloud OIDC app that was [limiting the size of the secret ID](https://github.com/nextcloud/user_oidc/issues/405) token to 64 characters. This issue was fixed in December 2023, so make sure you update to the latest version of the [OpenID Connect user backend](https://apps.nextcloud.com/apps/user_oidc) application.
|
||||
:::
|
||||
|
||||
:::note
|
||||
|
||||
628
website/package-lock.json
generated
628
website/package-lock.json
generated
@ -9,12 +9,12 @@
|
||||
"version": "0.0.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^3.2.0",
|
||||
"@docusaurus/plugin-client-redirects": "^3.2.0",
|
||||
"@docusaurus/plugin-content-docs": "^3.2.0",
|
||||
"@docusaurus/preset-classic": "^3.2.0",
|
||||
"@docusaurus/theme-common": "^3.2.0",
|
||||
"@docusaurus/theme-mermaid": "^3.2.0",
|
||||
"@docusaurus/core": "^3.2.1",
|
||||
"@docusaurus/plugin-client-redirects": "^3.2.1",
|
||||
"@docusaurus/plugin-content-docs": "^3.2.1",
|
||||
"@docusaurus/preset-classic": "^3.2.1",
|
||||
"@docusaurus/theme-common": "^3.2.1",
|
||||
"@docusaurus/theme-mermaid": "^3.2.1",
|
||||
"@mdx-js/react": "^3.0.1",
|
||||
"clsx": "^2.1.0",
|
||||
"disqus-react": "^1.1.5",
|
||||
@ -30,12 +30,12 @@
|
||||
"remark-github": "^12.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.2.0",
|
||||
"@docusaurus/tsconfig": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/module-type-aliases": "3.2.1",
|
||||
"@docusaurus/tsconfig": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@types/react": "^18.2.74",
|
||||
"prettier": "3.2.5",
|
||||
"typescript": "~5.4.3"
|
||||
"typescript": "~5.4.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
@ -2187,9 +2187,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/core": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.2.0.tgz",
|
||||
"integrity": "sha512-WTO6vW4404nhTmK9NL+95nd13I1JveFwZ8iOBYxb4xt+N2S3KzY+mm+1YtWw2vV37FbYfH+w+KrlrRaWuy5Hzw==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/core/-/core-3.2.1.tgz",
|
||||
"integrity": "sha512-ZeMAqNvy0eBv2dThEeMuNzzuu+4thqMQakhxsgT5s02A8LqRcdkg+rbcnuNqUIpekQ4GRx3+M5nj0ODJhBXo9w==",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.23.3",
|
||||
"@babel/generator": "^7.23.3",
|
||||
@ -2201,13 +2201,13 @@
|
||||
"@babel/runtime": "^7.22.6",
|
||||
"@babel/runtime-corejs3": "^7.22.6",
|
||||
"@babel/traverse": "^7.22.8",
|
||||
"@docusaurus/cssnano-preset": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.0",
|
||||
"@docusaurus/mdx-loader": "3.2.0",
|
||||
"@docusaurus/cssnano-preset": "3.2.1",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/mdx-loader": "3.2.1",
|
||||
"@docusaurus/react-loadable": "5.5.2",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-common": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@svgr/webpack": "^6.5.1",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"babel-loader": "^9.1.3",
|
||||
@ -2273,40 +2273,14 @@
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/cssnano-preset": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.2.0.tgz",
|
||||
"integrity": "sha512-H88RXGUia7r/VF3XfyoA4kbwgpUZcKsObF6VvwBOP91EdArTf6lnHbJ/x8Ca79KS/zf98qaWyBGzW+5ez58Iyw==",
|
||||
"node_modules/@docusaurus/core/node_modules/@docusaurus/mdx-loader": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.2.1.tgz",
|
||||
"integrity": "sha512-Fs8tXhXKZjNkdGaOy1xSLXSwfjCMT73J3Zfrju2U16uGedRFRjgK0ojpK5tiC7TnunsL3tOFgp1BSMBRflX9gw==",
|
||||
"dependencies": {
|
||||
"cssnano-preset-advanced": "^5.3.10",
|
||||
"postcss": "^8.4.26",
|
||||
"postcss-sort-media-queries": "^4.4.1",
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/logger": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.2.0.tgz",
|
||||
"integrity": "sha512-Z1R1NcOGXZ8CkIJSvjvyxnuDDSlx/+1xlh20iVTw1DZRjonFmI3T3tTgk40YpXyWUYQpIgAoqqPMpuseMMdgRQ==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2",
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/mdx-loader": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.2.0.tgz",
|
||||
"integrity": "sha512-JtkI5o6R/rJSr1Y23cHKz085aBJCvJw3AYHihJ7r+mBX+O8EuQIynG0e6/XpbSCpr7Ino0U50UtxaXcEbFwg9Q==",
|
||||
"dependencies": {
|
||||
"@docusaurus/logger": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@mdx-js/mdx": "^3.0.0",
|
||||
"@slorber/remark-comment": "^1.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
@ -2337,13 +2311,39 @@
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/cssnano-preset": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/cssnano-preset/-/cssnano-preset-3.2.1.tgz",
|
||||
"integrity": "sha512-wTL9KuSSbMJjKrfu385HZEzAoamUsbKqwscAQByZw4k6Ja/RWpqgVvt/CbAC+aYEH6inLzOt+MjuRwMOrD3VBA==",
|
||||
"dependencies": {
|
||||
"cssnano-preset-advanced": "^5.3.10",
|
||||
"postcss": "^8.4.26",
|
||||
"postcss-sort-media-queries": "^4.4.1",
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/logger": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/logger/-/logger-3.2.1.tgz",
|
||||
"integrity": "sha512-0voOKJCn9RaM3np6soqEfo7SsVvf2C+CDTWhW+H/1AyBhybASpExtDEz+7ECck9TwPzFQ5tt+I3zVugUJbJWDg==",
|
||||
"dependencies": {
|
||||
"chalk": "^4.1.2",
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/module-type-aliases": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.2.0.tgz",
|
||||
"integrity": "sha512-jRSp9YkvBwwNz6Xgy0RJPsnie+Ebb//gy7GdbkJ2pW2gvvlYKGib2+jSF0pfIzvyZLulfCynS1KQdvDKdSl8zQ==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/module-type-aliases/-/module-type-aliases-3.2.1.tgz",
|
||||
"integrity": "sha512-FyViV5TqhL1vsM7eh29nJ5NtbRE6Ra6LP1PDcPvhwPSlA7eiWGRKAn3jWwMUcmjkos5SYY+sr0/feCdbM3eQHQ==",
|
||||
"dependencies": {
|
||||
"@docusaurus/react-loadable": "5.5.2",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@types/history": "^4.7.11",
|
||||
"@types/react": "*",
|
||||
"@types/react-router-config": "*",
|
||||
@ -2357,15 +2357,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-client-redirects": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.2.0.tgz",
|
||||
"integrity": "sha512-re5bgvYOgBHmevlI8HO3fZHL7mvX2lAULr4E89n/bQ5kgekLLhsaerWrAah22ZluMZyJC2439EGjR63E9Ba6KA==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-client-redirects/-/plugin-client-redirects-3.2.1.tgz",
|
||||
"integrity": "sha512-GgzuqwbqNQSP5s/ouUrOQFuHI8m4Rn8a5CHuWkwpqj+5lbQMsABcvsoiWjrH9M00CzN48q+slSbJy7rtHjn7zg==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-common": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"eta": "^2.2.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
@ -2380,17 +2380,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-content-blog": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.2.0.tgz",
|
||||
"integrity": "sha512-MABqwjSicyHmYEfQueMthPCz18JkVxhK3EGhXTSRWwReAZ0UTuw9pG6+Wo+uXAugDaIcJH28rVZSwTDINPm2bw==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-blog/-/plugin-content-blog-3.2.1.tgz",
|
||||
"integrity": "sha512-lOx0JfhlGZoZu6pEJfeEpSISZR5dQbJGGvb42IP13G5YThNHhG9R9uoWuo4IOimPqBC7sHThdLA3VLevk61Fsw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.0",
|
||||
"@docusaurus/mdx-loader": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-common": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/mdx-loader": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"feed": "^4.2.2",
|
||||
"fs-extra": "^11.1.1",
|
||||
@ -2410,19 +2410,57 @@
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-content-docs": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.2.0.tgz",
|
||||
"integrity": "sha512-uuqhahmsBnirxOz+SXksnWt7+wc+iN4ntxNRH48BUgo7QRNLATWjHCgI8t6zrMJxK4o+QL9DhLaPDlFHs91B3Q==",
|
||||
"node_modules/@docusaurus/plugin-content-blog/node_modules/@docusaurus/mdx-loader": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.2.1.tgz",
|
||||
"integrity": "sha512-Fs8tXhXKZjNkdGaOy1xSLXSwfjCMT73J3Zfrju2U16uGedRFRjgK0ojpK5tiC7TnunsL3tOFgp1BSMBRflX9gw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.0",
|
||||
"@docusaurus/mdx-loader": "3.2.0",
|
||||
"@docusaurus/module-type-aliases": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-common": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@mdx-js/mdx": "^3.0.0",
|
||||
"@slorber/remark-comment": "^1.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"estree-util-value-to-estree": "^3.0.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"image-size": "^1.0.2",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"mdast-util-to-string": "^4.0.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-directive": "^3.0.0",
|
||||
"remark-emoji": "^4.0.0",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tslib": "^2.6.0",
|
||||
"unified": "^11.0.3",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"vfile": "^6.0.1",
|
||||
"webpack": "^5.88.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-content-docs": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-docs/-/plugin-content-docs-3.2.1.tgz",
|
||||
"integrity": "sha512-GHe5b/lCskAR8QVbfWAfPAApvRZgqk7FN3sOHgjCtjzQACZxkHmq6QqyqZ8Jp45V7lVck4wt2Xw2IzBJ7Cz3bA==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/mdx-loader": "3.2.1",
|
||||
"@docusaurus/module-type-aliases": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@types/react-router-config": "^5.0.7",
|
||||
"combine-promises": "^1.1.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
@ -2440,16 +2478,54 @@
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-content-pages": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.2.0.tgz",
|
||||
"integrity": "sha512-4ofAN7JDsdb4tODO9OIrizWY5DmEJXr0eu+UDIkLqGP+gXXTahJZv8h2mlxO+lPXGXRCVBOfA14OG1hOYJVPwA==",
|
||||
"node_modules/@docusaurus/plugin-content-docs/node_modules/@docusaurus/mdx-loader": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.2.1.tgz",
|
||||
"integrity": "sha512-Fs8tXhXKZjNkdGaOy1xSLXSwfjCMT73J3Zfrju2U16uGedRFRjgK0ojpK5tiC7TnunsL3tOFgp1BSMBRflX9gw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/mdx-loader": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@mdx-js/mdx": "^3.0.0",
|
||||
"@slorber/remark-comment": "^1.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"estree-util-value-to-estree": "^3.0.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"image-size": "^1.0.2",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"mdast-util-to-string": "^4.0.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-directive": "^3.0.0",
|
||||
"remark-emoji": "^4.0.0",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tslib": "^2.6.0",
|
||||
"unified": "^11.0.3",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"vfile": "^6.0.1",
|
||||
"webpack": "^5.88.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-content-pages": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-content-pages/-/plugin-content-pages-3.2.1.tgz",
|
||||
"integrity": "sha512-TOqVfMVTAHqWNEGM94Drz+PUpHDbwFy6ucHFgyTx9zJY7wPNSG5EN+rd/mU7OvAi26qpOn2o9xTdUmb28QLjEQ==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/mdx-loader": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"fs-extra": "^11.1.1",
|
||||
"tslib": "^2.6.0",
|
||||
"webpack": "^5.88.1"
|
||||
@ -2462,14 +2538,52 @@
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-debug": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.2.0.tgz",
|
||||
"integrity": "sha512-p6WxtO5XZGz66y6QNQtCJwBefq4S6/w75XaXVvH1/2P9uaijvF7R+Cm2EWQZ5WsvA5wl//DFWblyDHRyVC207Q==",
|
||||
"node_modules/@docusaurus/plugin-content-pages/node_modules/@docusaurus/mdx-loader": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.2.1.tgz",
|
||||
"integrity": "sha512-Fs8tXhXKZjNkdGaOy1xSLXSwfjCMT73J3Zfrju2U16uGedRFRjgK0ojpK5tiC7TnunsL3tOFgp1BSMBRflX9gw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@mdx-js/mdx": "^3.0.0",
|
||||
"@slorber/remark-comment": "^1.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"estree-util-value-to-estree": "^3.0.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"image-size": "^1.0.2",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"mdast-util-to-string": "^4.0.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-directive": "^3.0.0",
|
||||
"remark-emoji": "^4.0.0",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tslib": "^2.6.0",
|
||||
"unified": "^11.0.3",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"vfile": "^6.0.1",
|
||||
"webpack": "^5.88.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-debug": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-debug/-/plugin-debug-3.2.1.tgz",
|
||||
"integrity": "sha512-AMKq8NuUKf2sRpN1m/sIbqbRbnmk+rSA+8mNU1LNxEl9BW9F/Gng8m9HKlzeyMPrf5XidzS1jqkuTLDJ6KIrFw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"fs-extra": "^11.1.1",
|
||||
"react-json-view-lite": "^1.2.0",
|
||||
"tslib": "^2.6.0"
|
||||
@ -2483,13 +2597,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-google-analytics": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.2.0.tgz",
|
||||
"integrity": "sha512-//TepJTEyAZSvBwHKEbXHu9xT/VkK3wUil2ZakKvQZYfUC01uWn6A1E3toa8R7WhCy1xPUeIukqmJy1Clg8njQ==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-analytics/-/plugin-google-analytics-3.2.1.tgz",
|
||||
"integrity": "sha512-/rJ+9u+Px0eTCiF4TNcNtj3kHf8cp6K1HCwOTdbsSlz6Xn21syZYcy+f1VM9wF6HrvUkXUcbM5TDCvg2IRL6bQ==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -2501,13 +2615,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-google-gtag": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.2.0.tgz",
|
||||
"integrity": "sha512-3s6zxlaMMb87MW2Rxy6EnSRDs0WDEQPuHilZZH402C8kOrUnIwlhlfjWZ4ZyLDziGl/Eec/DvD0PVqj0qHRomA==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-gtag/-/plugin-google-gtag-3.2.1.tgz",
|
||||
"integrity": "sha512-XtuJnlMvYfppeVdUyKiDIJAa/gTJKCQU92z8CLZZ9ibJdgVjFOLS10s0hIC0eL5z0U2u2loJz2rZ63HOkNHbBA==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@types/gtag.js": "^0.0.12",
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
@ -2520,13 +2634,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-google-tag-manager": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.2.0.tgz",
|
||||
"integrity": "sha512-rAKtsJ11vPHA7dTAqWCgyIy7AyFRF/lpI77Zd/4HKgqcIvIayVBvL3QtelhUazfYTLTH6ls6kQ9wjMcIFxRiGg==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-google-tag-manager/-/plugin-google-tag-manager-3.2.1.tgz",
|
||||
"integrity": "sha512-wiS/kE0Ny5pnjTxVCs8ljRnkL1RVMj59t6jmSsgEX7piDOoaXSMIUaoIt9ogS/v132uO0xEsxHstkRUZHQyPcQ==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
"engines": {
|
||||
@ -2538,16 +2652,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/plugin-sitemap": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.2.0.tgz",
|
||||
"integrity": "sha512-gnWDFt6MStjLkdtt63Lzc+14EPSd8B6mzJGJp9GQMvWDUoMAUijUqpVIHYQq+DPMcI4PJZ5I2nsl5XFf1vOldA==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/plugin-sitemap/-/plugin-sitemap-3.2.1.tgz",
|
||||
"integrity": "sha512-uWZ7AxzdeaQSTCwD2yZtOiEm9zyKU+wqCmi/Sf25kQQqqFSBZUStXfaQ8OHP9cecnw893ZpZ811rPhB/wfujJw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-common": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"fs-extra": "^11.1.1",
|
||||
"sitemap": "^7.1.1",
|
||||
"tslib": "^2.6.0"
|
||||
@ -2561,23 +2675,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/preset-classic": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.2.0.tgz",
|
||||
"integrity": "sha512-t7tXyk8kUgT7hUqEOgSJnPs+Foem9ucuan/a9QVYaVFCDjp92Sb2FpCY8bVasAokYCjodYe2LfpAoSCj5YDYWg==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/preset-classic/-/preset-classic-3.2.1.tgz",
|
||||
"integrity": "sha512-E3OHSmttpEBcSMhfPBq3EJMBxZBM01W1rnaCUTXy9EHvkmB5AwgTfW1PwGAybPAX579ntE03R+2zmXdizWfKnQ==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/plugin-content-blog": "3.2.0",
|
||||
"@docusaurus/plugin-content-docs": "3.2.0",
|
||||
"@docusaurus/plugin-content-pages": "3.2.0",
|
||||
"@docusaurus/plugin-debug": "3.2.0",
|
||||
"@docusaurus/plugin-google-analytics": "3.2.0",
|
||||
"@docusaurus/plugin-google-gtag": "3.2.0",
|
||||
"@docusaurus/plugin-google-tag-manager": "3.2.0",
|
||||
"@docusaurus/plugin-sitemap": "3.2.0",
|
||||
"@docusaurus/theme-classic": "3.2.0",
|
||||
"@docusaurus/theme-common": "3.2.0",
|
||||
"@docusaurus/theme-search-algolia": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0"
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/plugin-content-blog": "3.2.1",
|
||||
"@docusaurus/plugin-content-docs": "3.2.1",
|
||||
"@docusaurus/plugin-content-pages": "3.2.1",
|
||||
"@docusaurus/plugin-debug": "3.2.1",
|
||||
"@docusaurus/plugin-google-analytics": "3.2.1",
|
||||
"@docusaurus/plugin-google-gtag": "3.2.1",
|
||||
"@docusaurus/plugin-google-tag-manager": "3.2.1",
|
||||
"@docusaurus/plugin-sitemap": "3.2.1",
|
||||
"@docusaurus/theme-classic": "3.2.1",
|
||||
"@docusaurus/theme-common": "3.2.1",
|
||||
"@docusaurus/theme-search-algolia": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
@ -2600,22 +2714,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/theme-classic": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.2.0.tgz",
|
||||
"integrity": "sha512-4oSO5BQOJ5ja7WYdL6jK1n4J96tp+VJHamdwao6Ea252sA3W3vvR0otTflG4p4XVjNZH6hlPQoi5lKW0HeRgfQ==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-classic/-/theme-classic-3.2.1.tgz",
|
||||
"integrity": "sha512-+vSbnQyoWjc6vRZi4vJO2dBU02wqzynsai15KK+FANZudrYaBHtkbLZAQhgmxzBGVpxzi87gRohlMm+5D8f4tA==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/mdx-loader": "3.2.0",
|
||||
"@docusaurus/module-type-aliases": "3.2.0",
|
||||
"@docusaurus/plugin-content-blog": "3.2.0",
|
||||
"@docusaurus/plugin-content-docs": "3.2.0",
|
||||
"@docusaurus/plugin-content-pages": "3.2.0",
|
||||
"@docusaurus/theme-common": "3.2.0",
|
||||
"@docusaurus/theme-translations": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-common": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/mdx-loader": "3.2.1",
|
||||
"@docusaurus/module-type-aliases": "3.2.1",
|
||||
"@docusaurus/plugin-content-blog": "3.2.1",
|
||||
"@docusaurus/plugin-content-docs": "3.2.1",
|
||||
"@docusaurus/plugin-content-pages": "3.2.1",
|
||||
"@docusaurus/theme-common": "3.2.1",
|
||||
"@docusaurus/theme-translations": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"copy-text-to-clipboard": "^3.2.0",
|
||||
@ -2638,18 +2752,56 @@
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/theme-common": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.2.0.tgz",
|
||||
"integrity": "sha512-sFbw9XviNJJ+760kAcZCQMQ3jkNIznGqa6MQ70E5BnbP+ja36kGgPOfjcsvAcNey1H1Rkhh3p2Mhf4HVLdKVVw==",
|
||||
"node_modules/@docusaurus/theme-classic/node_modules/@docusaurus/mdx-loader": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.2.1.tgz",
|
||||
"integrity": "sha512-Fs8tXhXKZjNkdGaOy1xSLXSwfjCMT73J3Zfrju2U16uGedRFRjgK0ojpK5tiC7TnunsL3tOFgp1BSMBRflX9gw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/mdx-loader": "3.2.0",
|
||||
"@docusaurus/module-type-aliases": "3.2.0",
|
||||
"@docusaurus/plugin-content-blog": "3.2.0",
|
||||
"@docusaurus/plugin-content-docs": "3.2.0",
|
||||
"@docusaurus/plugin-content-pages": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-common": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@mdx-js/mdx": "^3.0.0",
|
||||
"@slorber/remark-comment": "^1.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"estree-util-value-to-estree": "^3.0.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"image-size": "^1.0.2",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"mdast-util-to-string": "^4.0.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-directive": "^3.0.0",
|
||||
"remark-emoji": "^4.0.0",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tslib": "^2.6.0",
|
||||
"unified": "^11.0.3",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"vfile": "^6.0.1",
|
||||
"webpack": "^5.88.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/theme-common": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-common/-/theme-common-3.2.1.tgz",
|
||||
"integrity": "sha512-d+adiD7L9xv6EvfaAwUqdKf4orsM3jqgeqAM+HAjgL/Ux0GkVVnfKr+tsoe+4ow4rHe6NUt+nkkW8/K8dKdilA==",
|
||||
"dependencies": {
|
||||
"@docusaurus/mdx-loader": "3.2.1",
|
||||
"@docusaurus/module-type-aliases": "3.2.1",
|
||||
"@docusaurus/plugin-content-blog": "3.2.1",
|
||||
"@docusaurus/plugin-content-docs": "3.2.1",
|
||||
"@docusaurus/plugin-content-pages": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"@types/history": "^4.7.11",
|
||||
"@types/react": "*",
|
||||
"@types/react-router-config": "*",
|
||||
@ -2667,16 +2819,54 @@
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/theme-mermaid": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.2.0.tgz",
|
||||
"integrity": "sha512-PvN6K6m3JaM9cr9oSPyba6OlwAiSfBzqQtNqdgPFDjakKuT4kj6JODfExi+HKtWuxayOVRQlRl7zTnWxM4sTVw==",
|
||||
"node_modules/@docusaurus/theme-common/node_modules/@docusaurus/mdx-loader": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/mdx-loader/-/mdx-loader-3.2.1.tgz",
|
||||
"integrity": "sha512-Fs8tXhXKZjNkdGaOy1xSLXSwfjCMT73J3Zfrju2U16uGedRFRjgK0ojpK5tiC7TnunsL3tOFgp1BSMBRflX9gw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/module-type-aliases": "3.2.0",
|
||||
"@docusaurus/theme-common": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"@mdx-js/mdx": "^3.0.0",
|
||||
"@slorber/remark-comment": "^1.0.0",
|
||||
"escape-html": "^1.0.3",
|
||||
"estree-util-value-to-estree": "^3.0.1",
|
||||
"file-loader": "^6.2.0",
|
||||
"fs-extra": "^11.1.1",
|
||||
"image-size": "^1.0.2",
|
||||
"mdast-util-mdx": "^3.0.0",
|
||||
"mdast-util-to-string": "^4.0.0",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"remark-directive": "^3.0.0",
|
||||
"remark-emoji": "^4.0.0",
|
||||
"remark-frontmatter": "^5.0.0",
|
||||
"remark-gfm": "^4.0.0",
|
||||
"stringify-object": "^3.3.0",
|
||||
"tslib": "^2.6.0",
|
||||
"unified": "^11.0.3",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
"url-loader": "^4.1.1",
|
||||
"vfile": "^6.0.1",
|
||||
"webpack": "^5.88.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/theme-mermaid": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-mermaid/-/theme-mermaid-3.2.1.tgz",
|
||||
"integrity": "sha512-l1FzUPgDUor/25XeJDeO22dttmzB0QnmAbF2qKjDz3ENa9vlD5rd5r0NrItZIe8y7qoa+OOxkl5lLBKBxBVbLg==",
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/module-type-aliases": "3.2.1",
|
||||
"@docusaurus/theme-common": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"mermaid": "^10.4.0",
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
@ -2689,18 +2879,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/theme-search-algolia": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.2.0.tgz",
|
||||
"integrity": "sha512-PgvF4qHoqJp8+GfqClUbTF/zYNOsz4De251IuzXon7+7FAXwvb2qmYtA2nEwyMbB7faKOz33Pxzv+y+153KS/g==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-search-algolia/-/theme-search-algolia-3.2.1.tgz",
|
||||
"integrity": "sha512-bzhCrpyXBXzeydNUH83II2akvFEGfhsNTPPWsk5N7e+odgQCQwoHhcF+2qILbQXjaoZ6B3c48hrvkyCpeyqGHw==",
|
||||
"dependencies": {
|
||||
"@docsearch/react": "^3.5.2",
|
||||
"@docusaurus/core": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.0",
|
||||
"@docusaurus/plugin-content-docs": "3.2.0",
|
||||
"@docusaurus/theme-common": "3.2.0",
|
||||
"@docusaurus/theme-translations": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-validation": "3.2.0",
|
||||
"@docusaurus/core": "3.2.1",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/plugin-content-docs": "3.2.1",
|
||||
"@docusaurus/theme-common": "3.2.1",
|
||||
"@docusaurus/theme-translations": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-validation": "3.2.1",
|
||||
"algoliasearch": "^4.18.0",
|
||||
"algoliasearch-helper": "^3.13.3",
|
||||
"clsx": "^2.0.0",
|
||||
@ -2719,9 +2909,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/theme-translations": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.2.0.tgz",
|
||||
"integrity": "sha512-VXzZJBuyVEmwUYyud+7IgJQEBRM6R2u/s10Rp3DOP19CBQxeKgHYTKkKhFtDeKMHDassb665kjgOi0YlJfUT6w==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/theme-translations/-/theme-translations-3.2.1.tgz",
|
||||
"integrity": "sha512-jAUMkIkFfY+OAhJhv6mV8zlwY6J4AQxJPTgLdR2l+Otof9+QdJjHNh/ifVEu9q0lp3oSPlJj9l05AaP7Ref+cg==",
|
||||
"dependencies": {
|
||||
"fs-extra": "^11.1.1",
|
||||
"tslib": "^2.6.0"
|
||||
@ -2731,15 +2921,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/tsconfig": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.2.0.tgz",
|
||||
"integrity": "sha512-gWGa/72TYRxSRRxGFU2G6Au0yif6zmbkAgzW3+SeXAxoq1a7OLytMLGEwaHjMoIRXl7WbThnpx4gZVwo0xRRAg==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/tsconfig/-/tsconfig-3.2.1.tgz",
|
||||
"integrity": "sha512-+biUwtsYW3oChLxYezzA+NIgS3Q9KDRl7add/YT54RXs9Q4rKInebxdHdG6JFs5BaTg45gyjDu0rvNVcGeHODg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@docusaurus/types": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.2.0.tgz",
|
||||
"integrity": "sha512-uG3FfTkkkbZIPPNYx6xRfZHKeGyRd/inIT1cqvYt1FobFLd+7WhRXrSBqwJ9JajJjEAjNioRMVFgGofGf/Wdww==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/types/-/types-3.2.1.tgz",
|
||||
"integrity": "sha512-n/toxBzL2oxTtRTOFiGKsHypzn/Pm+sXyw+VSk1UbqbXQiHOwHwts55bpKwbcUgA530Is6kix3ELiFOv9GAMfw==",
|
||||
"dependencies": {
|
||||
"@mdx-js/mdx": "^3.0.0",
|
||||
"@types/history": "^4.7.11",
|
||||
@ -2757,12 +2947,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/utils": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.2.0.tgz",
|
||||
"integrity": "sha512-3rgrE7iL60yV2JQivlcoxUNNTK2APmn+OHLUmTvX2pueIM8DEOCEFHpJO4MiWjFO7V/Wq3iA/W1M03JnjdugVw==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/utils/-/utils-3.2.1.tgz",
|
||||
"integrity": "sha512-DPkIS/EPc+pGAV798PUXgNzJFM3HJouoQXgr0KDZuJVz1EkWbDLOcQwLIz8Qx7liI9ddfkN/TXTRQdsTPZNakw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/logger": "3.2.0",
|
||||
"@docusaurus/utils-common": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"@svgr/webpack": "^6.5.1",
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"file-loader": "^6.2.0",
|
||||
@ -2794,9 +2984,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/utils-common": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.2.0.tgz",
|
||||
"integrity": "sha512-WEQT5L2lT/tBQgDRgeZQAIi9YJBrwEILb1BuObQn1St3T/4K1gx5fWwOT8qdLOov296XLd1FQg9Ywu27aE9svw==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/utils-common/-/utils-common-3.2.1.tgz",
|
||||
"integrity": "sha512-N5vadULnRLiqX2QfTjVEU3u5vo6RG2EZTdyXvJdzDOdrLCGIZAfnf/VkssinFZ922sVfaFfQ4FnStdhn5TWdVg==",
|
||||
"dependencies": {
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
@ -2813,13 +3003,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@docusaurus/utils-validation": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.2.0.tgz",
|
||||
"integrity": "sha512-rCzMTqwNrBrEOyU8EaD1fYWdig4TDhfj+YLqB8DY68VUAqSIgbY+yshpqFKB0bznFYNBJbn0bGpvVuImQOa/vA==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@docusaurus/utils-validation/-/utils-validation-3.2.1.tgz",
|
||||
"integrity": "sha512-+x7IR9hNMXi62L1YAglwd0s95fR7+EtirjTxSN4kahYRWGqOi3jlQl1EV0az/yTEvKbxVvOPcdYicGu9dk4LJw==",
|
||||
"dependencies": {
|
||||
"@docusaurus/logger": "3.2.0",
|
||||
"@docusaurus/utils": "3.2.0",
|
||||
"@docusaurus/utils-common": "3.2.0",
|
||||
"@docusaurus/logger": "3.2.1",
|
||||
"@docusaurus/utils": "3.2.1",
|
||||
"@docusaurus/utils-common": "3.2.1",
|
||||
"joi": "^17.9.2",
|
||||
"js-yaml": "^4.1.0",
|
||||
"tslib": "^2.6.0"
|
||||
@ -4125,9 +4315,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/algoliasearch-helper": {
|
||||
"version": "3.16.3",
|
||||
"resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.16.3.tgz",
|
||||
"integrity": "sha512-1OuJT6sONAa9PxcOmWo5WCAT3jQSpCR9/m5Azujja7nhUQwAUDvaaAYrcmUySsrvHh74usZHbE3jFfGnWtZj8w==",
|
||||
"version": "3.17.0",
|
||||
"resolved": "https://registry.npmjs.org/algoliasearch-helper/-/algoliasearch-helper-3.17.0.tgz",
|
||||
"integrity": "sha512-R5422OiQjvjlK3VdpNQ/Qk7KsTIGeM5ACm8civGifOVWdRRV/3SgXuKmeNxe94Dz6fwj/IgpVmXbHutU4mHubg==",
|
||||
"dependencies": {
|
||||
"@algolia/events": "^4.0.1"
|
||||
},
|
||||
@ -15616,9 +15806,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.4.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
|
||||
"integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
|
||||
"version": "5.4.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.4.tgz",
|
||||
"integrity": "sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
|
||||
@ -16,12 +16,12 @@
|
||||
"test": "node --test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^3.2.0",
|
||||
"@docusaurus/plugin-client-redirects": "^3.2.0",
|
||||
"@docusaurus/plugin-content-docs": "^3.2.0",
|
||||
"@docusaurus/preset-classic": "^3.2.0",
|
||||
"@docusaurus/theme-common": "^3.2.0",
|
||||
"@docusaurus/theme-mermaid": "^3.2.0",
|
||||
"@docusaurus/core": "^3.2.1",
|
||||
"@docusaurus/plugin-client-redirects": "^3.2.1",
|
||||
"@docusaurus/plugin-content-docs": "^3.2.1",
|
||||
"@docusaurus/preset-classic": "^3.2.1",
|
||||
"@docusaurus/theme-common": "^3.2.1",
|
||||
"@docusaurus/theme-mermaid": "^3.2.1",
|
||||
"@mdx-js/react": "^3.0.1",
|
||||
"clsx": "^2.1.0",
|
||||
"disqus-react": "^1.1.5",
|
||||
@ -49,12 +49,12 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "3.2.0",
|
||||
"@docusaurus/tsconfig": "3.2.0",
|
||||
"@docusaurus/types": "3.2.0",
|
||||
"@docusaurus/module-type-aliases": "3.2.1",
|
||||
"@docusaurus/tsconfig": "3.2.1",
|
||||
"@docusaurus/types": "3.2.1",
|
||||
"@types/react": "^18.2.74",
|
||||
"prettier": "3.2.5",
|
||||
"typescript": "~5.4.3"
|
||||
"typescript": "~5.4.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20"
|
||||
|
||||
Reference in New Issue
Block a user