Compare commits

..

9 Commits

Author SHA1 Message Date
0b96a98183 wip: Set prettier config. 2025-06-26 23:58:10 +02:00
d948345096 web: Remove TS aliases. 2025-06-26 23:56:43 +02:00
ecfd1b077d web: Tidy order. 2025-06-26 23:56:40 +02:00
3e67e358ce web: Normalize extensions. 2025-06-26 23:56:38 +02:00
c1032386c6 web: Format imports. 2025-06-26 23:56:35 +02:00
55cb7f3f2c web: Flesh out import clean up. 2025-06-26 23:56:32 +02:00
0c4e5bfc22 web: Clean up entrypoint imports. 2025-06-26 23:56:28 +02:00
69e5b1dfbe web: Clean ambiguous imports. 2025-06-26 23:56:24 +02:00
ccc2a5bdfe web: Clean up locale. 2025-06-26 23:56:20 +02:00
702 changed files with 7349 additions and 6278 deletions

View File

@ -1,5 +1,5 @@
[bumpversion] [bumpversion]
current_version = 2025.6.3 current_version = 2025.6.2
tag = True tag = True
commit = True commit = True
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))? parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(?:-(?P<rc_t>[a-zA-Z-]+)(?P<rc_n>[1-9]\\d*))?

View File

@ -38,8 +38,6 @@ jobs:
# Needed for attestation # Needed for attestation
id-token: write id-token: write
attestations: write attestations: write
# Needed for checkout
contents: read
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: docker/setup-qemu-action@v3.6.0 - uses: docker/setup-qemu-action@v3.6.0

View File

@ -9,7 +9,6 @@ on:
jobs: jobs:
test-container: test-container:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
fail-fast: false fail-fast: false

View File

@ -247,13 +247,11 @@ jobs:
# Needed for attestation # Needed for attestation
id-token: write id-token: write
attestations: write attestations: write
# Needed for checkout
contents: read
needs: ci-core-mark needs: ci-core-mark
uses: ./.github/workflows/_reusable-docker-build.yaml uses: ./.github/workflows/_reusable-docker-build.yaml
secrets: inherit secrets: inherit
with: with:
image_name: ${{ github.repository == 'goauthentik/authentik-internal' && 'ghcr.io/goauthentik/internal-server' || 'ghcr.io/goauthentik/dev-server' }} image_name: ghcr.io/goauthentik/dev-server
release: false release: false
pr-comment: pr-comment:
needs: needs:

View File

@ -59,7 +59,6 @@ jobs:
with: with:
jobs: ${{ toJSON(needs) }} jobs: ${{ toJSON(needs) }}
build-container: build-container:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
timeout-minutes: 120 timeout-minutes: 120
needs: needs:
- ci-outpost-mark - ci-outpost-mark

View File

@ -63,7 +63,6 @@ jobs:
working-directory: website/ working-directory: website/
run: npm run ${{ matrix.job }} run: npm run ${{ matrix.job }}
build-container: build-container:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
# Needed to upload container images to ghcr.io # Needed to upload container images to ghcr.io
@ -123,4 +122,3 @@ jobs:
- uses: re-actors/alls-green@release/v1 - uses: re-actors/alls-green@release/v1
with: with:
jobs: ${{ toJSON(needs) }} jobs: ${{ toJSON(needs) }}
allowed-skips: ${{ github.repository == 'goauthentik/authentik-internal' && 'build-container' || '[]' }}

View File

@ -1,21 +0,0 @@
name: "authentik-repo-mirror-cleanup"
on:
workflow_dispatch:
jobs:
to_internal:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- if: ${{ env.MIRROR_KEY != '' }}
uses: BeryJu/repository-mirroring-action@5cf300935bc2e068f73ea69bcc411a8a997208eb
with:
target_repo_url: git@github.com:goauthentik/authentik-internal.git
ssh_private_key: ${{ secrets.GH_MIRROR_KEY }}
args: --tags --force --prune
env:
MIRROR_KEY: ${{ secrets.GH_MIRROR_KEY }}

View File

@ -11,10 +11,11 @@ jobs:
with: with:
fetch-depth: 0 fetch-depth: 0
- if: ${{ env.MIRROR_KEY != '' }} - if: ${{ env.MIRROR_KEY != '' }}
uses: BeryJu/repository-mirroring-action@5cf300935bc2e068f73ea69bcc411a8a997208eb uses: pixta-dev/repository-mirroring-action@v1
with: with:
target_repo_url: git@github.com:goauthentik/authentik-internal.git target_repo_url:
ssh_private_key: ${{ secrets.GH_MIRROR_KEY }} git@github.com:goauthentik/authentik-internal.git
args: --tags --force ssh_private_key:
${{ secrets.GH_MIRROR_KEY }}
env: env:
MIRROR_KEY: ${{ secrets.GH_MIRROR_KEY }} MIRROR_KEY: ${{ secrets.GH_MIRROR_KEY }}

View File

@ -16,7 +16,6 @@ env:
jobs: jobs:
compile: compile:
if: ${{ github.repository != 'goauthentik/authentik-internal' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- id: generate_token - id: generate_token

View File

@ -75,7 +75,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
/bin/sh -c "GEOIPUPDATE_LICENSE_KEY_FILE=/run/secrets/GEOIPUPDATE_LICENSE_KEY /usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0" /bin/sh -c "GEOIPUPDATE_LICENSE_KEY_FILE=/run/secrets/GEOIPUPDATE_LICENSE_KEY /usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
# Stage 4: Download uv # Stage 4: Download uv
FROM ghcr.io/astral-sh/uv:0.7.17 AS uv FROM ghcr.io/astral-sh/uv:0.7.15 AS uv
# Stage 5: Base python image # Stage 5: Base python image
FROM ghcr.io/goauthentik/fips-python:3.13.5-slim-bookworm-fips AS python-base FROM ghcr.io/goauthentik/fips-python:3.13.5-slim-bookworm-fips AS python-base

View File

@ -2,7 +2,7 @@
from os import environ from os import environ
__version__ = "2025.6.3" __version__ = "2025.6.2"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH" ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -5,6 +5,7 @@ from collections.abc import Callable
from django.apps import apps from django.apps import apps
from django.test import TestCase from django.test import TestCase
from authentik.blueprints.v1.importer import is_model_allowed
from authentik.lib.models import SerializerModel from authentik.lib.models import SerializerModel
from authentik.providers.oauth2.models import RefreshToken from authentik.providers.oauth2.models import RefreshToken
@ -21,13 +22,10 @@ def serializer_tester_factory(test_model: type[SerializerModel]) -> Callable:
return return
model_class = test_model() model_class = test_model()
self.assertTrue(isinstance(model_class, SerializerModel)) self.assertTrue(isinstance(model_class, SerializerModel))
# Models that have subclasses don't have to have a serializer
if len(test_model.__subclasses__()) > 0:
return
self.assertIsNotNone(model_class.serializer) self.assertIsNotNone(model_class.serializer)
if model_class.serializer.Meta().model == RefreshToken: if model_class.serializer.Meta().model == RefreshToken:
return return
self.assertTrue(issubclass(test_model, model_class.serializer.Meta().model)) self.assertEqual(model_class.serializer.Meta().model, test_model)
return tester return tester
@ -36,6 +34,6 @@ for app in apps.get_app_configs():
if not app.label.startswith("authentik"): if not app.label.startswith("authentik"):
continue continue
for model in app.get_models(): for model in app.get_models():
if not issubclass(model, SerializerModel): if not is_model_allowed(model):
continue continue
setattr(TestModels, f"test_{app.label}_{model.__name__}", serializer_tester_factory(model)) setattr(TestModels, f"test_{app.label}_{model.__name__}", serializer_tester_factory(model))

View File

@ -43,7 +43,6 @@ from authentik.core.models import (
) )
from authentik.enterprise.license import LicenseKey from authentik.enterprise.license import LicenseKey
from authentik.enterprise.models import LicenseUsage from authentik.enterprise.models import LicenseUsage
from authentik.enterprise.providers.apple_psso.models import AppleNonce
from authentik.enterprise.providers.google_workspace.models import ( from authentik.enterprise.providers.google_workspace.models import (
GoogleWorkspaceProviderGroup, GoogleWorkspaceProviderGroup,
GoogleWorkspaceProviderUser, GoogleWorkspaceProviderUser,
@ -136,7 +135,6 @@ def excluded_models() -> list[type[Model]]:
EndpointDeviceConnection, EndpointDeviceConnection,
DeviceToken, DeviceToken,
StreamEvent, StreamEvent,
AppleNonce,
) )

View File

@ -1082,12 +1082,6 @@ class AuthenticatedSession(SerializerModel):
user = models.ForeignKey(User, on_delete=models.CASCADE) user = models.ForeignKey(User, on_delete=models.CASCADE)
@property
def serializer(self) -> type[Serializer]:
from authentik.core.api.authenticated_sessions import AuthenticatedSessionSerializer
return AuthenticatedSessionSerializer
class Meta: class Meta:
verbose_name = _("Authenticated Session") verbose_name = _("Authenticated Session")
verbose_name_plural = _("Authenticated Sessions") verbose_name_plural = _("Authenticated Sessions")

View File

@ -1,32 +0,0 @@
"""Apple Platform SSO Provider API Views"""
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.providers import ProviderSerializer
from authentik.core.api.used_by import UsedByMixin
from authentik.enterprise.api import EnterpriseRequiredMixin
from authentik.enterprise.providers.apple_psso.models import ApplePlatformSSOProvider
class ApplePlatformSSOProviderSerializer(EnterpriseRequiredMixin, ProviderSerializer):
"""ApplePlatformSSOProvider Serializer"""
class Meta:
model = ApplePlatformSSOProvider
fields = [
"pk",
"name",
]
extra_kwargs = {}
class ApplePlatformSSOProviderViewSet(UsedByMixin, ModelViewSet):
"""ApplePlatformSSOProvider Viewset"""
queryset = ApplePlatformSSOProvider.objects.all()
serializer_class = ApplePlatformSSOProviderSerializer
filterset_fields = [
"name",
]
search_fields = ["name"]
ordering = ["name"]

View File

@ -1,13 +0,0 @@
from authentik.enterprise.apps import EnterpriseConfig
class AuthentikEnterpriseProviderApplePSSOConfig(EnterpriseConfig):
name = "authentik.enterprise.providers.apple_psso"
label = "authentik_providers_apple_psso"
verbose_name = "authentik Enterprise.Providers.Apple Platform SSO"
default = True
mountpoints = {
"authentik.enterprise.providers.apple_psso.urls": "endpoint/apple/sso/",
"authentik.enterprise.providers.apple_psso.urls_root": "",
}

View File

@ -1,118 +0,0 @@
from base64 import urlsafe_b64encode
from json import dumps
from secrets import token_bytes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.concatkdf import ConcatKDFHash
from django.http import HttpResponse
from jwcrypto.common import base64url_decode, base64url_encode
from authentik.enterprise.providers.apple_psso.models import AppleDevice
def length_prefixed(data: bytes) -> bytes:
length = len(data)
return length.to_bytes(4, "big") + data
def build_apu(public_key: ec.EllipticCurvePublicKey):
# X9.63 representation: 0x04 || X || Y
public_numbers = public_key.public_numbers()
x_bytes = public_numbers.x.to_bytes(32, "big")
y_bytes = public_numbers.y.to_bytes(32, "big")
x963 = bytes([0x04]) + x_bytes + y_bytes
result = length_prefixed(b"APPLE") + length_prefixed(x963)
return result
def encrypt_token_with_a256_gcm(body: dict, device_encryption_key: str, apv: bytes) -> str:
ephemeral_key = ec.generate_private_key(curve=ec.SECP256R1())
device_public_key = serialization.load_pem_public_key(
device_encryption_key.encode(), backend=default_backend()
)
shared_secret_z = ephemeral_key.exchange(ec.ECDH(), device_public_key)
apu = build_apu(ephemeral_key.public_key())
jwe_header = {
"enc": "A256GCM",
"kid": "ephemeralKey",
"epk": {
"x": base64url_encode(
ephemeral_key.public_key().public_numbers().x.to_bytes(32, "big")
),
"y": base64url_encode(
ephemeral_key.public_key().public_numbers().y.to_bytes(32, "big")
),
"kty": "EC",
"crv": "P-256",
},
"typ": "platformsso-login-response+jwt",
"alg": "ECDH-ES",
"apu": base64url_encode(apu),
"apv": base64url_encode(apv),
}
party_u_info = length_prefixed(apu)
party_v_info = length_prefixed(apv)
supp_pub_info = (256).to_bytes(4, "big")
other_info = length_prefixed(b"A256GCM") + party_u_info + party_v_info + supp_pub_info
ckdf = ConcatKDFHash(
algorithm=hashes.SHA256(),
length=32,
otherinfo=other_info,
)
derived_key = ckdf.derive(shared_secret_z)
nonce = token_bytes(12)
header_json = dumps(jwe_header, separators=(",", ":")).encode()
aad = urlsafe_b64encode(header_json).rstrip(b"=")
aesgcm = AESGCM(derived_key)
ciphertext = aesgcm.encrypt(nonce, dumps(body).encode(), aad)
ciphertext_body = ciphertext[:-16]
tag = ciphertext[-16:]
# base64url encoding
protected_b64 = urlsafe_b64encode(header_json).rstrip(b"=")
iv_b64 = urlsafe_b64encode(nonce).rstrip(b"=")
ciphertext_b64 = urlsafe_b64encode(ciphertext_body).rstrip(b"=")
tag_b64 = urlsafe_b64encode(tag).rstrip(b"=")
jwe_compact = b".".join(
[
protected_b64,
b"",
iv_b64,
ciphertext_b64,
tag_b64,
]
)
return jwe_compact.decode()
class JWEResponse(HttpResponse):
def __init__(
self,
data: dict,
device: AppleDevice,
apv: str,
):
super().__init__(
content=encrypt_token_with_a256_gcm(data, device.encryption_key, base64url_decode(apv)),
content_type="application/platformsso-login-response+jwt",
)

View File

@ -1,36 +0,0 @@
# Generated by Django 5.1.11 on 2025-06-28 00:12
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
("authentik_providers_oauth2", "0028_migrate_session"),
]
operations = [
migrations.CreateModel(
name="ApplePlatformSSOProvider",
fields=[
(
"oauth2provider_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="authentik_providers_oauth2.oauth2provider",
),
),
],
options={
"abstract": False,
},
bases=("authentik_providers_oauth2.oauth2provider",),
),
]

View File

@ -1,94 +0,0 @@
# Generated by Django 5.1.11 on 2025-06-28 15:50
import django.db.models.deletion
import uuid
from django.conf import settings
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_providers_apple_psso", "0001_initial"),
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name="AppleDevice",
fields=[
(
"endpoint_uuid",
models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False),
),
("signing_key", models.TextField()),
("encryption_key", models.TextField()),
("key_exchange_key", models.TextField()),
("sign_key_id", models.TextField()),
("enc_key_id", models.TextField()),
("creation_time", models.DateTimeField(auto_now_add=True)),
(
"provider",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="authentik_providers_apple_psso.appleplatformssoprovider",
),
),
],
),
migrations.CreateModel(
name="AppleDeviceUser",
fields=[
("uuid", models.UUIDField(default=uuid.uuid4, primary_key=True, serialize=False)),
("signing_key", models.TextField()),
("encryption_key", models.TextField()),
("sign_key_id", models.TextField()),
("enc_key_id", models.TextField()),
(
"device",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
to="authentik_providers_apple_psso.appledevice",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL
),
),
],
),
migrations.AddField(
model_name="appledevice",
name="users",
field=models.ManyToManyField(
through="authentik_providers_apple_psso.AppleDeviceUser",
to=settings.AUTH_USER_MODEL,
),
),
migrations.CreateModel(
name="AppleNonce",
fields=[
(
"id",
models.AutoField(
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
),
),
("expires", models.DateTimeField(default=None, null=True)),
("expiring", models.BooleanField(default=True)),
("nonce", models.TextField()),
],
options={
"abstract": False,
"indexes": [
models.Index(fields=["expires"], name="authentik_p_expires_47d534_idx"),
models.Index(fields=["expiring"], name="authentik_p_expirin_87253e_idx"),
models.Index(
fields=["expiring", "expires"], name="authentik_p_expirin_20a7c9_idx"
),
],
},
),
]

View File

@ -1,34 +0,0 @@
# Generated by Django 5.1.11 on 2025-06-28 22:18
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
(
"authentik_providers_apple_psso",
"0002_appledevice_appledeviceuser_appledevice_users_and_more",
),
]
operations = [
migrations.RenameField(
model_name="appledeviceuser",
old_name="sign_key_id",
new_name="enclave_key_id",
),
migrations.RenameField(
model_name="appledeviceuser",
old_name="signing_key",
new_name="secure_enclave_key",
),
migrations.RemoveField(
model_name="appledeviceuser",
name="enc_key_id",
),
migrations.RemoveField(
model_name="appledeviceuser",
name="encryption_key",
),
]

View File

@ -1,85 +0,0 @@
from uuid import uuid4
from django.db import models
from django.utils.translation import gettext_lazy as _
from rest_framework.serializers import Serializer
from authentik.core.models import ExpiringModel, User
from authentik.crypto.models import CertificateKeyPair
from authentik.providers.oauth2.models import (
ClientTypes,
IssuerMode,
OAuth2Provider,
RedirectURI,
RedirectURIMatchingMode,
ScopeMapping,
)
class ApplePlatformSSOProvider(OAuth2Provider):
"""Integrate with Apple Platform SSO"""
def set_oauth_defaults(self):
"""Ensure all OAuth2-related settings are correct"""
self.issuer_mode = IssuerMode.PER_PROVIDER
self.client_type = ClientTypes.PUBLIC
self.signing_key = CertificateKeyPair.objects.get(name="authentik Self-signed Certificate")
self.include_claims_in_id_token = True
scopes = ScopeMapping.objects.filter(
managed__in=[
"goauthentik.io/providers/oauth2/scope-openid",
"goauthentik.io/providers/oauth2/scope-profile",
"goauthentik.io/providers/oauth2/scope-email",
"goauthentik.io/providers/oauth2/scope-offline_access",
"goauthentik.io/providers/oauth2/scope-authentik_api",
]
)
self.property_mappings.add(*list(scopes))
self.redirect_uris = [
RedirectURI(RedirectURIMatchingMode.STRICT, "io.goauthentik.endpoint:/oauth2redirect"),
]
@property
def component(self) -> str:
return "ak-provider-apple-psso-form"
@property
def serializer(self) -> type[Serializer]:
from authentik.enterprise.providers.apple_psso.api.providers import (
ApplePlatformSSOProviderSerializer,
)
return ApplePlatformSSOProviderSerializer
class Meta:
verbose_name = _("Apple Platform SSO Provider")
verbose_name_plural = _("Apple Platform SSO Providers")
class AppleDevice(models.Model):
endpoint_uuid = models.UUIDField(default=uuid4, primary_key=True)
signing_key = models.TextField()
encryption_key = models.TextField()
key_exchange_key = models.TextField()
sign_key_id = models.TextField()
enc_key_id = models.TextField()
creation_time = models.DateTimeField(auto_now_add=True)
provider = models.ForeignKey(ApplePlatformSSOProvider, on_delete=models.CASCADE)
users = models.ManyToManyField(User, through="AppleDeviceUser")
class AppleDeviceUser(models.Model):
uuid = models.UUIDField(default=uuid4, primary_key=True)
device = models.ForeignKey(AppleDevice, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
secure_enclave_key = models.TextField()
enclave_key_id = models.TextField()
class AppleNonce(ExpiringModel):
nonce = models.TextField()

View File

@ -1,15 +0,0 @@
from django.urls import path
from authentik.enterprise.providers.apple_psso.views.nonce import NonceView
from authentik.enterprise.providers.apple_psso.views.register import (
RegisterDeviceView,
RegisterUserView,
)
from authentik.enterprise.providers.apple_psso.views.token import TokenView
urlpatterns = [
path("token/", TokenView.as_view(), name="token"),
path("nonce/", NonceView.as_view(), name="nonce"),
path("register/device/", RegisterDeviceView.as_view(), name="register-device"),
path("register/user/", RegisterUserView.as_view(), name="register-user"),
]

View File

@ -1,7 +0,0 @@
from django.urls import path
from authentik.enterprise.providers.apple_psso.views.site_association import AppleAppSiteAssociation
urlpatterns = [
path(".well-known/apple-app-site-association", AppleAppSiteAssociation.as_view(), name="asa"),
]

View File

@ -1,25 +0,0 @@
from base64 import b64encode
from datetime import timedelta
from secrets import token_bytes
from django.http import HttpRequest, JsonResponse
from django.utils.decorators import method_decorator
from django.utils.timezone import now
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from authentik.enterprise.providers.apple_psso.models import AppleNonce
@method_decorator(csrf_exempt, name="dispatch")
class NonceView(View):
def post(self, request: HttpRequest, *args, **kwargs):
nonce = AppleNonce.objects.create(
nonce=b64encode(token_bytes(32)).decode(), expires=now() + timedelta(minutes=5)
)
return JsonResponse(
{
"Nonce": nonce.nonce,
}
)

View File

@ -1,92 +0,0 @@
from django.shortcuts import get_object_or_404
from rest_framework.authentication import BaseAuthentication
from rest_framework.fields import CharField
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from authentik.api.authentication import TokenAuthentication
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import User
from authentik.enterprise.providers.apple_psso.models import (
AppleDevice,
AppleDeviceUser,
ApplePlatformSSOProvider,
)
from authentik.lib.generators import generate_key
class DeviceRegisterAuth(BaseAuthentication):
def authenticate(self, request):
# very temporary, lol
return (User(), None)
class RegisterDeviceView(APIView):
class DeviceRegistration(PassiveSerializer):
device_uuid = CharField()
client_id = CharField()
device_signing_key = CharField()
device_encryption_key = CharField()
sign_key_id = CharField()
enc_key_id = CharField()
permission_classes = []
pagination_class = None
filter_backends = []
serializer_class = DeviceRegistration
authentication_classes = [DeviceRegisterAuth, TokenAuthentication]
def post(self, request: Request) -> Response:
data = self.DeviceRegistration(data=request.data)
data.is_valid(raise_exception=True)
provider = get_object_or_404(
ApplePlatformSSOProvider, client_id=data.validated_data["client_id"]
)
AppleDevice.objects.update_or_create(
endpoint_uuid=data.validated_data["device_uuid"],
defaults={
"signing_key": data.validated_data["device_signing_key"],
"encryption_key": data.validated_data["device_encryption_key"],
"sign_key_id": data.validated_data["sign_key_id"],
"enc_key_id": data.validated_data["enc_key_id"],
"key_exchange_key": generate_key(),
"provider": provider,
},
)
return Response()
class RegisterUserView(APIView):
class UserRegistration(PassiveSerializer):
device_uuid = CharField()
user_secure_enclave_key = CharField()
enclave_key_id = CharField()
permission_classes = []
pagination_class = None
filter_backends = []
serializer_class = UserRegistration
authentication_classes = [TokenAuthentication]
def post(self, request: Request) -> Response:
data = self.UserRegistration(data=request.data)
data.is_valid(raise_exception=True)
device = get_object_or_404(AppleDevice, endpoint_uuid=data.validated_data["device_uuid"])
AppleDeviceUser.objects.update_or_create(
device=device,
user=request.user,
defaults={
"secure_enclave_key": data.validated_data["user_secure_enclave_key"],
"enclave_key_id": data.validated_data["enclave_key_id"],
},
)
return Response(
{
"username": request.user.username,
}
)

View File

@ -1,16 +0,0 @@
from django.http import HttpRequest, HttpResponse, JsonResponse
from django.views import View
class AppleAppSiteAssociation(View):
def get(self, request: HttpRequest) -> HttpResponse:
return JsonResponse(
{
"authsrv": {
"apps": [
"232G855Y8N.io.goauthentik.endpoint",
"232G855Y8N.io.goauthentik.endpoint.psso",
]
}
}
)

View File

@ -1,140 +0,0 @@
from datetime import timedelta
from django.http import Http404, HttpRequest, HttpResponse
from django.utils.decorators import method_decorator
from django.utils.timezone import now
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from jwt import PyJWT, decode
from rest_framework.exceptions import ValidationError
from structlog.stdlib import get_logger
from authentik.core.models import AuthenticatedSession, Session, User
from authentik.core.sessions import SessionStore
from authentik.enterprise.providers.apple_psso.http import JWEResponse
from authentik.enterprise.providers.apple_psso.models import (
AppleDevice,
AppleDeviceUser,
AppleNonce,
ApplePlatformSSOProvider,
)
from authentik.events.models import Event, EventAction
from authentik.events.signals import SESSION_LOGIN_EVENT
from authentik.providers.oauth2.constants import TOKEN_TYPE
from authentik.providers.oauth2.id_token import IDToken
from authentik.providers.oauth2.models import RefreshToken
from authentik.root.middleware import SessionMiddleware
LOGGER = get_logger()
@method_decorator(csrf_exempt, name="dispatch")
class TokenView(View):
device: AppleDevice
provider: ApplePlatformSSOProvider
def post(self, request: HttpRequest) -> HttpResponse:
version = request.POST.get("platform_sso_version")
assertion = request.POST.get("assertion", request.POST.get("request"))
if not assertion:
return HttpResponse(status=400)
decode_unvalidated = PyJWT().decode_complete(assertion, options={"verify_signature": False})
LOGGER.debug(decode_unvalidated["header"])
expected_kid = decode_unvalidated["header"]["kid"]
self.device = AppleDevice.objects.filter(sign_key_id=expected_kid).first()
if not self.device:
raise Http404
self.provider = self.device.provider
# Properly decode the JWT with the key from the device
decoded = decode(
assertion, self.device.signing_key, algorithms=["ES256"], options={"verify_aud": False}
)
LOGGER.debug(decoded)
LOGGER.debug("got device", device=self.device)
# Check that the nonce hasn't been used before
nonce = AppleNonce.objects.filter(nonce=decoded["request_nonce"]).first()
if not nonce:
return HttpResponse(status=400)
nonce.delete()
handler_func = (
f"handle_v{version}_{decode_unvalidated["header"]["typ"]}".replace("-", "_")
.replace("+", "_")
.replace(".", "_")
)
handler = getattr(self, handler_func, None)
if not handler:
LOGGER.debug("Handler not found", handler=handler_func)
return HttpResponse(status=400)
LOGGER.debug("sending to handler", handler=handler_func)
return handler(decoded)
def validate_device_user_response(self, assertion: str) -> tuple[AppleDeviceUser, dict] | None:
"""Decode an embedded assertion and validate it by looking up the matching device user"""
decode_unvalidated = PyJWT().decode_complete(assertion, options={"verify_signature": False})
expected_kid = decode_unvalidated["header"]["kid"]
device_user = AppleDeviceUser.objects.filter(
device=self.device, enclave_key_id=expected_kid
).first()
if not device_user:
return None
return device_user, decode(
assertion,
device_user.secure_enclave_key,
audience="apple-platform-sso",
algorithms=["ES256"],
)
def create_auth_session(self, user: User):
event = Event.new(EventAction.LOGIN).from_http(self.request, user=user)
store = SessionStore()
store[SESSION_LOGIN_EVENT] = event
store.save()
session = Session.objects.filter(session_key=store.session_key).first()
AuthenticatedSession.objects.create(session=session, user=user)
session = SessionMiddleware.encode_session(store.session_key, user)
return session
def handle_v1_0_platformsso_login_request_jwt(self, decoded: dict):
user = None
if decoded["grant_type"] == "urn:ietf:params:oauth:grant-type:jwt-bearer":
# Decode and validate inner assertion
user, inner = self.validate_device_user_response(decoded["assertion"])
if inner["nonce"] != decoded["nonce"]:
LOGGER.warning("Mis-matched nonce to outer assertion")
raise ValidationError("Invalid request")
refresh_token = RefreshToken(
user=user.user,
scope=decoded["scope"],
expires=now() + timedelta(hours=8),
provider=self.provider,
auth_time=now(),
session=None,
)
id_token = IDToken.new(
self.provider,
refresh_token,
self.request,
)
id_token.nonce = decoded["nonce"]
refresh_token.id_token = id_token
refresh_token.save()
return JWEResponse(
{
"refresh_token": refresh_token.token,
"refresh_token_expires_in": int((refresh_token.expires - now()).total_seconds()),
"id_token": refresh_token.id_token.to_jwt(self.provider),
"token_type": TOKEN_TYPE,
"session_key": self.create_auth_session(user.user),
},
device=self.device,
apv=decoded["jwe_crypto"]["apv"],
)

View File

@ -15,7 +15,6 @@ CELERY_BEAT_SCHEDULE = {
TENANT_APPS = [ TENANT_APPS = [
"authentik.enterprise.audit", "authentik.enterprise.audit",
"authentik.enterprise.policies.unique_password", "authentik.enterprise.policies.unique_password",
"authentik.enterprise.providers.apple_psso",
"authentik.enterprise.providers.google_workspace", "authentik.enterprise.providers.google_workspace",
"authentik.enterprise.providers.microsoft_entra", "authentik.enterprise.providers.microsoft_entra",
"authentik.enterprise.providers.ssf", "authentik.enterprise.providers.ssf",

View File

@ -555,8 +555,6 @@ class TokenView(View):
provider: OAuth2Provider | None = None provider: OAuth2Provider | None = None
params: TokenParams | None = None params: TokenParams | None = None
params_class = TokenParams
provider_class = OAuth2Provider
def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
response = super().dispatch(request, *args, **kwargs) response = super().dispatch(request, *args, **kwargs)
@ -576,14 +574,12 @@ class TokenView(View):
op="authentik.providers.oauth2.post.parse", op="authentik.providers.oauth2.post.parse",
): ):
client_id, client_secret = extract_client_auth(request) client_id, client_secret = extract_client_auth(request)
self.provider = self.provider_class.objects.filter(client_id=client_id).first() self.provider = OAuth2Provider.objects.filter(client_id=client_id).first()
if not self.provider: if not self.provider:
LOGGER.warning("OAuth2Provider does not exist", client_id=client_id) LOGGER.warning("OAuth2Provider does not exist", client_id=client_id)
raise TokenError("invalid_client") raise TokenError("invalid_client")
CTX_AUTH_VIA.set("oauth_client_secret") CTX_AUTH_VIA.set("oauth_client_secret")
self.params = self.params_class.parse( self.params = TokenParams.parse(request, self.provider, client_id, client_secret)
request, self.provider, client_id, client_secret
)
with start_span( with start_span(
op="authentik.providers.oauth2.post.response", op="authentik.providers.oauth2.post.response",

View File

@ -66,10 +66,7 @@ class RACClientConsumer(AsyncWebsocketConsumer):
def init_outpost_connection(self): def init_outpost_connection(self):
"""Initialize guac connection settings""" """Initialize guac connection settings"""
self.token = ( self.token = (
ConnectionToken.filter_not_expired( ConnectionToken.filter_not_expired(token=self.scope["url_route"]["kwargs"]["token"])
token=self.scope["url_route"]["kwargs"]["token"],
session__session__session_key=self.scope["session"].session_key,
)
.select_related("endpoint", "provider", "session", "session__user") .select_related("endpoint", "provider", "session", "session__user")
.first() .first()
) )

View File

@ -87,22 +87,3 @@ class TestRACViews(APITestCase):
) )
body = loads(flow_response.content) body = loads(flow_response.content)
self.assertEqual(body["component"], "ak-stage-access-denied") self.assertEqual(body["component"], "ak-stage-access-denied")
def test_different_session(self):
"""Test request"""
self.client.force_login(self.user)
response = self.client.get(
reverse(
"authentik_providers_rac:start",
kwargs={"app": self.app.slug, "endpoint": str(self.endpoint.pk)},
)
)
self.assertEqual(response.status_code, 302)
flow_response = self.client.get(
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
)
body = loads(flow_response.content)
next_url = body["to"]
self.client.logout()
final_response = self.client.get(next_url)
self.assertEqual(final_response.url, reverse("authentik_core:if-user"))

View File

@ -68,10 +68,7 @@ class RACInterface(InterfaceView):
def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: def dispatch(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
# Early sanity check to ensure token still exists # Early sanity check to ensure token still exists
token = ConnectionToken.filter_not_expired( token = ConnectionToken.filter_not_expired(token=self.kwargs["token"]).first()
token=self.kwargs["token"],
session__session__session_key=request.session.session_key,
).first()
if not token: if not token:
return redirect("authentik_core:if-user") return redirect("authentik_core:if-user")
self.token = token self.token = token

View File

@ -61,22 +61,6 @@ class SessionMiddleware(UpstreamSessionMiddleware):
pass pass
return session_key return session_key
@staticmethod
def encode_session(session_key: str, user: User):
payload = {
"sid": session_key,
"iss": "authentik",
"sub": "anonymous",
"authenticated": user.is_authenticated,
"acr": ACR_AUTHENTIK_SESSION,
}
if user.is_authenticated:
payload["sub"] = user.uid
value = encode(payload=payload, key=SIGNING_HASH)
if settings.TEST:
value = session_key
return value
def process_request(self, request: HttpRequest): def process_request(self, request: HttpRequest):
raw_session = request.COOKIES.get(settings.SESSION_COOKIE_NAME) raw_session = request.COOKIES.get(settings.SESSION_COOKIE_NAME)
session_key = SessionMiddleware.decode_session_key(raw_session) session_key = SessionMiddleware.decode_session_key(raw_session)
@ -133,9 +117,21 @@ class SessionMiddleware(UpstreamSessionMiddleware):
"request completed. The user may have logged " "request completed. The user may have logged "
"out in a concurrent request, for example." "out in a concurrent request, for example."
) from None ) from None
payload = {
"sid": request.session.session_key,
"iss": "authentik",
"sub": "anonymous",
"authenticated": request.user.is_authenticated,
"acr": ACR_AUTHENTIK_SESSION,
}
if request.user.is_authenticated:
payload["sub"] = request.user.uid
value = encode(payload=payload, key=SIGNING_HASH)
if settings.TEST:
value = request.session.session_key
response.set_cookie( response.set_cookie(
settings.SESSION_COOKIE_NAME, settings.SESSION_COOKIE_NAME,
SessionMiddleware.encode_session(request.session.session_key, request.user), value,
max_age=max_age, max_age=max_age,
expires=expires, expires=expires,
domain=settings.SESSION_COOKIE_DOMAIN, domain=settings.SESSION_COOKIE_DOMAIN,

View File

@ -27,6 +27,7 @@
</table> </table>
</td> </td>
</tr> </tr>
<td>
{% endblock %} {% endblock %}
{% block sub_content %} {% block sub_content %}

View File

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema", "$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://goauthentik.io/blueprints/schema.json", "$id": "https://goauthentik.io/blueprints/schema.json",
"type": "object", "type": "object",
"title": "authentik 2025.6.3 Blueprint schema", "title": "authentik 2025.6.2 Blueprint schema",
"required": [ "required": [
"version", "version",
"entries" "entries"
@ -496,46 +496,6 @@
} }
} }
}, },
{
"type": "object",
"required": [
"model",
"identifiers"
],
"properties": {
"model": {
"const": "authentik_providers_apple_psso.appleplatformssoprovider"
},
"id": {
"type": "string"
},
"state": {
"type": "string",
"enum": [
"absent",
"created",
"must_created",
"present"
],
"default": "present"
},
"conditions": {
"type": "array",
"items": {
"type": "boolean"
}
},
"permissions": {
"$ref": "#/$defs/model_authentik_providers_apple_psso.appleplatformssoprovider_permissions"
},
"attrs": {
"$ref": "#/$defs/model_authentik_providers_apple_psso.appleplatformssoprovider"
},
"identifiers": {
"$ref": "#/$defs/model_authentik_providers_apple_psso.appleplatformssoprovider"
}
}
},
{ {
"type": "object", "type": "object",
"required": [ "required": [
@ -5068,22 +5028,6 @@
"authentik_policies_unique_password.delete_userpasswordhistory", "authentik_policies_unique_password.delete_userpasswordhistory",
"authentik_policies_unique_password.view_uniquepasswordpolicy", "authentik_policies_unique_password.view_uniquepasswordpolicy",
"authentik_policies_unique_password.view_userpasswordhistory", "authentik_policies_unique_password.view_userpasswordhistory",
"authentik_providers_apple_psso.add_appledevice",
"authentik_providers_apple_psso.add_appledeviceuser",
"authentik_providers_apple_psso.add_applenonce",
"authentik_providers_apple_psso.add_appleplatformssoprovider",
"authentik_providers_apple_psso.change_appledevice",
"authentik_providers_apple_psso.change_appledeviceuser",
"authentik_providers_apple_psso.change_applenonce",
"authentik_providers_apple_psso.change_appleplatformssoprovider",
"authentik_providers_apple_psso.delete_appledevice",
"authentik_providers_apple_psso.delete_appledeviceuser",
"authentik_providers_apple_psso.delete_applenonce",
"authentik_providers_apple_psso.delete_appleplatformssoprovider",
"authentik_providers_apple_psso.view_appledevice",
"authentik_providers_apple_psso.view_appledeviceuser",
"authentik_providers_apple_psso.view_applenonce",
"authentik_providers_apple_psso.view_appleplatformssoprovider",
"authentik_providers_google_workspace.add_googleworkspaceprovider", "authentik_providers_google_workspace.add_googleworkspaceprovider",
"authentik_providers_google_workspace.add_googleworkspaceprovidergroup", "authentik_providers_google_workspace.add_googleworkspaceprovidergroup",
"authentik_providers_google_workspace.add_googleworkspaceprovidermapping", "authentik_providers_google_workspace.add_googleworkspaceprovidermapping",
@ -5655,43 +5599,6 @@
} }
} }
}, },
"model_authentik_providers_apple_psso.appleplatformssoprovider": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1,
"title": "Name"
}
},
"required": []
},
"model_authentik_providers_apple_psso.appleplatformssoprovider_permissions": {
"type": "array",
"items": {
"type": "object",
"required": [
"permission"
],
"properties": {
"permission": {
"type": "string",
"enum": [
"add_appleplatformssoprovider",
"change_appleplatformssoprovider",
"delete_appleplatformssoprovider",
"view_appleplatformssoprovider"
]
},
"user": {
"type": "integer"
},
"role": {
"type": "string"
}
}
}
},
"model_authentik_providers_google_workspace.googleworkspaceprovider": { "model_authentik_providers_google_workspace.googleworkspaceprovider": {
"type": "object", "type": "object",
"properties": { "properties": {
@ -7435,7 +7342,6 @@
"authentik.enterprise", "authentik.enterprise",
"authentik.enterprise.audit", "authentik.enterprise.audit",
"authentik.enterprise.policies.unique_password", "authentik.enterprise.policies.unique_password",
"authentik.enterprise.providers.apple_psso",
"authentik.enterprise.providers.google_workspace", "authentik.enterprise.providers.google_workspace",
"authentik.enterprise.providers.microsoft_entra", "authentik.enterprise.providers.microsoft_entra",
"authentik.enterprise.providers.ssf", "authentik.enterprise.providers.ssf",
@ -7546,7 +7452,6 @@
"authentik_core.token", "authentik_core.token",
"authentik_enterprise.license", "authentik_enterprise.license",
"authentik_policies_unique_password.uniquepasswordpolicy", "authentik_policies_unique_password.uniquepasswordpolicy",
"authentik_providers_apple_psso.appleplatformssoprovider",
"authentik_providers_google_workspace.googleworkspaceprovider", "authentik_providers_google_workspace.googleworkspaceprovider",
"authentik_providers_google_workspace.googleworkspaceprovidermapping", "authentik_providers_google_workspace.googleworkspaceprovidermapping",
"authentik_providers_microsoft_entra.microsoftentraprovider", "authentik_providers_microsoft_entra.microsoftentraprovider",
@ -9769,22 +9674,6 @@
"authentik_policies_unique_password.delete_userpasswordhistory", "authentik_policies_unique_password.delete_userpasswordhistory",
"authentik_policies_unique_password.view_uniquepasswordpolicy", "authentik_policies_unique_password.view_uniquepasswordpolicy",
"authentik_policies_unique_password.view_userpasswordhistory", "authentik_policies_unique_password.view_userpasswordhistory",
"authentik_providers_apple_psso.add_appledevice",
"authentik_providers_apple_psso.add_appledeviceuser",
"authentik_providers_apple_psso.add_applenonce",
"authentik_providers_apple_psso.add_appleplatformssoprovider",
"authentik_providers_apple_psso.change_appledevice",
"authentik_providers_apple_psso.change_appledeviceuser",
"authentik_providers_apple_psso.change_applenonce",
"authentik_providers_apple_psso.change_appleplatformssoprovider",
"authentik_providers_apple_psso.delete_appledevice",
"authentik_providers_apple_psso.delete_appledeviceuser",
"authentik_providers_apple_psso.delete_applenonce",
"authentik_providers_apple_psso.delete_appleplatformssoprovider",
"authentik_providers_apple_psso.view_appledevice",
"authentik_providers_apple_psso.view_appledeviceuser",
"authentik_providers_apple_psso.view_applenonce",
"authentik_providers_apple_psso.view_appleplatformssoprovider",
"authentik_providers_google_workspace.add_googleworkspaceprovider", "authentik_providers_google_workspace.add_googleworkspaceprovider",
"authentik_providers_google_workspace.add_googleworkspaceprovidergroup", "authentik_providers_google_workspace.add_googleworkspaceprovidergroup",
"authentik_providers_google_workspace.add_googleworkspaceprovidermapping", "authentik_providers_google_workspace.add_googleworkspaceprovidermapping",

View File

@ -31,7 +31,7 @@ services:
volumes: volumes:
- redis:/data - redis:/data
server: server:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.3} image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.2}
restart: unless-stopped restart: unless-stopped
command: server command: server
environment: environment:
@ -55,7 +55,7 @@ services:
redis: redis:
condition: service_healthy condition: service_healthy
worker: worker:
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.3} image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2025.6.2}
restart: unless-stopped restart: unless-stopped
command: worker command: worker
environment: environment:

2
go.mod
View File

@ -29,7 +29,7 @@ require (
github.com/spf13/cobra v1.9.1 github.com/spf13/cobra v1.9.1
github.com/stretchr/testify v1.10.0 github.com/stretchr/testify v1.10.0
github.com/wwt/guac v1.3.2 github.com/wwt/guac v1.3.2
goauthentik.io/api/v3 v3.2025063.1 goauthentik.io/api/v3 v3.2025062.6
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.30.0 golang.org/x/oauth2 v0.30.0
golang.org/x/sync v0.15.0 golang.org/x/sync v0.15.0

4
go.sum
View File

@ -298,8 +298,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
goauthentik.io/api/v3 v3.2025063.1 h1:zvKhZTESgMY/SNiLuTs7G0YleBnev1v7+S9Xd6PZ9bc= goauthentik.io/api/v3 v3.2025062.6 h1:rlChhGP2vJufYCaTMb4sbRBEE1p2uL5T4HzMqF1AJ4A=
goauthentik.io/api/v3 v3.2025063.1/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw= goauthentik.io/api/v3 v3.2025062.6/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=

View File

@ -33,4 +33,4 @@ func UserAgent() string {
return fmt.Sprintf("authentik@%s", FullVersion()) return fmt.Sprintf("authentik@%s", FullVersion())
} }
const VERSION = "2025.6.3" const VERSION = "2025.6.2"

View File

@ -26,7 +26,7 @@ Parameters:
Description: authentik Docker image Description: authentik Docker image
AuthentikVersion: AuthentikVersion:
Type: String Type: String
Default: 2025.6.3 Default: 2025.6.2
Description: authentik Docker image tag Description: authentik Docker image tag
AuthentikServerCPU: AuthentikServerCPU:
Type: Number Type: Number

Binary file not shown.

View File

@ -11,18 +11,18 @@
# Nicola Mersi, 2024 # Nicola Mersi, 2024
# tmassimi, 2024 # tmassimi, 2024
# Marc Schmitt, 2024 # Marc Schmitt, 2024
# albanobattistella <albanobattistella@gmail.com>, 2024
# Matteo Piccina <altermatte@gmail.com>, 2025 # Matteo Piccina <altermatte@gmail.com>, 2025
# Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025 # Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025
# albanobattistella <albanobattistella@gmail.com>, 2025
# #
#, fuzzy #, fuzzy
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-25 00:10+0000\n" "POT-Creation-Date: 2025-05-28 11:25+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n" "PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: albanobattistella <albanobattistella@gmail.com>, 2025\n" "Last-Translator: Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025\n"
"Language-Team: Italian (https://app.transifex.com/authentik/teams/119923/it/)\n" "Language-Team: Italian (https://app.transifex.com/authentik/teams/119923/it/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -116,7 +116,7 @@ msgstr "Certificato Web utilizzato dal server Web authentik Core."
#: authentik/brands/models.py #: authentik/brands/models.py
msgid "Certificates used for client authentication." msgid "Certificates used for client authentication."
msgstr "Certificati utilizzati per l'autenticazione del client." msgstr ""
#: authentik/brands/models.py #: authentik/brands/models.py
msgid "Brand" msgid "Brand"
@ -130,6 +130,10 @@ msgstr "Brands"
msgid "User does not have access to application." msgid "User does not have access to application."
msgstr "L'utente non ha accesso all'applicazione." msgstr "L'utente non ha accesso all'applicazione."
#: authentik/core/api/devices.py
msgid "Extra description not available"
msgstr "Descrizione extra non disponibile"
#: authentik/core/api/groups.py #: authentik/core/api/groups.py
msgid "Cannot set group as parent of itself." msgid "Cannot set group as parent of itself."
msgstr "Impossibile impostare il gruppo come padre di se stesso." msgstr "Impossibile impostare il gruppo come padre di se stesso."
@ -290,15 +294,15 @@ msgid ""
msgstr "" msgstr ""
"Collegamento a un utente con indirizzo email identico. Può avere " "Collegamento a un utente con indirizzo email identico. Può avere "
"implicazioni sulla sicurezza quando una fonte non convalida gli indirizzi " "implicazioni sulla sicurezza quando una fonte non convalida gli indirizzi "
"email." "e-mail."
#: authentik/core/models.py #: authentik/core/models.py
msgid "" msgid ""
"Use the user's email address, but deny enrollment when the email address " "Use the user's email address, but deny enrollment when the email address "
"already exists." "already exists."
msgstr "" msgstr ""
"Usa l'indirizzo email dell'utente, ma nega l'iscrizione quando l'indirizzo " "Usa l'indirizzo e-mail dell'utente, ma nega l'iscrizione quando l'indirizzo "
"email esiste già." "e-mail esiste già."
#: authentik/core/models.py #: authentik/core/models.py
msgid "" msgid ""
@ -678,29 +682,26 @@ msgid ""
"option has a higher priority than the `client_certificate` option on " "option has a higher priority than the `client_certificate` option on "
"`Brand`." "`Brand`."
msgstr "" msgstr ""
"Configura le autorità di certificazione per convalidare il certificato. "
"Questa opzione ha una priorità maggiore rispetto all'opzione "
"`client_certificate` su `Brand`."
#: authentik/enterprise/stages/mtls/models.py #: authentik/enterprise/stages/mtls/models.py
msgid "Mutual TLS Stage" msgid "Mutual TLS Stage"
msgstr "Fase di TLS reciproca" msgstr ""
#: authentik/enterprise/stages/mtls/models.py #: authentik/enterprise/stages/mtls/models.py
msgid "Mutual TLS Stages" msgid "Mutual TLS Stages"
msgstr "Fasi di TLS reciproche" msgstr ""
#: authentik/enterprise/stages/mtls/models.py #: authentik/enterprise/stages/mtls/models.py
msgid "Permissions to pass Certificates for outposts." msgid "Permissions to pass Certificates for outposts."
msgstr " Permessi di trasmissione dei Certificati per gli avamposti." msgstr ""
#: authentik/enterprise/stages/mtls/stage.py #: authentik/enterprise/stages/mtls/stage.py
msgid "Certificate required but no certificate was given." msgid "Certificate required but no certificate was given."
msgstr " Il certificato è stato richiesto ma non è stato consegnato." msgstr ""
#: authentik/enterprise/stages/mtls/stage.py #: authentik/enterprise/stages/mtls/stage.py
msgid "No user found for certificate." msgid "No user found for certificate."
msgstr "Nessun utente trovato per il certificato." msgstr ""
#: authentik/enterprise/stages/source/models.py #: authentik/enterprise/stages/source/models.py
msgid "" msgid ""
@ -833,14 +834,6 @@ msgstr ""
"Definisci a quale gruppo di utenti deve essere inviata e mostrata questa " "Definisci a quale gruppo di utenti deve essere inviata e mostrata questa "
"notifica. Se lasciato vuoto, la notifica non verrà inviata." "notifica. Se lasciato vuoto, la notifica non verrà inviata."
#: authentik/events/models.py
msgid ""
"When enabled, notification will be sent to user the user that triggered the "
"event.When destination_group is configured, notification is sent to both."
msgstr ""
"Se abilitata, la notifica verrà inviata all'utente che ha attivato l'evento."
" Se destination_group è configurato, la notifica verrà inviata a entrambi."
#: authentik/events/models.py #: authentik/events/models.py
msgid "Notification Rule" msgid "Notification Rule"
msgstr "Regola di notifica" msgstr "Regola di notifica"
@ -1057,16 +1050,16 @@ msgstr "Avvio della sincronizzazione completa del provider"
#: authentik/lib/sync/outgoing/tasks.py #: authentik/lib/sync/outgoing/tasks.py
msgid "Syncing users" msgid "Syncing users"
msgstr "Sincronizzazione degli utenti" msgstr ""
#: authentik/lib/sync/outgoing/tasks.py #: authentik/lib/sync/outgoing/tasks.py
msgid "Syncing groups" msgid "Syncing groups"
msgstr "Sincronizzazione dei gruppi" msgstr ""
#: authentik/lib/sync/outgoing/tasks.py #: authentik/lib/sync/outgoing/tasks.py
#, python-brace-format #, python-brace-format
msgid "Syncing page {page} of {object_type}" msgid "Syncing page {page} of groups"
msgstr "Sincronizzazione della pagina {page} di {object_type}" msgstr "Sincronizzando pagina {page} dei gruppi"
#: authentik/lib/sync/outgoing/tasks.py #: authentik/lib/sync/outgoing/tasks.py
msgid "Dropping mutating request due to dry run" msgid "Dropping mutating request due to dry run"
@ -2468,10 +2461,6 @@ msgstr "Gruppo di aggiunta DN"
msgid "Consider Objects matching this filter to be Users." msgid "Consider Objects matching this filter to be Users."
msgstr "Considerare gli oggetti corrispondenti a questo filtro come Utenti." msgstr "Considerare gli oggetti corrispondenti a questo filtro come Utenti."
#: authentik/sources/ldap/models.py
msgid "Attribute which matches the value of `group_membership_field`."
msgstr "Attributo che corrisponde al valore di `group_membership_field`."
#: authentik/sources/ldap/models.py #: authentik/sources/ldap/models.py
msgid "Field which contains members of a group." msgid "Field which contains members of a group."
msgstr "Campo che contiene i membri di un gruppo." msgstr "Campo che contiene i membri di un gruppo."
@ -2513,8 +2502,6 @@ msgid ""
"Delete authentik users and groups which were previously supplied by this " "Delete authentik users and groups which were previously supplied by this "
"source, but are now missing from it." "source, but are now missing from it."
msgstr "" msgstr ""
"Elimina gli utenti e i gruppi authentik precedentemente forniti da questa "
"fonte, ma che ora mancano."
#: authentik/sources/ldap/models.py #: authentik/sources/ldap/models.py
msgid "LDAP Source" msgid "LDAP Source"
@ -2536,8 +2523,6 @@ msgstr "Mappature delle proprietà della sorgente LDAP"
msgid "" msgid ""
"Unique ID used while checking if this object still exists in the directory." "Unique ID used while checking if this object still exists in the directory."
msgstr "" msgstr ""
"ID univoco utilizzato per verificare se questo oggetto esiste ancora nella "
"directory."
#: authentik/sources/ldap/models.py #: authentik/sources/ldap/models.py
msgid "User LDAP Source Connection" msgid "User LDAP Source Connection"
@ -2935,7 +2920,7 @@ msgstr "Connessioni sorgente SAML di gruppo"
#: authentik/sources/saml/views.py #: authentik/sources/saml/views.py
#, python-brace-format #, python-brace-format
msgid "Continue to {source_name}" msgid "Continue to {source_name}"
msgstr "Continua su {source_name}" msgstr ""
#: authentik/sources/scim/models.py #: authentik/sources/scim/models.py
msgid "SCIM Source" msgid "SCIM Source"
@ -3003,8 +2988,8 @@ msgstr "Fasi di configurazione dell'autenticatore email"
#: authentik/stages/email/stage.py #: authentik/stages/email/stage.py
msgid "Exception occurred while rendering E-mail template" msgid "Exception occurred while rendering E-mail template"
msgstr "" msgstr ""
"Si è verificata un'eccezione durante la visualizzazione del modello di posta" "Eccezione verificatasi durante la visualizzazione del modello di posta "
" elettronica" "elettronica"
#: authentik/stages/authenticator_email/models.py #: authentik/stages/authenticator_email/models.py
msgid "Email Device" msgid "Email Device"
@ -3043,7 +3028,7 @@ msgid ""
" " " "
msgstr "" msgstr ""
"\n" "\n"
" Codice MFA via email.\n" " Codice MFA via e-mail.\n"
" " " "
#: authentik/stages/authenticator_email/templates/email/email_otp.html #: authentik/stages/authenticator_email/templates/email/email_otp.html
@ -3069,7 +3054,7 @@ msgid ""
"Email MFA code\n" "Email MFA code\n"
msgstr "" msgstr ""
"\n" "\n"
"Codice email MFA\n" "Codice e-mail MFA\n"
#: authentik/stages/authenticator_email/templates/email/email_otp.txt #: authentik/stages/authenticator_email/templates/email/email_otp.txt
#, python-format #, python-format
@ -3336,7 +3321,7 @@ msgstr "Consensi utente"
#: authentik/stages/consent/stage.py #: authentik/stages/consent/stage.py
msgid "Invalid consent token, re-showing prompt" msgid "Invalid consent token, re-showing prompt"
msgstr "Token di consenso non valido, viene nuovamente visualizzato il prompt" msgstr ""
#: authentik/stages/deny/models.py #: authentik/stages/deny/models.py
msgid "Deny Stage" msgid "Deny Stage"
@ -3356,11 +3341,11 @@ msgstr "Fasi fittizie"
#: authentik/stages/email/flow.py #: authentik/stages/email/flow.py
msgid "Continue to confirm this email address." msgid "Continue to confirm this email address."
msgstr "Continua per confermare questo indirizzo email." msgstr ""
#: authentik/stages/email/flow.py #: authentik/stages/email/flow.py
msgid "Link was already used, please request a new link." msgid "Link was already used, please request a new link."
msgstr "Il collegamento è già stato utilizzato. Richiedine uno nuovo." msgstr ""
#: authentik/stages/email/models.py #: authentik/stages/email/models.py
msgid "Password Reset" msgid "Password Reset"
@ -3380,7 +3365,7 @@ msgstr "Fase email"
#: authentik/stages/email/models.py #: authentik/stages/email/models.py
msgid "Email Stages" msgid "Email Stages"
msgstr "Fasi email" msgstr "Fasi Email"
#: authentik/stages/email/stage.py #: authentik/stages/email/stage.py
msgid "Successfully verified Email." msgid "Successfully verified Email."
@ -3482,7 +3467,7 @@ msgid ""
" " " "
msgstr "" msgstr ""
"\n" "\n"
" Se non hai richiesto una modifica della password, ignora questa email. Il link sopra è valido per %(expires)s.\n" " Se non hai richiesto una modifica della password, ignora questa e-mail. Il link sopra è valido per %(expires)s.\n"
" " " "
#: authentik/stages/email/templates/email/password_reset.txt #: authentik/stages/email/templates/email/password_reset.txt
@ -3500,11 +3485,11 @@ msgid ""
"If you did not request a password change, please ignore this email. The link above is valid for %(expires)s.\n" "If you did not request a password change, please ignore this email. The link above is valid for %(expires)s.\n"
msgstr "" msgstr ""
"\n" "\n"
"Se non hai richiesto una modifica della password, ignora questa email. Il link sopra è valido per %(expires)s.\n" "Se non hai richiesto una modifica della password, ignora questa e-mail. Il link sopra è valido per %(expires)s.\n"
#: authentik/stages/email/templates/email/setup.html #: authentik/stages/email/templates/email/setup.html
msgid "authentik Test-Email" msgid "authentik Test-Email"
msgstr "email di prova di authentik" msgstr "e-mail di prova di authentik"
#: authentik/stages/email/templates/email/setup.html #: authentik/stages/email/templates/email/setup.html
msgid "" msgid ""
@ -3513,7 +3498,7 @@ msgid ""
" " " "
msgstr "" msgstr ""
"\n" "\n"
" Questa è un'email di prova per informarti che hai configurato correttamente le email di authentik.\n" " Questa è un'e-mail di prova per informarti che hai configurato correttamente le e-mail di authentik.\n"
" " " "
#: authentik/stages/email/templates/email/setup.txt #: authentik/stages/email/templates/email/setup.txt
@ -3522,7 +3507,7 @@ msgid ""
"This is a test email to inform you, that you've successfully configured authentik emails.\n" "This is a test email to inform you, that you've successfully configured authentik emails.\n"
msgstr "" msgstr ""
"\n" "\n"
"Questa è un'email di prova per informarti che hai configurato correttamente le email di authentik.\n" "Questa è un'e-mail di prova per informarti che hai configurato correttamente le e-mail di authentik.\n"
#: authentik/stages/identification/api.py #: authentik/stages/identification/api.py
msgid "When no user fields are selected, at least one source must be selected" msgid "When no user fields are selected, at least one source must be selected"
@ -3725,7 +3710,7 @@ msgstr ""
#: authentik/stages/prompt/models.py #: authentik/stages/prompt/models.py
msgid "Email: Text field with Email type." msgid "Email: Text field with Email type."
msgstr "Email: Campo di testo con il tipo di email." msgstr "E-mail: Campo di testo con il tipo di e-mail."
#: authentik/stages/prompt/models.py #: authentik/stages/prompt/models.py
msgid "" msgid ""
@ -3880,6 +3865,10 @@ msgstr "Fasi di accesso utente"
msgid "No Pending user to login." msgid "No Pending user to login."
msgstr "Nessun utente in attesa di accesso." msgstr "Nessun utente in attesa di accesso."
#: authentik/stages/user_login/stage.py
msgid "Successfully logged in!"
msgstr "Accesso effettuato!"
#: authentik/stages/user_logout/models.py #: authentik/stages/user_logout/models.py
msgid "User Logout Stage" msgid "User Logout Stage"
msgstr "Fase di disconnessione dell'utente" msgstr "Fase di disconnessione dell'utente"

Binary file not shown.

View File

@ -15,7 +15,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-25 00:10+0000\n" "POT-Creation-Date: 2025-06-04 00:12+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n" "PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: deluxghost, 2025\n" "Last-Translator: deluxghost, 2025\n"
"Language-Team: Chinese Simplified (https://app.transifex.com/authentik/teams/119923/zh-Hans/)\n" "Language-Team: Chinese Simplified (https://app.transifex.com/authentik/teams/119923/zh-Hans/)\n"
@ -118,6 +118,10 @@ msgstr "品牌"
msgid "User does not have access to application." msgid "User does not have access to application."
msgstr "用户没有访问此应用程序的权限。" msgstr "用户没有访问此应用程序的权限。"
#: authentik/core/api/devices.py
msgid "Extra description not available"
msgstr "额外描述不可用"
#: authentik/core/api/groups.py #: authentik/core/api/groups.py
msgid "Cannot set group as parent of itself." msgid "Cannot set group as parent of itself."
msgstr "无法设置组自身为父级。" msgstr "无法设置组自身为父级。"
@ -771,12 +775,6 @@ msgid ""
"If left empty, Notification won't ben sent." "If left empty, Notification won't ben sent."
msgstr "定义此通知应该发送到哪些用户组。如果留空,则不会发送通知。" msgstr "定义此通知应该发送到哪些用户组。如果留空,则不会发送通知。"
#: authentik/events/models.py
msgid ""
"When enabled, notification will be sent to user the user that triggered the "
"event.When destination_group is configured, notification is sent to both."
msgstr "启用时,通知会被发送到触发事件的用户。当配置了 destination_group 时,通知也会同时发送到对应组。"
#: authentik/events/models.py #: authentik/events/models.py
msgid "Notification Rule" msgid "Notification Rule"
msgstr "通知规则" msgstr "通知规则"

Binary file not shown.

View File

@ -14,7 +14,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-06-25 00:10+0000\n" "POT-Creation-Date: 2025-06-04 00:12+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n" "PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: deluxghost, 2025\n" "Last-Translator: deluxghost, 2025\n"
"Language-Team: Chinese (China) (https://app.transifex.com/authentik/teams/119923/zh_CN/)\n" "Language-Team: Chinese (China) (https://app.transifex.com/authentik/teams/119923/zh_CN/)\n"
@ -117,6 +117,10 @@ msgstr "品牌"
msgid "User does not have access to application." msgid "User does not have access to application."
msgstr "用户没有访问此应用程序的权限。" msgstr "用户没有访问此应用程序的权限。"
#: authentik/core/api/devices.py
msgid "Extra description not available"
msgstr "额外描述不可用"
#: authentik/core/api/groups.py #: authentik/core/api/groups.py
msgid "Cannot set group as parent of itself." msgid "Cannot set group as parent of itself."
msgstr "无法设置组自身为父级。" msgstr "无法设置组自身为父级。"
@ -770,12 +774,6 @@ msgid ""
"If left empty, Notification won't ben sent." "If left empty, Notification won't ben sent."
msgstr "定义此通知应该发送到哪些用户组。如果留空,则不会发送通知。" msgstr "定义此通知应该发送到哪些用户组。如果留空,则不会发送通知。"
#: authentik/events/models.py
msgid ""
"When enabled, notification will be sent to user the user that triggered the "
"event.When destination_group is configured, notification is sent to both."
msgstr "启用时,通知会被发送到触发事件的用户。当配置了 destination_group 时,通知也会同时发送到对应组。"
#: authentik/events/models.py #: authentik/events/models.py
msgid "Notification Rule" msgid "Notification Rule"
msgstr "通知规则" msgstr "通知规则"

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "@goauthentik/authentik", "name": "@goauthentik/authentik",
"version": "2025.6.3", "version": "2025.6.2",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "@goauthentik/authentik", "name": "@goauthentik/authentik",
"version": "2025.6.3", "version": "2025.6.2",
"devDependencies": { "devDependencies": {
"@trivago/prettier-plugin-sort-imports": "^5.2.2", "@trivago/prettier-plugin-sort-imports": "^5.2.2",
"prettier": "^3.3.3", "prettier": "^3.3.3",

View File

@ -1,6 +1,6 @@
{ {
"name": "@goauthentik/authentik", "name": "@goauthentik/authentik",
"version": "2025.6.3", "version": "2025.6.2",
"private": true, "private": true,
"type": "module", "type": "module",
"devDependencies": { "devDependencies": {

View File

@ -2,8 +2,11 @@
* @file Prettier configuration for authentik. * @file Prettier configuration for authentik.
* *
* @import { Config as PrettierConfig } from "prettier"; * @import { Config as PrettierConfig } from "prettier";
* @import { PluginConfig as SortPluginConfig } from "@trivago/prettier-plugin-sort-imports"; */
*
import { importsPlugin } from "./imports.js";
/**
* @typedef {object} PackageJSONPluginConfig * @typedef {object} PackageJSONPluginConfig
* @property {string[]} [packageSortOrder] Custom ordering array. * @property {string[]} [packageSortOrder] Custom ordering array.
*/ */
@ -11,7 +14,7 @@
/** /**
* authentik Prettier configuration. * authentik Prettier configuration.
* *
* @type {PrettierConfig & SortPluginConfig & PackageJSONPluginConfig} * @type {PrettierConfig & PackageJSONPluginConfig}
* @internal * @internal
*/ */
export const AuthentikPrettierConfig = { export const AuthentikPrettierConfig = {
@ -34,32 +37,8 @@ export const AuthentikPrettierConfig = {
plugins: [ plugins: [
// --- // ---
"prettier-plugin-packagejson", "prettier-plugin-packagejson",
"@trivago/prettier-plugin-sort-imports", importsPlugin(),
], ],
importOrder: [
// ---
"^(@goauthentik/|#)common.+",
"^(@goauthentik/|#)elements.+",
"^(@goauthentik/|#)components.+",
"^(@goauthentik/|#)user.+",
"^(@goauthentik/|#)admin.+",
"^(@goauthentik/|#)flow.+",
"^#.+",
"^@goauthentik.+",
"<THIRD_PARTY_MODULES>",
"^(@?)lit(.*)$",
"\\.css$",
"^@goauthentik/api$",
"^[./]",
],
importOrderSideEffects: false,
importOrderSeparation: true,
importOrderSortSpecifiers: true,
importOrderParserPlugins: ["typescript", "jsx", "classProperties", "decorators-legacy"],
overrides: [ overrides: [
{ {
files: "schemas/**/*.json", files: "schemas/**/*.json",

View File

@ -0,0 +1,172 @@
import { createRequire } from "node:module";
import { formatSourceFromFile } from "format-imports";
import { parsers as babelParsers } from "prettier/plugins/babel";
/**
* @file Prettier import plugin.
*
* @import { Plugin, ParserOptions } from "prettier";
*/
import { parsers as typescriptParsers } from "prettier/plugins/typescript";
const require = createRequire(process.cwd() + "/");
/**
* @param {string} name
* @returns {string | null}
*/
function resolveModule(name) {
try {
return require.resolve(name);
} catch (error) {
return null;
}
}
const webSubmodules = [
// ---
"common",
"elements",
"components",
"user",
"admin",
"flow",
];
/**
* Ensure that every import without an extension adds one.
* @param {string} input
* @returns {string}
*/
function normalizeExtensions(input) {
return input.replace(/(?:import|from)\s*["']((?:\.\.?\/).*?)(?<!\.\w+)["']/gm, (line, path) => {
return line.replace(path, `${path}.js`);
});
}
/**
* @param {string} filepath
* @param {string} input
* @returns {string}
*/
function normalizeImports(filepath, input) {
let output = input;
// Replace all TypeScript imports with the paths resolved by Node/Browser import maps.
for (const submodule of webSubmodules) {
const legacyPattern = new RegExp(
[
// ---
`(?:import|from)`,
`\\\(?\\n?\\s*`,
`"(?<suffix>@goauthentik\/${submodule}\/)`,
`(?<path>[^"'.]+)`,
`(?:\.[^"']+)?["']`,
`\\n?\\s*\\\)?;`,
].join(""),
"gm",
);
output = output.replace(
legacyPattern,
/**
* @param {string} line
* @param {string} suffix
* @param {string} path
*/
(line, suffix, path) => {
const exported = `@goauthentik/web/${submodule}/${path}`;
let imported = `#${submodule}/${path}`;
let module = resolveModule(`${exported}.ts`);
if (!module) {
module = resolveModule(`${exported}/index.ts`);
imported += "/index";
}
if (imported.endsWith(".css")) {
imported += ".js";
}
if (!module) {
console.warn(`\nCannot resolve module ${exported} from ${filepath}`, {
line,
path,
exported,
imported,
module,
});
process.exit(1);
}
return (
line
// ---
.replace(suffix + path, imported)
.replace(`${imported}.js`, imported)
);
},
);
}
return output;
}
/**
* @returns {Plugin}
*/
export function importsPlugin({
useLegacyCleanup = process.env.AK_FIX_LEGACY_IMPORTS === "true",
} = {}) {
/**
* @param {string} input
* @param {ParserOptions} options
*/
const preprocess = (input, { filepath, printWidth }) => {
let output = input;
if (useLegacyCleanup) {
output = normalizeExtensions(input);
output = normalizeImports(filepath, output);
}
const value = formatSourceFromFile.sync(output, filepath, {
nodeProtocol: "always",
maxLineLength: printWidth,
wrappingStyle: "prettier",
groupRules: [
"^node:",
...webSubmodules.map((submodule) => `^(@goauthentik/|#)${submodule}.+`),
"^#.+",
"^@goauthentik.+",
{}, // Other imports.
"^(@?)lit(.*)$",
"\\.css$",
"^@goauthentik/api$",
"^[./]",
],
});
return value || input;
};
return {
parsers: {
typescript: {
...typescriptParsers.typescript,
preprocess,
},
babel: {
...babelParsers.babel,
preprocess,
},
},
};
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "@goauthentik/prettier-config", "name": "@goauthentik/prettier-config",
"version": "2.0.1", "version": "3.0.0",
"description": "authentik's Prettier config", "description": "authentik's Prettier config",
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
@ -10,19 +10,19 @@
}, },
"type": "module", "type": "module",
"exports": "./index.js", "exports": "./index.js",
"dependencies": {
"format-imports": "^4.0.7"
},
"devDependencies": { "devDependencies": {
"@goauthentik/tsconfig": "^1.0.1", "@goauthentik/tsconfig": "^1.0.1",
"@trivago/prettier-plugin-sort-imports": "^5.2.2", "@types/node": "^24.0.4",
"prettier": "^3.5.3", "prettier": "^3.6.1",
"prettier-plugin-organize-imports": "^4.1.0", "prettier-plugin-packagejson": "^2.5.16",
"prettier-plugin-packagejson": "^2.5.15",
"typescript": "^5.8.3" "typescript": "^5.8.3"
}, },
"peerDependencies": { "peerDependencies": {
"@trivago/prettier-plugin-sort-imports": "^5.2.2", "prettier": "^3.6.1",
"prettier": "^3.5.3", "prettier-plugin-packagejson": "^2.5.16"
"prettier-plugin-organize-imports": "^4.1.0",
"prettier-plugin-packagejson": "^2.5.15"
}, },
"engines": { "engines": {
"node": ">=22" "node": ">=22"

View File

@ -1,6 +1,6 @@
[project] [project]
name = "authentik" name = "authentik"
version = "2025.6.3" version = "2025.6.2"
description = "" description = ""
authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }] authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }]
requires-python = "==3.13.*" requires-python = "==3.13.*"
@ -57,7 +57,7 @@ dependencies = [
"pyyaml==6.0.2", "pyyaml==6.0.2",
"requests-oauthlib==2.0.0", "requests-oauthlib==2.0.0",
"scim2-filter-parser==0.7.0", "scim2-filter-parser==0.7.0",
"sentry-sdk==2.32.0", "sentry-sdk==2.31.0",
"service-identity==24.2.0", "service-identity==24.2.0",
"setproctitle==1.3.6", "setproctitle==1.3.6",
"structlog==25.4.0", "structlog==25.4.0",
@ -67,7 +67,7 @@ dependencies = [
"ua-parser==1.0.1", "ua-parser==1.0.1",
"unidecode==1.4.0", "unidecode==1.4.0",
"urllib3<3", "urllib3<3",
"uvicorn[standard]==0.35.0", "uvicorn[standard]==0.34.3",
"watchdog==6.0.0", "watchdog==6.0.0",
"webauthn==2.6.0", "webauthn==2.6.0",
"wsproto==1.2.0", "wsproto==1.2.0",

View File

@ -1,7 +1,7 @@
openapi: 3.0.3 openapi: 3.0.3
info: info:
title: authentik title: authentik
version: 2025.6.3 version: 2025.6.2
description: Making authentication simple. description: Making authentication simple.
contact: contact:
email: hello@goauthentik.io email: hello@goauthentik.io
@ -24864,7 +24864,6 @@ paths:
- authentik_policies_password.passwordpolicy - authentik_policies_password.passwordpolicy
- authentik_policies_reputation.reputationpolicy - authentik_policies_reputation.reputationpolicy
- authentik_policies_unique_password.uniquepasswordpolicy - authentik_policies_unique_password.uniquepasswordpolicy
- authentik_providers_apple_psso.appleplatformssoprovider
- authentik_providers_google_workspace.googleworkspaceprovider - authentik_providers_google_workspace.googleworkspaceprovider
- authentik_providers_google_workspace.googleworkspaceprovidermapping - authentik_providers_google_workspace.googleworkspaceprovidermapping
- authentik_providers_ldap.ldapprovider - authentik_providers_ldap.ldapprovider
@ -25114,7 +25113,6 @@ paths:
- authentik_policies_password.passwordpolicy - authentik_policies_password.passwordpolicy
- authentik_policies_reputation.reputationpolicy - authentik_policies_reputation.reputationpolicy
- authentik_policies_unique_password.uniquepasswordpolicy - authentik_policies_unique_password.uniquepasswordpolicy
- authentik_providers_apple_psso.appleplatformssoprovider
- authentik_providers_google_workspace.googleworkspaceprovider - authentik_providers_google_workspace.googleworkspaceprovider
- authentik_providers_google_workspace.googleworkspaceprovidermapping - authentik_providers_google_workspace.googleworkspaceprovidermapping
- authentik_providers_ldap.ldapprovider - authentik_providers_ldap.ldapprovider
@ -41214,7 +41212,6 @@ components:
- authentik.enterprise - authentik.enterprise
- authentik.enterprise.audit - authentik.enterprise.audit
- authentik.enterprise.policies.unique_password - authentik.enterprise.policies.unique_password
- authentik.enterprise.providers.apple_psso
- authentik.enterprise.providers.google_workspace - authentik.enterprise.providers.google_workspace
- authentik.enterprise.providers.microsoft_entra - authentik.enterprise.providers.microsoft_entra
- authentik.enterprise.providers.ssf - authentik.enterprise.providers.ssf
@ -41261,15 +41258,6 @@ components:
- redirect_uri - redirect_uri
- scope - scope
- state - state
ApplePlatformSSOProviderRequest:
type: object
description: ApplePlatformSSOProvider Serializer
properties:
name:
type: string
minLength: 1
required:
- name
Application: Application:
type: object type: object
description: Application Serializer description: Application Serializer
@ -48726,7 +48714,6 @@ components:
- authentik_core.token - authentik_core.token
- authentik_enterprise.license - authentik_enterprise.license
- authentik_policies_unique_password.uniquepasswordpolicy - authentik_policies_unique_password.uniquepasswordpolicy
- authentik_providers_apple_psso.appleplatformssoprovider
- authentik_providers_google_workspace.googleworkspaceprovider - authentik_providers_google_workspace.googleworkspaceprovider
- authentik_providers_google_workspace.googleworkspaceprovidermapping - authentik_providers_google_workspace.googleworkspaceprovidermapping
- authentik_providers_microsoft_entra.microsoftentraprovider - authentik_providers_microsoft_entra.microsoftentraprovider
@ -56672,7 +56659,6 @@ components:
type: string type: string
ProviderModelEnum: ProviderModelEnum:
enum: enum:
- authentik_providers_apple_psso.appleplatformssoprovider
- authentik_providers_google_workspace.googleworkspaceprovider - authentik_providers_google_workspace.googleworkspaceprovider
- authentik_providers_ldap.ldapprovider - authentik_providers_ldap.ldapprovider
- authentik_providers_microsoft_entra.microsoftentraprovider - authentik_providers_microsoft_entra.microsoftentraprovider
@ -61885,7 +61871,6 @@ components:
- worker_id - worker_id
modelRequest: modelRequest:
oneOf: oneOf:
- $ref: '#/components/schemas/ApplePlatformSSOProviderRequest'
- $ref: '#/components/schemas/GoogleWorkspaceProviderRequest' - $ref: '#/components/schemas/GoogleWorkspaceProviderRequest'
- $ref: '#/components/schemas/LDAPProviderRequest' - $ref: '#/components/schemas/LDAPProviderRequest'
- $ref: '#/components/schemas/MicrosoftEntraProviderRequest' - $ref: '#/components/schemas/MicrosoftEntraProviderRequest'
@ -61899,7 +61884,6 @@ components:
discriminator: discriminator:
propertyName: provider_model propertyName: provider_model
mapping: mapping:
authentik_providers_apple_psso.appleplatformssoprovider: '#/components/schemas/ApplePlatformSSOProviderRequest'
authentik_providers_google_workspace.googleworkspaceprovider: '#/components/schemas/GoogleWorkspaceProviderRequest' authentik_providers_google_workspace.googleworkspaceprovider: '#/components/schemas/GoogleWorkspaceProviderRequest'
authentik_providers_ldap.ldapprovider: '#/components/schemas/LDAPProviderRequest' authentik_providers_ldap.ldapprovider: '#/components/schemas/LDAPProviderRequest'
authentik_providers_microsoft_entra.microsoftentraprovider: '#/components/schemas/MicrosoftEntraProviderRequest' authentik_providers_microsoft_entra.microsoftentraprovider: '#/components/schemas/MicrosoftEntraProviderRequest'

View File

@ -7,7 +7,7 @@ services:
network_mode: host network_mode: host
restart: always restart: always
mailpit: mailpit:
image: docker.io/axllent/mailpit:v1.27.0 image: docker.io/axllent/mailpit:v1.26.2
ports: ports:
- 1025:1025 - 1025:1025
- 8025:8025 - 8025:8025

18
uv.lock generated
View File

@ -165,7 +165,7 @@ wheels = [
[[package]] [[package]]
name = "authentik" name = "authentik"
version = "2025.6.3" version = "2025.6.2"
source = { editable = "." } source = { editable = "." }
dependencies = [ dependencies = [
{ name = "argon2-cffi" }, { name = "argon2-cffi" },
@ -319,7 +319,7 @@ requires-dist = [
{ name = "pyyaml", specifier = "==6.0.2" }, { name = "pyyaml", specifier = "==6.0.2" },
{ name = "requests-oauthlib", specifier = "==2.0.0" }, { name = "requests-oauthlib", specifier = "==2.0.0" },
{ name = "scim2-filter-parser", specifier = "==0.7.0" }, { name = "scim2-filter-parser", specifier = "==0.7.0" },
{ name = "sentry-sdk", specifier = "==2.32.0" }, { name = "sentry-sdk", specifier = "==2.31.0" },
{ name = "service-identity", specifier = "==24.2.0" }, { name = "service-identity", specifier = "==24.2.0" },
{ name = "setproctitle", specifier = "==1.3.6" }, { name = "setproctitle", specifier = "==1.3.6" },
{ name = "structlog", specifier = "==25.4.0" }, { name = "structlog", specifier = "==25.4.0" },
@ -329,7 +329,7 @@ requires-dist = [
{ name = "ua-parser", specifier = "==1.0.1" }, { name = "ua-parser", specifier = "==1.0.1" },
{ name = "unidecode", specifier = "==1.4.0" }, { name = "unidecode", specifier = "==1.4.0" },
{ name = "urllib3", specifier = "<3" }, { name = "urllib3", specifier = "<3" },
{ name = "uvicorn", extras = ["standard"], specifier = "==0.35.0" }, { name = "uvicorn", extras = ["standard"], specifier = "==0.34.3" },
{ name = "watchdog", specifier = "==6.0.0" }, { name = "watchdog", specifier = "==6.0.0" },
{ name = "webauthn", specifier = "==2.6.0" }, { name = "webauthn", specifier = "==2.6.0" },
{ name = "wsproto", specifier = "==1.2.0" }, { name = "wsproto", specifier = "==1.2.0" },
@ -2961,15 +2961,15 @@ wheels = [
[[package]] [[package]]
name = "sentry-sdk" name = "sentry-sdk"
version = "2.32.0" version = "2.31.0"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "certifi" }, { name = "certifi" },
{ name = "urllib3" }, { name = "urllib3" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/10/59/eb90c45cb836cf8bec973bba10230ddad1c55e2b2e9ffa9d7d7368948358/sentry_sdk-2.32.0.tar.gz", hash = "sha256:9016c75d9316b0f6921ac14c8cd4fb938f26002430ac5be9945ab280f78bec6b", size = 334932, upload-time = "2025-06-27T08:10:02.89Z" } sdist = { url = "https://files.pythonhosted.org/packages/d0/45/c7ef7e12d8434fda8b61cdab432d8af64fb832480c93cdaf4bdcab7f5597/sentry_sdk-2.31.0.tar.gz", hash = "sha256:fed6d847f15105849cdf5dfdc64dcec356f936d41abb8c9d66adae45e60959ec", size = 334167, upload-time = "2025-06-24T16:36:26.066Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/01/a1/fc4856bd02d2097324fb7ce05b3021fb850f864b83ca765f6e37e92ff8ca/sentry_sdk-2.32.0-py2.py3-none-any.whl", hash = "sha256:6cf51521b099562d7ce3606da928c473643abe99b00ce4cb5626ea735f4ec345", size = 356122, upload-time = "2025-06-27T08:10:01.424Z" }, { url = "https://files.pythonhosted.org/packages/7d/a2/9b6d8cc59f03251c583b3fec9d2f075dc09c0f6e030e0e0a3b223c6e64b2/sentry_sdk-2.31.0-py2.py3-none-any.whl", hash = "sha256:e953f5ab083e6599bab255b75d6829b33b3ddf9931a27ca00b4ab0081287e84f", size = 355638, upload-time = "2025-06-24T16:36:24.306Z" },
] ]
[[package]] [[package]]
@ -3322,15 +3322,15 @@ socks = [
[[package]] [[package]]
name = "uvicorn" name = "uvicorn"
version = "0.35.0" version = "0.34.3"
source = { registry = "https://pypi.org/simple" } source = { registry = "https://pypi.org/simple" }
dependencies = [ dependencies = [
{ name = "click" }, { name = "click" },
{ name = "h11" }, { name = "h11" },
] ]
sdist = { url = "https://files.pythonhosted.org/packages/5e/42/e0e305207bb88c6b8d3061399c6a961ffe5fbb7e2aa63c9234df7259e9cd/uvicorn-0.35.0.tar.gz", hash = "sha256:bc662f087f7cf2ce11a1d7fd70b90c9f98ef2e2831556dd078d131b96cc94a01", size = 78473, upload-time = "2025-06-28T16:15:46.058Z" } sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631, upload-time = "2025-06-01T07:48:17.531Z" }
wheels = [ wheels = [
{ url = "https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl", hash = "sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a", size = 66406, upload-time = "2025-06-28T16:15:44.816Z" }, { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431, upload-time = "2025-06-01T07:48:15.664Z" },
] ]
[package.optional-dependencies] [package.optional-dependencies]

View File

@ -4,7 +4,6 @@
* @import { InlineConfig, Plugin } from "vite"; * @import { InlineConfig, Plugin } from "vite";
*/ */
import postcssLit from "rollup-plugin-postcss-lit"; import postcssLit from "rollup-plugin-postcss-lit";
import tsconfigPaths from "vite-tsconfig-paths";
const CSSImportPattern = /import [\w$]+ from .+\.(css)/g; const CSSImportPattern = /import [\w$]+ from .+\.(css)/g;
const JavaScriptFilePattern = /\.m?(js|ts|tsx)$/; const JavaScriptFilePattern = /\.m?(js|ts|tsx)$/;
@ -61,7 +60,7 @@ const config = {
*/ */
const overrides = { const overrides = {
define: createBundleDefinitions(), define: createBundleDefinitions(),
plugins: [inlineCSSPlugin, postcssLit(), tsconfigPaths()], plugins: [inlineCSSPlugin, postcssLit()],
}; };
return mergeConfig(config, overrides); return mergeConfig(config, overrides);

View File

@ -4,6 +4,7 @@
* @import { ThemeVarsPartial } from "storybook/internal/theming"; * @import { ThemeVarsPartial } from "storybook/internal/theming";
*/ */
import { createUIThemeEffect, resolveUITheme } from "@goauthentik/web/common/theme.ts"; import { createUIThemeEffect, resolveUITheme } from "@goauthentik/web/common/theme.ts";
import { addons } from "@storybook/manager-api"; import { addons } from "@storybook/manager-api";
import { create } from "@storybook/theming/create"; import { create } from "@storybook/theming/create";

View File

@ -10,10 +10,11 @@
* PluginBuild * PluginBuild
* } from "esbuild" * } from "esbuild"
*/ */
import { MonoRepoRoot } from "@goauthentik/core/paths/node";
import * as fs from "node:fs/promises"; import * as fs from "node:fs/promises";
import * as path from "node:path"; import * as path from "node:path";
import { MonoRepoRoot } from "@goauthentik/core/paths/node";
/** /**
* @typedef {Omit<OnLoadArgs, 'pluginData'> & LoadDataFields} LoadData Data passed to `onload`. * @typedef {Omit<OnLoadArgs, 'pluginData'> & LoadDataFields} LoadData Data passed to `onload`.
* *

View File

@ -1,4 +1,5 @@
import { createESLintPackageConfig } from "@goauthentik/eslint-config"; import { createESLintPackageConfig } from "@goauthentik/eslint-config";
import tseslint from "typescript-eslint"; import tseslint from "typescript-eslint";
// @ts-check // @ts-check

46
web/package-lock.json generated
View File

@ -128,7 +128,6 @@
"typescript": "^5.8.3", "typescript": "^5.8.3",
"typescript-eslint": "^8.35.0", "typescript-eslint": "^8.35.0",
"vite-plugin-lit-css": "^2.0.0", "vite-plugin-lit-css": "^2.0.0",
"vite-tsconfig-paths": "^5.0.1",
"wireit": "^0.14.12" "wireit": "^0.14.12"
}, },
"engines": { "engines": {
@ -16314,12 +16313,6 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/globrex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==",
"dev": true
},
"node_modules/gopd": { "node_modules/gopd": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@ -26430,26 +26423,6 @@
"resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz", "resolved": "https://registry.npmjs.org/ts-toolbelt/-/ts-toolbelt-9.6.0.tgz",
"integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==" "integrity": "sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w=="
}, },
"node_modules/tsconfck": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.3.tgz",
"integrity": "sha512-ulNZP1SVpRDesxeMLON/LtWM8HIgAJEIVpVVhBM6gsmvQ8+Rh+ZG7FWGvHh7Ah3pRABwVJWklWCr/BTZSv0xnQ==",
"dev": true,
"bin": {
"tsconfck": "bin/tsconfck.js"
},
"engines": {
"node": "^18 || >=20"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/tsconfig-paths": { "node_modules/tsconfig-paths": {
"version": "3.15.0", "version": "3.15.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
@ -27772,25 +27745,6 @@
"uuid": "dist/bin/uuid" "uuid": "dist/bin/uuid"
} }
}, },
"node_modules/vite-tsconfig-paths": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-5.0.1.tgz",
"integrity": "sha512-yqwv+LstU7NwPeNqajZzLEBVpUFU6Dugtb2P84FXuvaoYA+/70l9MHE+GYfYAycVyPSDYZ7mjOFuYBRqlEpTig==",
"dev": true,
"dependencies": {
"debug": "^4.1.1",
"globrex": "^0.1.2",
"tsconfck": "^3.0.3"
},
"peerDependencies": {
"vite": "*"
},
"peerDependenciesMeta": {
"vite": {
"optional": true
}
}
},
"node_modules/vite/node_modules/@esbuild/aix-ppc64": { "node_modules/vite/node_modules/@esbuild/aix-ppc64": {
"version": "0.21.5", "version": "0.21.5",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz",

View File

@ -148,7 +148,7 @@
"@goauthentik/core": "^1.0.0", "@goauthentik/core": "^1.0.0",
"@goauthentik/esbuild-plugin-live-reload": "^1.0.5", "@goauthentik/esbuild-plugin-live-reload": "^1.0.5",
"@goauthentik/eslint-config": "^1.0.5", "@goauthentik/eslint-config": "^1.0.5",
"@goauthentik/prettier-config": "^1.0.5", "@goauthentik/prettier-config": "^3.0.0",
"@goauthentik/tsconfig": "^1.0.4", "@goauthentik/tsconfig": "^1.0.4",
"@hcaptcha/types": "^1.0.4", "@hcaptcha/types": "^1.0.4",
"@lit/localize-tools": "^0.8.0", "@lit/localize-tools": "^0.8.0",
@ -199,7 +199,6 @@
"typescript": "^5.8.3", "typescript": "^5.8.3",
"typescript-eslint": "^8.35.0", "typescript-eslint": "^8.35.0",
"vite-plugin-lit-css": "^2.0.0", "vite-plugin-lit-css": "^2.0.0",
"vite-tsconfig-paths": "^5.0.1",
"wireit": "^0.14.12" "wireit": "^0.14.12"
}, },
"optionalDependencies": { "optionalDependencies": {

View File

@ -7,6 +7,4 @@
* @ignore * @ignore
*/ */
export {};
export default {}; export default {};

View File

@ -3,9 +3,12 @@
* *
* @runtime node * @runtime node
*/ */
import { MonoRepoRoot } from "#paths/node";
import { execSync } from "node:child_process"; import { execSync } from "node:child_process";
import { MonoRepoRoot } from "#paths/node";
// ts-import-sorter: disable
import PackageJSON from "../../../../package.json" with { type: "json" }; import PackageJSON from "../../../../package.json" with { type: "json" };
/** /**

View File

@ -1,10 +1,11 @@
/** /**
* @file Rollup configuration for the SFE package. * @file Rollup configuration for the SFE package.
*/ */
import { resolve as resolvePath } from "node:path";
import commonjs from "@rollup/plugin-commonjs"; import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve"; import resolve from "@rollup/plugin-node-resolve";
import swc from "@rollup/plugin-swc"; import swc from "@rollup/plugin-swc";
import { resolve as resolvePath } from "node:path";
import copy from "rollup-plugin-copy"; import copy from "rollup-plugin-copy";
export async function createConfig() { export async function createConfig() {

View File

@ -1,6 +1,4 @@
import { fromByteArray } from "base64-js";
import "formdata-polyfill"; import "formdata-polyfill";
import $ from "jquery";
import "weakmap-polyfill"; import "weakmap-polyfill";
import { import {
@ -16,6 +14,9 @@ import {
type RedirectChallenge, type RedirectChallenge,
} from "@goauthentik/api"; } from "@goauthentik/api";
import { fromByteArray } from "base64-js";
import $ from "jquery";
interface GlobalAuthentik { interface GlobalAuthentik {
brand: { brand: {
branding_logo: string; branding_logo: string;

View File

@ -3,10 +3,12 @@
* *
* @runtime node * @runtime node
*/ */
import { DistDirectoryName } from "#paths";
import { dirname, resolve } from "node:path"; import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url"; import { fileURLToPath } from "node:url";
import { DistDirectoryName } from "#paths";
const relativeDirname = dirname(fileURLToPath(import.meta.url)); const relativeDirname = dirname(fileURLToPath(import.meta.url));
//#region Base paths //#region Base paths

View File

@ -9,14 +9,15 @@
* long spew of "this string is not translated" and replacing it with a * long spew of "this string is not translated" and replacing it with a
* summary of how many strings are missing with respect to the source locale. * summary of how many strings are missing with respect to the source locale.
* *
* @import { ConfigFile } from "@lit/localize-tools/lib/types/config" * @import { ConfigFile } from "@lit/localize-tools/lib/types/config.js"
* @import { Stats } from "fs"; * @import { Stats } from "node:fs";
*/ */
import { PackageRoot } from "#paths/node";
import { spawnSync } from "node:child_process"; import { spawnSync } from "node:child_process";
import { readFileSync, statSync } from "node:fs"; import { readFileSync, statSync } from "node:fs";
import path from "node:path"; import path from "node:path";
import { PackageRoot } from "#paths/node";
/** /**
* @type {ConfigFile} * @type {ConfigFile}
*/ */

View File

@ -1,21 +1,25 @@
/// <reference types="../types/esbuild.js" />
/** /**
* @file ESBuild script for building the authentik web UI. * @file ESBuild script for building the authentik web UI.
* *
* @import { BuildOptions } from "esbuild"; * @import { BuildOptions } from "esbuild";
*/ */
import * as fs from "node:fs/promises";
import * as path from "node:path";
import { mdxPlugin } from "#bundler/mdx-plugin/node"; import { mdxPlugin } from "#bundler/mdx-plugin/node";
import { createBundleDefinitions } from "#bundler/utils/node"; import { createBundleDefinitions } from "#bundler/utils/node";
import { DistDirectory, EntryPoint, PackageRoot } from "#paths/node"; import { DistDirectory, EntryPoint, PackageRoot } from "#paths/node";
import { NodeEnvironment } from "@goauthentik/core/environment/node"; import { NodeEnvironment } from "@goauthentik/core/environment/node";
import { MonoRepoRoot, resolvePackage } from "@goauthentik/core/paths/node"; import { MonoRepoRoot, resolvePackage } from "@goauthentik/core/paths/node";
import { readBuildIdentifier } from "@goauthentik/core/version/node"; import { readBuildIdentifier } from "@goauthentik/core/version/node";
import { deepmerge } from "deepmerge-ts"; import { deepmerge } from "deepmerge-ts";
import esbuild from "esbuild"; import esbuild from "esbuild";
import copy from "esbuild-plugin-copy"; import { copy } from "esbuild-plugin-copy";
import { polyfillNode } from "esbuild-plugin-polyfill-node"; import { polyfillNode } from "esbuild-plugin-polyfill-node";
import * as fs from "node:fs/promises";
import * as path from "node:path"; /// <reference types="../types/esbuild.js" />
const logPrefix = "[Build]"; const logPrefix = "[Build]";

View File

@ -6,9 +6,12 @@
* @import { ProgramMessage } from "@lit/localize-tools/src/messages.js" * @import { ProgramMessage } from "@lit/localize-tools/src/messages.js"
* @import { Locale } from "@lit/localize-tools/src/types/locale.js" * @import { Locale } from "@lit/localize-tools/src/types/locale.js"
*/ */
import { PackageRoot } from "#paths/node";
import { readFileSync } from "node:fs"; import { readFileSync } from "node:fs";
import path from "node:path"; import path from "node:path";
import { PackageRoot } from "#paths/node";
import pseudolocale from "pseudolocale"; import pseudolocale from "pseudolocale";
import { makeFormatter } from "@lit/localize-tools/lib/formatters/index.js"; import { makeFormatter } from "@lit/localize-tools/lib/formatters/index.js";

View File

@ -1,19 +1,21 @@
import "#elements/EmptyState";
import { DEFAULT_CONFIG } from "#common/api/config";
import { globalAK } from "#common/global";
import { ModalButton } from "#elements/buttons/ModalButton";
import { WithBrandConfig } from "#elements/mixins/branding"; import { WithBrandConfig } from "#elements/mixins/branding";
import { WithLicenseSummary } from "#elements/mixins/license"; import { WithLicenseSummary } from "#elements/mixins/license";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { globalAK } from "@goauthentik/common/global"; import { AdminApi, CapabilitiesEnum, LicenseSummaryStatusEnum } from "@goauthentik/api";
import "@goauthentik/elements/EmptyState";
import { ModalButton } from "@goauthentik/elements/buttons/ModalButton";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { TemplateResult, css, html } from "lit"; import { css, html, TemplateResult } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import { until } from "lit/directives/until.js"; import { until } from "lit/directives/until.js";
import PFAbout from "@patternfly/patternfly/components/AboutModalBox/about-modal-box.css"; import PFAbout from "@patternfly/patternfly/components/AboutModalBox/about-modal-box.css";
import { AdminApi, CapabilitiesEnum, LicenseSummaryStatusEnum } from "@goauthentik/api";
@customElement("ak-about-modal") @customElement("ak-about-modal")
export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton)) { export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton)) {
static get styles() { static get styles() {

View File

@ -1,8 +1,9 @@
import { ID_REGEX, SLUG_REGEX, UUID_REGEX } from "@goauthentik/elements/router/Route"; import { ID_REGEX, SLUG_REGEX, UUID_REGEX } from "#elements/router/Route";
import { spread } from "@open-wc/lit-helpers"; import { spread } from "@open-wc/lit-helpers";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { TemplateResult, html, nothing } from "lit"; import { html, nothing, TemplateResult } from "lit";
import { repeat } from "lit/directives/repeat.js"; import { repeat } from "lit/directives/repeat.js";
// The second attribute type is of string[] to help with the 'activeWhen' control, which was // The second attribute type is of string[] to help with the 'activeWhen' control, which was

View File

@ -1,28 +1,31 @@
import "#admin/AdminInterface/AboutModal"; import "#admin/AdminInterface/AboutModal";
import type { AboutModal } from "#admin/AdminInterface/AboutModal";
import { ROUTES } from "#admin/Routes";
import { EVENT_API_DRAWER_TOGGLE, EVENT_NOTIFICATION_DRAWER_TOGGLE } from "#common/constants";
import { configureSentry } from "#common/sentry/index";
import { me } from "#common/users";
import { WebsocketClient } from "#common/ws";
import { SidebarToggleEventDetail } from "#components/ak-page-header";
import { AuthenticatedInterface } from "#elements/AuthenticatedInterface";
import "#elements/ak-locale-context/ak-locale-context"; import "#elements/ak-locale-context/ak-locale-context";
import "#elements/banner/EnterpriseStatusBanner"; import "#elements/banner/EnterpriseStatusBanner";
import "#elements/banner/EnterpriseStatusBanner";
import "#elements/banner/VersionBanner";
import "#elements/banner/VersionBanner"; import "#elements/banner/VersionBanner";
import "#elements/messages/MessageContainer"; import "#elements/messages/MessageContainer";
import "#elements/messages/MessageContainer";
import { WithCapabilitiesConfig } from "#elements/mixins/capabilities";
import "#elements/notifications/APIDrawer"; import "#elements/notifications/APIDrawer";
import "#elements/notifications/NotificationDrawer"; import "#elements/notifications/NotificationDrawer";
import { getURLParam, updateURLParams } from "#elements/router/RouteMatch";
import "#elements/router/RouterOutlet"; import "#elements/router/RouterOutlet";
import "#elements/sidebar/Sidebar"; import "#elements/sidebar/Sidebar";
import "#elements/sidebar/SidebarItem"; import "#elements/sidebar/SidebarItem";
import { CSSResult, TemplateResult, css, html, nothing } from "lit"; import { EVENT_API_DRAWER_TOGGLE, EVENT_NOTIFICATION_DRAWER_TOGGLE } from "#common/constants";
import { configureSentry } from "#common/sentry/index";
import { me } from "#common/users";
import { WebsocketClient } from "#common/ws";
import { AuthenticatedInterface } from "#elements/AuthenticatedInterface";
import { WithCapabilitiesConfig } from "#elements/mixins/capabilities";
import { getURLParam, updateURLParams } from "#elements/router/RouteMatch";
import { SidebarToggleEventDetail } from "#components/ak-page-header";
import type { AboutModal } from "#admin/AdminInterface/AboutModal";
import { ROUTES } from "#admin/Routes";
import { CapabilitiesEnum, SessionUser, UiThemeEnum } from "@goauthentik/api";
import { css, CSSResult, html, nothing, TemplateResult } from "lit";
import { customElement, eventOptions, property, query } from "lit/decorators.js"; import { customElement, eventOptions, property, query } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js"; import { classMap } from "lit/directives/class-map.js";
@ -32,8 +35,6 @@ import PFNav from "@patternfly/patternfly/components/Nav/nav.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css"; import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { CapabilitiesEnum, SessionUser, UiThemeEnum } from "@goauthentik/api";
import { import {
AdminSidebarEnterpriseEntries, AdminSidebarEnterpriseEntries,
AdminSidebarEntries, AdminSidebarEntries,

View File

@ -1,12 +1,17 @@
import "#components/ak-page-header";
import { DEFAULT_CONFIG } from "#common/api/config"; import { DEFAULT_CONFIG } from "#common/api/config";
import { parseAPIResponseError, pluckErrorDetail } from "#common/errors/network"; import { parseAPIResponseError, pluckErrorDetail } from "#common/errors/network";
import { MessageLevel } from "#common/messages"; import { MessageLevel } from "#common/messages";
import "#components/ak-page-header";
import { AKElement } from "#elements/Base"; import { AKElement } from "#elements/Base";
import { showMessage } from "#elements/messages/MessageContainer"; import { showMessage } from "#elements/messages/MessageContainer";
import { AdminApi } from "@goauthentik/api";
import * as Sentry from "@sentry/browser"; import * as Sentry from "@sentry/browser";
import { CSSResult, TemplateResult, html } from "lit"; import { CSSResult, html, TemplateResult } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import PFButton from "@patternfly/patternfly/components/Button/button.css"; import PFButton from "@patternfly/patternfly/components/Button/button.css";
@ -15,8 +20,6 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css"; import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { AdminApi } from "@goauthentik/api";
@customElement("ak-admin-debug-page") @customElement("ak-admin-debug-page")
export class DebugPage extends AKElement { export class DebugPage extends AKElement {
static get styles(): CSSResult[] { static get styles(): CSSResult[] {

View File

@ -1,5 +1,6 @@
import "@goauthentik/admin/admin-overview/AdminOverviewPage"; import "#admin/admin-overview/AdminOverviewPage";
import { ID_REGEX, Route, SLUG_REGEX, UUID_REGEX } from "@goauthentik/elements/router/Route";
import { ID_REGEX, Route, SLUG_REGEX, UUID_REGEX } from "#elements/router/Route";
import { html } from "lit"; import { html } from "lit";
@ -13,147 +14,147 @@ export const ROUTES: Route[] = [
return html`<ak-admin-overview></ak-admin-overview>`; return html`<ak-admin-overview></ak-admin-overview>`;
}), }),
new Route(new RegExp("^/administration/dashboard/users$"), async () => { new Route(new RegExp("^/administration/dashboard/users$"), async () => {
await import("@goauthentik/admin/admin-overview/DashboardUserPage"); await import("#admin/admin-overview/DashboardUserPage");
return html`<ak-admin-dashboard-users></ak-admin-dashboard-users>`; return html`<ak-admin-dashboard-users></ak-admin-dashboard-users>`;
}), }),
new Route(new RegExp("^/administration/system-tasks$"), async () => { new Route(new RegExp("^/administration/system-tasks$"), async () => {
await import("@goauthentik/admin/system-tasks/SystemTaskListPage"); await import("#admin/system-tasks/SystemTaskListPage");
return html`<ak-system-task-list></ak-system-task-list>`; return html`<ak-system-task-list></ak-system-task-list>`;
}), }),
new Route(new RegExp("^/core/providers$"), async () => { new Route(new RegExp("^/core/providers$"), async () => {
await import("@goauthentik/admin/providers/ProviderListPage"); await import("#admin/providers/ProviderListPage");
return html`<ak-provider-list></ak-provider-list>`; return html`<ak-provider-list></ak-provider-list>`;
}), }),
new Route(new RegExp(`^/core/providers/(?<id>${ID_REGEX})$`), async (args) => { new Route(new RegExp(`^/core/providers/(?<id>${ID_REGEX})$`), async (args) => {
await import("@goauthentik/admin/providers/ProviderViewPage"); await import("#admin/providers/ProviderViewPage");
return html`<ak-provider-view .providerID=${parseInt(args.id, 10)}></ak-provider-view>`; return html`<ak-provider-view .providerID=${parseInt(args.id, 10)}></ak-provider-view>`;
}), }),
new Route(new RegExp("^/core/applications$"), async () => { new Route(new RegExp("^/core/applications$"), async () => {
await import("@goauthentik/admin/applications/ApplicationListPage"); await import("#admin/applications/ApplicationListPage");
return html`<ak-application-list></ak-application-list>`; return html`<ak-application-list></ak-application-list>`;
}), }),
new Route(new RegExp(`^/core/applications/(?<slug>${SLUG_REGEX})$`), async (args) => { new Route(new RegExp(`^/core/applications/(?<slug>${SLUG_REGEX})$`), async (args) => {
await import("@goauthentik/admin/applications/ApplicationViewPage"); await import("#admin/applications/ApplicationViewPage");
return html`<ak-application-view .applicationSlug=${args.slug}></ak-application-view>`; return html`<ak-application-view .applicationSlug=${args.slug}></ak-application-view>`;
}), }),
new Route(new RegExp("^/core/sources$"), async () => { new Route(new RegExp("^/core/sources$"), async () => {
await import("@goauthentik/admin/sources/SourceListPage"); await import("#admin/sources/SourceListPage");
return html`<ak-source-list></ak-source-list>`; return html`<ak-source-list></ak-source-list>`;
}), }),
new Route(new RegExp(`^/core/sources/(?<slug>${SLUG_REGEX})$`), async (args) => { new Route(new RegExp(`^/core/sources/(?<slug>${SLUG_REGEX})$`), async (args) => {
await import("@goauthentik/admin/sources/SourceViewPage"); await import("#admin/sources/SourceViewPage");
return html`<ak-source-view .sourceSlug=${args.slug}></ak-source-view>`; return html`<ak-source-view .sourceSlug=${args.slug}></ak-source-view>`;
}), }),
new Route(new RegExp("^/core/property-mappings$"), async () => { new Route(new RegExp("^/core/property-mappings$"), async () => {
await import("@goauthentik/admin/property-mappings/PropertyMappingListPage"); await import("#admin/property-mappings/PropertyMappingListPage");
return html`<ak-property-mapping-list></ak-property-mapping-list>`; return html`<ak-property-mapping-list></ak-property-mapping-list>`;
}), }),
new Route(new RegExp("^/core/tokens$"), async () => { new Route(new RegExp("^/core/tokens$"), async () => {
await import("@goauthentik/admin/tokens/TokenListPage"); await import("#admin/tokens/TokenListPage");
return html`<ak-token-list></ak-token-list>`; return html`<ak-token-list></ak-token-list>`;
}), }),
new Route(new RegExp("^/core/brands"), async () => { new Route(new RegExp("^/core/brands"), async () => {
await import("@goauthentik/admin/brands/BrandListPage"); await import("#admin/brands/BrandListPage");
return html`<ak-brand-list></ak-brand-list>`; return html`<ak-brand-list></ak-brand-list>`;
}), }),
new Route(new RegExp("^/policy/policies$"), async () => { new Route(new RegExp("^/policy/policies$"), async () => {
await import("@goauthentik/admin/policies/PolicyListPage"); await import("#admin/policies/PolicyListPage");
return html`<ak-policy-list></ak-policy-list>`; return html`<ak-policy-list></ak-policy-list>`;
}), }),
new Route(new RegExp("^/policy/reputation$"), async () => { new Route(new RegExp("^/policy/reputation$"), async () => {
await import("@goauthentik/admin/policies/reputation/ReputationListPage"); await import("#admin/policies/reputation/ReputationListPage");
return html`<ak-policy-reputation-list></ak-policy-reputation-list>`; return html`<ak-policy-reputation-list></ak-policy-reputation-list>`;
}), }),
new Route(new RegExp("^/identity/groups$"), async () => { new Route(new RegExp("^/identity/groups$"), async () => {
await import("@goauthentik/admin/groups/GroupListPage"); await import("#admin/groups/GroupListPage");
return html`<ak-group-list></ak-group-list>`; return html`<ak-group-list></ak-group-list>`;
}), }),
new Route(new RegExp(`^/identity/groups/(?<uuid>${UUID_REGEX})$`), async (args) => { new Route(new RegExp(`^/identity/groups/(?<uuid>${UUID_REGEX})$`), async (args) => {
await import("@goauthentik/admin/groups/GroupViewPage"); await import("#admin/groups/GroupViewPage");
return html`<ak-group-view .groupId=${args.uuid}></ak-group-view>`; return html`<ak-group-view .groupId=${args.uuid}></ak-group-view>`;
}), }),
new Route(new RegExp("^/identity/users$"), async () => { new Route(new RegExp("^/identity/users$"), async () => {
await import("@goauthentik/admin/users/UserListPage"); await import("#admin/users/UserListPage");
return html`<ak-user-list></ak-user-list>`; return html`<ak-user-list></ak-user-list>`;
}), }),
new Route(new RegExp(`^/identity/users/(?<id>${ID_REGEX})$`), async (args) => { new Route(new RegExp(`^/identity/users/(?<id>${ID_REGEX})$`), async (args) => {
await import("@goauthentik/admin/users/UserViewPage"); await import("#admin/users/UserViewPage");
return html`<ak-user-view .userId=${parseInt(args.id, 10)}></ak-user-view>`; return html`<ak-user-view .userId=${parseInt(args.id, 10)}></ak-user-view>`;
}), }),
new Route(new RegExp("^/identity/roles$"), async () => { new Route(new RegExp("^/identity/roles$"), async () => {
await import("@goauthentik/admin/roles/RoleListPage"); await import("#admin/roles/RoleListPage");
return html`<ak-role-list></ak-role-list>`; return html`<ak-role-list></ak-role-list>`;
}), }),
new Route(new RegExp("^/identity/initial-permissions$"), async () => { new Route(new RegExp("^/identity/initial-permissions$"), async () => {
await import("@goauthentik/admin/rbac/InitialPermissionsListPage"); await import("#admin/rbac/InitialPermissionsListPage");
return html`<ak-initial-permissions-list></ak-initial-permissions-list>`; return html`<ak-initial-permissions-list></ak-initial-permissions-list>`;
}), }),
new Route(new RegExp(`^/identity/roles/(?<id>${UUID_REGEX})$`), async (args) => { new Route(new RegExp(`^/identity/roles/(?<id>${UUID_REGEX})$`), async (args) => {
await import("@goauthentik/admin/roles/RoleViewPage"); await import("#admin/roles/RoleViewPage");
return html`<ak-role-view roleId=${args.id}></ak-role-view>`; return html`<ak-role-view roleId=${args.id}></ak-role-view>`;
}), }),
new Route(new RegExp("^/flow/stages/invitations$"), async () => { new Route(new RegExp("^/flow/stages/invitations$"), async () => {
await import("@goauthentik/admin/stages/invitation/InvitationListPage"); await import("#admin/stages/invitation/InvitationListPage");
return html`<ak-stage-invitation-list></ak-stage-invitation-list>`; return html`<ak-stage-invitation-list></ak-stage-invitation-list>`;
}), }),
new Route(new RegExp("^/flow/stages/prompts$"), async () => { new Route(new RegExp("^/flow/stages/prompts$"), async () => {
await import("@goauthentik/admin/stages/prompt/PromptListPage"); await import("#admin/stages/prompt/PromptListPage");
return html`<ak-stage-prompt-list></ak-stage-prompt-list>`; return html`<ak-stage-prompt-list></ak-stage-prompt-list>`;
}), }),
new Route(new RegExp("^/flow/stages$"), async () => { new Route(new RegExp("^/flow/stages$"), async () => {
await import("@goauthentik/admin/stages/StageListPage"); await import("#admin/stages/StageListPage");
return html`<ak-stage-list></ak-stage-list>`; return html`<ak-stage-list></ak-stage-list>`;
}), }),
new Route(new RegExp("^/flow/flows$"), async () => { new Route(new RegExp("^/flow/flows$"), async () => {
await import("@goauthentik/admin/flows/FlowListPage"); await import("#admin/flows/FlowListPage");
return html`<ak-flow-list></ak-flow-list>`; return html`<ak-flow-list></ak-flow-list>`;
}), }),
new Route(new RegExp(`^/flow/flows/(?<slug>${SLUG_REGEX})$`), async (args) => { new Route(new RegExp(`^/flow/flows/(?<slug>${SLUG_REGEX})$`), async (args) => {
await import("@goauthentik/admin/flows/FlowViewPage"); await import("#admin/flows/FlowViewPage");
return html`<ak-flow-view .flowSlug=${args.slug}></ak-flow-view>`; return html`<ak-flow-view .flowSlug=${args.slug}></ak-flow-view>`;
}), }),
new Route(new RegExp("^/events/log$"), async () => { new Route(new RegExp("^/events/log$"), async () => {
await import("@goauthentik/admin/events/EventListPage"); await import("#admin/events/EventListPage");
return html`<ak-event-list></ak-event-list>`; return html`<ak-event-list></ak-event-list>`;
}), }),
new Route(new RegExp(`^/events/log/(?<id>${UUID_REGEX})$`), async (args) => { new Route(new RegExp(`^/events/log/(?<id>${UUID_REGEX})$`), async (args) => {
await import("@goauthentik/admin/events/EventViewPage"); await import("#admin/events/EventViewPage");
return html`<ak-event-view .eventID=${args.id}></ak-event-view>`; return html`<ak-event-view .eventID=${args.id}></ak-event-view>`;
}), }),
new Route(new RegExp("^/events/transports$"), async () => { new Route(new RegExp("^/events/transports$"), async () => {
await import("@goauthentik/admin/events/TransportListPage"); await import("#admin/events/TransportListPage");
return html`<ak-event-transport-list></ak-event-transport-list>`; return html`<ak-event-transport-list></ak-event-transport-list>`;
}), }),
new Route(new RegExp("^/events/rules$"), async () => { new Route(new RegExp("^/events/rules$"), async () => {
await import("@goauthentik/admin/events/RuleListPage"); await import("#admin/events/RuleListPage");
return html`<ak-event-rule-list></ak-event-rule-list>`; return html`<ak-event-rule-list></ak-event-rule-list>`;
}), }),
new Route(new RegExp("^/outpost/outposts$"), async () => { new Route(new RegExp("^/outpost/outposts$"), async () => {
await import("@goauthentik/admin/outposts/OutpostListPage"); await import("#admin/outposts/OutpostListPage");
return html`<ak-outpost-list></ak-outpost-list>`; return html`<ak-outpost-list></ak-outpost-list>`;
}), }),
new Route(new RegExp("^/outpost/integrations$"), async () => { new Route(new RegExp("^/outpost/integrations$"), async () => {
await import("@goauthentik/admin/outposts/ServiceConnectionListPage"); await import("#admin/outposts/ServiceConnectionListPage");
return html`<ak-outpost-service-connection-list></ak-outpost-service-connection-list>`; return html`<ak-outpost-service-connection-list></ak-outpost-service-connection-list>`;
}), }),
new Route(new RegExp("^/crypto/certificates$"), async () => { new Route(new RegExp("^/crypto/certificates$"), async () => {
await import("@goauthentik/admin/crypto/CertificateKeyPairListPage"); await import("#admin/crypto/CertificateKeyPairListPage");
return html`<ak-crypto-certificate-list></ak-crypto-certificate-list>`; return html`<ak-crypto-certificate-list></ak-crypto-certificate-list>`;
}), }),
new Route(new RegExp("^/admin/settings$"), async () => { new Route(new RegExp("^/admin/settings$"), async () => {
await import("@goauthentik/admin/admin-settings/AdminSettingsPage"); await import("#admin/admin-settings/AdminSettingsPage");
return html`<ak-admin-settings></ak-admin-settings>`; return html`<ak-admin-settings></ak-admin-settings>`;
}), }),
new Route(new RegExp("^/blueprints/instances$"), async () => { new Route(new RegExp("^/blueprints/instances$"), async () => {
await import("@goauthentik/admin/blueprints/BlueprintListPage"); await import("#admin/blueprints/BlueprintListPage");
return html`<ak-blueprint-list></ak-blueprint-list>`; return html`<ak-blueprint-list></ak-blueprint-list>`;
}), }),
new Route(new RegExp("^/debug$"), async () => { new Route(new RegExp("^/debug$"), async () => {
await import("@goauthentik/admin/DebugPage"); await import("#admin/DebugPage");
return html`<ak-admin-debug-page></ak-admin-debug-page>`; return html`<ak-admin-debug-page></ak-admin-debug-page>`;
}), }),
new Route(new RegExp("^/enterprise/licenses$"), async () => { new Route(new RegExp("^/enterprise/licenses$"), async () => {
await import("@goauthentik/admin/enterprise/EnterpriseLicenseListPage"); await import("#admin/enterprise/EnterpriseLicenseListPage");
return html`<ak-enterprise-license-list></ak-enterprise-license-list>`; return html`<ak-enterprise-license-list></ak-enterprise-license-list>`;
}), }),
]; ];

View File

@ -8,18 +8,22 @@ import "#admin/admin-overview/cards/WorkerStatusCard";
import "#admin/admin-overview/charts/AdminLoginAuthorizeChart"; import "#admin/admin-overview/charts/AdminLoginAuthorizeChart";
import "#admin/admin-overview/charts/OutpostStatusChart"; import "#admin/admin-overview/charts/OutpostStatusChart";
import "#admin/admin-overview/charts/SyncStatusChart"; import "#admin/admin-overview/charts/SyncStatusChart";
import { me } from "#common/users";
import "#components/ak-page-header"; import "#components/ak-page-header";
import { AKElement } from "#elements/Base";
import "#elements/cards/AggregatePromiseCard"; import "#elements/cards/AggregatePromiseCard";
import type { QuickAction } from "#elements/cards/QuickActionsCard";
import "#elements/cards/QuickActionsCard"; import "#elements/cards/QuickActionsCard";
import { me } from "#common/users";
import { AKElement } from "#elements/Base";
import type { QuickAction } from "#elements/cards/QuickActionsCard";
import { WithLicenseSummary } from "#elements/mixins/license"; import { WithLicenseSummary } from "#elements/mixins/license";
import { paramURL } from "#elements/router/RouterOutlet"; import { paramURL } from "#elements/router/RouterOutlet";
import { SessionUser } from "@goauthentik/api";
import { createReleaseNotesURL } from "@goauthentik/core/version"; import { createReleaseNotesURL } from "@goauthentik/core/version";
import { msg, str } from "@lit/localize"; import { msg, str } from "@lit/localize";
import { CSSResult, TemplateResult, css, html, nothing } from "lit"; import { css, CSSResult, html, nothing, TemplateResult } from "lit";
import { customElement, state } from "lit/decorators.js"; import { customElement, state } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js"; import { classMap } from "lit/directives/class-map.js";
@ -29,8 +33,6 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css"; import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { SessionUser } from "@goauthentik/api";
const AdminOverviewBase = WithLicenseSummary(AKElement); const AdminOverviewBase = WithLicenseSummary(AKElement);
@customElement("ak-admin-overview") @customElement("ak-admin-overview")

View File

@ -1,10 +1,13 @@
import "#admin/admin-overview/charts/AdminModelPerDay"; import "#admin/admin-overview/charts/AdminModelPerDay";
import "#components/ak-page-header"; import "#components/ak-page-header";
import { AKElement } from "#elements/Base";
import "#elements/cards/AggregatePromiseCard"; import "#elements/cards/AggregatePromiseCard";
import { AKElement } from "#elements/Base";
import { EventActions, EventsEventsVolumeListRequest } from "@goauthentik/api";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, css, html } from "lit"; import { css, CSSResult, html, TemplateResult } from "lit";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import PFContent from "@patternfly/patternfly/components/Content/content.css"; import PFContent from "@patternfly/patternfly/components/Content/content.css";
@ -13,8 +16,6 @@ import PFList from "@patternfly/patternfly/components/List/list.css";
import PFPage from "@patternfly/patternfly/components/Page/page.css"; import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css"; import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import { EventActions, EventsEventsVolumeListRequest } from "@goauthentik/api";
@customElement("ak-admin-dashboard-users") @customElement("ak-admin-dashboard-users")
export class DashboardUserPage extends AKElement { export class DashboardUserPage extends AKElement {
static get styles(): CSSResult[] { static get styles(): CSSResult[] {

View File

@ -1,15 +1,17 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import "#elements/Spinner";
import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/Spinner"; import { DEFAULT_CONFIG } from "#common/api/config";
import { AKElement } from "#elements/Base";
import { EventsApi, EventTopPerUser } from "@goauthentik/api";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, html } from "lit"; import { CSSResult, html, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import PFTable from "@patternfly/patternfly/components/Table/table.css"; import PFTable from "@patternfly/patternfly/components/Table/table.css";
import { EventTopPerUser, EventsApi } from "@goauthentik/api";
@customElement("ak-top-applications-table") @customElement("ak-top-applications-table")
export class TopApplicationsTable extends AKElement { export class TopApplicationsTable extends AKElement {
@property({ attribute: false }) @property({ attribute: false })

View File

@ -1,14 +1,11 @@
import { EVENT_REFRESH } from "@goauthentik/common/constants"; import { EVENT_REFRESH } from "#common/constants";
import { PFSize } from "@goauthentik/common/enums.js"; import { PFSize } from "#common/enums";
import { import { APIError, parseAPIResponseError, pluckErrorDetail } from "#common/errors/network";
APIError,
parseAPIResponseError, import { AggregateCard } from "#elements/cards/AggregateCard";
pluckErrorDetail,
} from "@goauthentik/common/errors/network";
import { AggregateCard } from "@goauthentik/elements/cards/AggregateCard";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { PropertyValues, TemplateResult, html, nothing } from "lit"; import { html, nothing, PropertyValues, TemplateResult } from "lit";
import { state } from "lit/decorators.js"; import { state } from "lit/decorators.js";
export interface AdminStatus { export interface AdminStatus {

View File

@ -1,15 +1,13 @@
import { import { DEFAULT_CONFIG } from "#common/api/config";
AdminStatus,
AdminStatusCard,
} from "@goauthentik/admin/admin-overview/cards/AdminStatusCard";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { msg } from "@lit/localize"; import { AdminStatus, AdminStatusCard } from "#admin/admin-overview/cards/AdminStatusCard";
import { TemplateResult, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { AdminApi, SystemInfo } from "@goauthentik/api"; import { AdminApi, SystemInfo } from "@goauthentik/api";
import { msg } from "@lit/localize";
import { html, TemplateResult } from "lit";
import { customElement, state } from "lit/decorators.js";
type StatusContent = { icon: string; message: TemplateResult }; type StatusContent = { icon: string; message: TemplateResult };
@customElement("ak-admin-fips-status-system") @customElement("ak-admin-fips-status-system")

View File

@ -1,25 +1,27 @@
import { EventGeo, renderEventUser } from "@goauthentik/admin/events/utils"; import "#components/ak-event-info";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import "#elements/Tabs";
import { EventWithContext } from "@goauthentik/common/events"; import "#elements/buttons/Dropdown";
import { actionToLabel } from "@goauthentik/common/labels"; import "#elements/buttons/ModalButton";
import { formatElapsedTime } from "@goauthentik/common/temporal"; import "#elements/buttons/SpinnerButton/index";
import "@goauthentik/components/ak-event-info";
import "@goauthentik/elements/Tabs"; import { DEFAULT_CONFIG } from "#common/api/config";
import "@goauthentik/elements/buttons/Dropdown"; import { EventWithContext } from "#common/events";
import "@goauthentik/elements/buttons/ModalButton"; import { actionToLabel } from "#common/labels";
import "@goauthentik/elements/buttons/SpinnerButton"; import { formatElapsedTime } from "#common/temporal";
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
import { Table, TableColumn } from "@goauthentik/elements/table/Table"; import { PaginatedResponse, Table, TableColumn } from "#elements/table/Table";
import { SlottedTemplateResult } from "@goauthentik/elements/types"; import { SlottedTemplateResult } from "#elements/types";
import { EventGeo, renderEventUser } from "#admin/events/utils";
import { Event, EventsApi } from "@goauthentik/api";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, css, html } from "lit"; import { css, CSSResult, html, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import PFCard from "@patternfly/patternfly/components/Card/card.css"; import PFCard from "@patternfly/patternfly/components/Card/card.css";
import { Event, EventsApi } from "@goauthentik/api";
@customElement("ak-recent-events") @customElement("ak-recent-events")
export class RecentEventsCard extends Table<Event> { export class RecentEventsCard extends Table<Event> {
@property() @property()

View File

@ -1,15 +1,13 @@
import { import { DEFAULT_CONFIG } from "#common/api/config";
AdminStatus,
AdminStatusCard,
} from "@goauthentik/admin/admin-overview/cards/AdminStatusCard";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { msg } from "@lit/localize"; import { AdminStatus, AdminStatusCard } from "#admin/admin-overview/cards/AdminStatusCard";
import { TemplateResult, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { AdminApi, OutpostsApi, SystemInfo } from "@goauthentik/api"; import { AdminApi, OutpostsApi, SystemInfo } from "@goauthentik/api";
import { msg } from "@lit/localize";
import { html, TemplateResult } from "lit";
import { customElement, state } from "lit/decorators.js";
@customElement("ak-admin-status-system") @customElement("ak-admin-status-system")
export class SystemStatusCard extends AdminStatusCard<SystemInfo> { export class SystemStatusCard extends AdminStatusCard<SystemInfo> {
now?: Date; now?: Date;

View File

@ -1,15 +1,13 @@
import { import { DEFAULT_CONFIG } from "#common/api/config";
AdminStatus,
AdminStatusCard,
} from "@goauthentik/admin/admin-overview/cards/AdminStatusCard";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { msg, str } from "@lit/localize"; import { AdminStatus, AdminStatusCard } from "#admin/admin-overview/cards/AdminStatusCard";
import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js";
import { AdminApi, Version } from "@goauthentik/api"; import { AdminApi, Version } from "@goauthentik/api";
import { msg, str } from "@lit/localize";
import { html, TemplateResult } from "lit";
import { customElement } from "lit/decorators.js";
@customElement("ak-admin-status-version") @customElement("ak-admin-status-version")
export class VersionStatusCard extends AdminStatusCard<Version> { export class VersionStatusCard extends AdminStatusCard<Version> {
icon = "pf-icon pf-icon-bundle"; icon = "pf-icon pf-icon-bundle";

View File

@ -1,15 +1,13 @@
import { import { DEFAULT_CONFIG } from "#common/api/config";
AdminStatus,
AdminStatusCard,
} from "@goauthentik/admin/admin-overview/cards/AdminStatusCard";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { msg } from "@lit/localize"; import { AdminStatus, AdminStatusCard } from "#admin/admin-overview/cards/AdminStatusCard";
import { TemplateResult, html } from "lit";
import { customElement } from "lit/decorators.js";
import { AdminApi, Worker } from "@goauthentik/api"; import { AdminApi, Worker } from "@goauthentik/api";
import { msg } from "@lit/localize";
import { html, TemplateResult } from "lit";
import { customElement } from "lit/decorators.js";
@customElement("ak-admin-status-card-workers") @customElement("ak-admin-status-card-workers")
export class WorkersStatusCard extends AdminStatusCard<Worker[]> { export class WorkersStatusCard extends AdminStatusCard<Worker[]> {
icon = "pf-icon pf-icon-server"; icon = "pf-icon pf-icon-server";

View File

@ -1,12 +1,14 @@
import { DEFAULT_CONFIG } from "#common/api/config";
import { EventChart } from "#elements/charts/EventChart"; import { EventChart } from "#elements/charts/EventChart";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EventActions, EventsApi, EventVolume } from "@goauthentik/api";
import { ChartData, ChartDataset } from "chart.js"; import { ChartData, ChartDataset } from "chart.js";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import { EventActions, EventVolume, EventsApi } from "@goauthentik/api";
@customElement("ak-charts-admin-login-authorization") @customElement("ak-charts-admin-login-authorization")
export class AdminLoginAuthorizeChart extends EventChart { export class AdminLoginAuthorizeChart extends EventChart {
async apiRequest(): Promise<EventVolume[]> { async apiRequest(): Promise<EventVolume[]> {

View File

@ -1,17 +1,19 @@
import { DEFAULT_CONFIG } from "#common/api/config";
import { EventChart } from "#elements/charts/EventChart"; import { EventChart } from "#elements/charts/EventChart";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import {
EventActions,
EventsApi,
EventsEventsVolumeListRequest,
EventVolume,
} from "@goauthentik/api";
import { ChartData } from "chart.js"; import { ChartData } from "chart.js";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import {
EventActions,
EventVolume,
EventsApi,
EventsEventsVolumeListRequest,
} from "@goauthentik/api";
@customElement("ak-charts-admin-model-per-day") @customElement("ak-charts-admin-model-per-day")
export class AdminModelPerDay extends EventChart { export class AdminModelPerDay extends EventChart {
@property() @property()

View File

@ -1,15 +1,19 @@
import "#elements/forms/ConfirmationForm";
import { DEFAULT_CONFIG } from "#common/api/config";
import { AKChart } from "#elements/charts/Chart";
import { actionToColor } from "#elements/charts/EventChart"; import { actionToColor } from "#elements/charts/EventChart";
import { SummarizedSyncStatus } from "@goauthentik/admin/admin-overview/charts/SyncStatusChart";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import { SummarizedSyncStatus } from "#admin/admin-overview/charts/SyncStatusChart";
import { AKChart } from "@goauthentik/elements/charts/Chart";
import "@goauthentik/elements/forms/ConfirmationForm"; import { EventActions, OutpostsApi } from "@goauthentik/api";
import { ChartData, ChartOptions } from "chart.js"; import { ChartData, ChartOptions } from "chart.js";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { customElement } from "lit/decorators.js"; import { customElement } from "lit/decorators.js";
import { EventActions, OutpostsApi } from "@goauthentik/api";
@customElement("ak-admin-status-chart-outpost") @customElement("ak-admin-status-chart-outpost")
export class OutpostStatusChart extends AKChart<SummarizedSyncStatus[]> { export class OutpostStatusChart extends AKChart<SummarizedSyncStatus[]> {
getChartType(): string { getChartType(): string {

View File

@ -1,12 +1,10 @@
import { actionToColor } from "#elements/charts/EventChart"; import "#elements/forms/ConfirmationForm";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { AKChart } from "@goauthentik/elements/charts/Chart";
import "@goauthentik/elements/forms/ConfirmationForm";
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
import { ChartData, ChartOptions } from "chart.js";
import { msg } from "@lit/localize"; import { DEFAULT_CONFIG } from "#common/api/config";
import { customElement } from "lit/decorators.js";
import { AKChart } from "#elements/charts/Chart";
import { actionToColor } from "#elements/charts/EventChart";
import { PaginatedResponse } from "#elements/table/Table";
import { import {
EventActions, EventActions,
@ -16,6 +14,11 @@ import {
SystemTaskStatusEnum, SystemTaskStatusEnum,
} from "@goauthentik/api"; } from "@goauthentik/api";
import { ChartData, ChartOptions } from "chart.js";
import { msg } from "@lit/localize";
import { customElement } from "lit/decorators.js";
export interface SummarizedSyncStatus { export interface SummarizedSyncStatus {
healthy: number; healthy: number;
failed: number; failed: number;

View File

@ -1,5 +1,8 @@
import { AkControlElement } from "@goauthentik/elements/AkControlElement.js"; import { AkControlElement } from "#elements/AkControlElement";
import { type Spread } from "@goauthentik/elements/types"; import { type Spread } from "#elements/types";
import { FooterLink } from "@goauthentik/api";
import { spread } from "@open-wc/lit-helpers"; import { spread } from "@open-wc/lit-helpers";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
@ -11,8 +14,6 @@ import PFFormControl from "@patternfly/patternfly/components/FormControl/form-co
import PFInputGroup from "@patternfly/patternfly/components/InputGroup/input-group.css"; import PFInputGroup from "@patternfly/patternfly/components/InputGroup/input-group.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { FooterLink } from "@goauthentik/api";
export interface IFooterLinkInput { export interface IFooterLinkInput {
footerLink: FooterLink; footerLink: FooterLink;
} }

View File

@ -1,26 +1,28 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import "#components/ak-number-input";
import "@goauthentik/components/ak-number-input"; import "#components/ak-switch-input";
import "@goauthentik/components/ak-switch-input"; import "#components/ak-text-input";
import "@goauthentik/components/ak-text-input"; import "#elements/ak-array-input";
import "@goauthentik/elements/ak-array-input.js"; import "#elements/forms/FormGroup";
import { Form } from "@goauthentik/elements/forms/Form"; import "#elements/forms/HorizontalFormElement";
import "@goauthentik/elements/forms/FormGroup"; import "#elements/forms/Radio";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "#elements/forms/SearchSelect/index";
import "@goauthentik/elements/forms/Radio"; import "#elements/utils/TimeDeltaHelp";
import "@goauthentik/elements/forms/SearchSelect"; import "./AdminSettingsFooterLinks.js";
import "@goauthentik/elements/utils/TimeDeltaHelp";
import { DEFAULT_CONFIG } from "#common/api/config";
import { Form } from "#elements/forms/Form";
import { AdminApi, FooterLink, Settings, SettingsRequest } from "@goauthentik/api";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, css, html } from "lit"; import { css, CSSResult, html, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js"; import { ifDefined } from "lit/directives/if-defined.js";
import PFList from "@patternfly/patternfly/components/List/list.css"; import PFList from "@patternfly/patternfly/components/List/list.css";
import { AdminApi, FooterLink, Settings, SettingsRequest } from "@goauthentik/api"; import { akFooterLinkInput, IFooterLinkInput } from "./AdminSettingsFooterLinks.js";
import "./AdminSettingsFooterLinks.js";
import { IFooterLinkInput, akFooterLinkInput } from "./AdminSettingsFooterLinks.js";
const DEFAULT_REPUTATION_LOWER_LIMIT = -5; const DEFAULT_REPUTATION_LOWER_LIMIT = -5;
const DEFAULT_REPUTATION_UPPER_LIMIT = 5; const DEFAULT_REPUTATION_UPPER_LIMIT = 5;

View File

@ -1,9 +1,6 @@
import "#admin/admin-settings/AdminSettingsForm"; import "#admin/admin-settings/AdminSettingsForm";
import { AdminSettingsForm } from "#admin/admin-settings/AdminSettingsForm";
import { DEFAULT_CONFIG } from "#common/api/config";
import "#components/ak-page-header"; import "#components/ak-page-header";
import "#components/events/ObjectChangelog"; import "#components/events/ObjectChangelog";
import { AKElement } from "#elements/Base";
import "#elements/CodeMirror"; import "#elements/CodeMirror";
import "#elements/EmptyState"; import "#elements/EmptyState";
import "#elements/Tabs"; import "#elements/Tabs";
@ -11,6 +8,14 @@ import "#elements/buttons/ModalButton";
import "#elements/buttons/SpinnerButton/ak-spinner-button"; import "#elements/buttons/SpinnerButton/ak-spinner-button";
import "#elements/forms/ModalForm"; import "#elements/forms/ModalForm";
import { DEFAULT_CONFIG } from "#common/api/config";
import { AKElement } from "#elements/Base";
import { AdminSettingsForm } from "#admin/admin-settings/AdminSettingsForm";
import { AdminApi, Settings } from "@goauthentik/api";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { html, nothing } from "lit"; import { html, nothing } from "lit";
import { customElement, query, state } from "lit/decorators.js"; import { customElement, query, state } from "lit/decorators.js";
@ -26,8 +31,6 @@ import PFPage from "@patternfly/patternfly/components/Page/page.css";
import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css"; import PFGrid from "@patternfly/patternfly/layouts/Grid/grid.css";
import PFBase from "@patternfly/patternfly/patternfly-base.css"; import PFBase from "@patternfly/patternfly/patternfly-base.css";
import { AdminApi, Settings } from "@goauthentik/api";
@customElement("ak-admin-settings") @customElement("ak-admin-settings")
export class AdminSettingsPage extends AKElement { export class AdminSettingsPage extends AKElement {
static get styles() { static get styles() {

View File

@ -1,11 +1,12 @@
import "@goauthentik/elements/messages/MessageContainer"; import "#elements/messages/MessageContainer";
import "../AdminSettingsFooterLinks.js";
import { Meta, StoryObj, WebComponentsRenderer } from "@storybook/web-components"; import { Meta, StoryObj, WebComponentsRenderer } from "@storybook/web-components";
import { DecoratorFunction } from "storybook/internal/types"; import { DecoratorFunction } from "storybook/internal/types";
import { html } from "lit"; import { html } from "lit";
import { FooterLinkInput } from "../AdminSettingsFooterLinks.js"; import { FooterLinkInput } from "../AdminSettingsFooterLinks.js";
import "../AdminSettingsFooterLinks.js";
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
type Decorator = DecoratorFunction<WebComponentsRenderer, any>; type Decorator = DecoratorFunction<WebComponentsRenderer, any>;

View File

@ -1,10 +1,11 @@
import { render } from "@goauthentik/elements/tests/utils.js"; import "../AdminSettingsFooterLinks.js";
import { render } from "#elements/tests/utils";
import { $, expect } from "@wdio/globals"; import { $, expect } from "@wdio/globals";
import { html } from "lit"; import { html } from "lit";
import "../AdminSettingsFooterLinks.js";
describe("ak-admin-settings-footer-link", () => { describe("ak-admin-settings-footer-link", () => {
afterEach(async () => { afterEach(async () => {
await browser.execute(async () => { await browser.execute(async () => {

View File

@ -1,12 +1,14 @@
import { DEFAULT_CONFIG } from "#common/api/config";
import { EventChart } from "#elements/charts/EventChart"; import { EventChart } from "#elements/charts/EventChart";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EventActions, EventsApi, EventVolume } from "@goauthentik/api";
import { ChartData } from "chart.js"; import { ChartData } from "chart.js";
import { msg } from "@lit/localize"; import { msg } from "@lit/localize";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import { EventActions, EventVolume, EventsApi } from "@goauthentik/api";
@customElement("ak-charts-application-authorize") @customElement("ak-charts-application-authorize")
export class ApplicationAuthorizeChart extends EventChart { export class ApplicationAuthorizeChart extends EventChart {
@property({ attribute: "application-id" }) @property({ attribute: "application-id" })

View File

@ -1,15 +1,11 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import "#components/ak-status-label";
import "@goauthentik/components/ak-status-label"; import "#elements/events/LogViewer";
import "@goauthentik/elements/events/LogViewer"; import "#elements/forms/HorizontalFormElement";
import { Form } from "@goauthentik/elements/forms/Form"; import "#elements/forms/SearchSelect/index";
import "@goauthentik/elements/forms/HorizontalFormElement";
import "@goauthentik/elements/forms/SearchSelect";
import { msg } from "@lit/localize"; import { DEFAULT_CONFIG } from "#common/api/config";
import { CSSResult, TemplateResult, html } from "lit";
import { customElement, property } from "lit/decorators.js";
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css"; import { Form } from "#elements/forms/Form";
import { import {
Application, Application,
@ -19,6 +15,12 @@ import {
User, User,
} from "@goauthentik/api"; } from "@goauthentik/api";
import { msg } from "@lit/localize";
import { CSSResult, html, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
import PFDescriptionList from "@patternfly/patternfly/components/DescriptionList/description-list.css";
@customElement("ak-application-check-access-form") @customElement("ak-application-check-access-form")
export class ApplicationCheckAccessForm extends Form<{ forUser: number }> { export class ApplicationCheckAccessForm extends Form<{ forUser: number }> {
@property({ attribute: false }) @property({ attribute: false })

View File

@ -1,33 +1,35 @@
import { CapabilitiesEnum, WithCapabilitiesConfig } from "#elements/mixins/capabilities"; import "#admin/applications/ProviderSelectModal";
import "@goauthentik/admin/applications/ProviderSelectModal"; import "#components/ak-file-input";
import { iconHelperText } from "@goauthentik/admin/helperText"; import "#components/ak-radio-input";
import { policyEngineModes } from "@goauthentik/admin/policies/PolicyEngineModes"; import "#components/ak-slug-input";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config"; import "#components/ak-switch-input";
import "@goauthentik/components/ak-file-input"; import "#components/ak-text-input";
import "@goauthentik/components/ak-radio-input"; import "#components/ak-textarea-input";
import "@goauthentik/components/ak-slug-input"; import "#elements/Alert";
import "@goauthentik/components/ak-switch-input"; import "#elements/forms/FormGroup";
import "@goauthentik/components/ak-text-input"; import "#elements/forms/HorizontalFormElement";
import "@goauthentik/components/ak-textarea-input"; import "#elements/forms/ModalForm";
import "@goauthentik/elements/Alert"; import "#elements/forms/ProxyForm";
import "@goauthentik/elements/forms/FormGroup"; import "#elements/forms/Radio";
import "@goauthentik/elements/forms/HorizontalFormElement"; import "#elements/forms/SearchSelect/ak-search-select";
import "@goauthentik/elements/forms/ModalForm";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
import "@goauthentik/elements/forms/ProxyForm";
import "@goauthentik/elements/forms/Radio";
import "@goauthentik/elements/forms/SearchSelect/ak-search-select";
import "@patternfly/elements/pf-tooltip/pf-tooltip.js"; import "@patternfly/elements/pf-tooltip/pf-tooltip.js";
import "./components/ak-backchannel-input.js";
import "./components/ak-provider-search-input.js";
import { msg } from "@lit/localize"; import { DEFAULT_CONFIG } from "#common/api/config";
import { TemplateResult, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators.js"; import { ModelForm } from "#elements/forms/ModelForm";
import { ifDefined } from "lit/directives/if-defined.js"; import { CapabilitiesEnum, WithCapabilitiesConfig } from "#elements/mixins/capabilities";
import { iconHelperText } from "#admin/helperText";
import { policyEngineModes } from "#admin/policies/PolicyEngineModes";
import { Application, CoreApi, Provider } from "@goauthentik/api"; import { Application, CoreApi, Provider } from "@goauthentik/api";
import "./components/ak-backchannel-input"; import { msg } from "@lit/localize";
import "./components/ak-provider-search-input"; import { html, nothing, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
@customElement("ak-application-form") @customElement("ak-application-form")
export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Application, string>) { export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Application, string>) {

Some files were not shown because too many files have changed in this diff Show More