Compare commits
9 Commits
enterprise
...
import-org
| Author | SHA1 | Date | |
|---|---|---|---|
| 0b96a98183 | |||
| d948345096 | |||
| ecfd1b077d | |||
| 3e67e358ce | |||
| c1032386c6 | |||
| 55cb7f3f2c | |||
| 0c4e5bfc22 | |||
| 69e5b1dfbe | |||
| ccc2a5bdfe |
@ -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*))?
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
1
.github/workflows/ci-main-daily.yml
vendored
1
.github/workflows/ci-main-daily.yml
vendored
@ -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
|
||||||
|
|||||||
4
.github/workflows/ci-main.yml
vendored
4
.github/workflows/ci-main.yml
vendored
@ -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:
|
||||||
|
|||||||
1
.github/workflows/ci-outpost.yml
vendored
1
.github/workflows/ci-outpost.yml
vendored
@ -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
|
||||||
|
|||||||
2
.github/workflows/ci-website.yml
vendored
2
.github/workflows/ci-website.yml
vendored
@ -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' || '[]' }}
|
|
||||||
|
|||||||
21
.github/workflows/repo-mirror-cleanup.yml
vendored
21
.github/workflows/repo-mirror-cleanup.yml
vendored
@ -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 }}
|
|
||||||
9
.github/workflows/repo-mirror.yml
vendored
9
.github/workflows/repo-mirror.yml
vendored
@ -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 }}
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|
||||||
|
|||||||
@ -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"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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))
|
||||||
|
|||||||
@ -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,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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")
|
||||||
|
|||||||
@ -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"]
|
|
||||||
@ -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": "",
|
|
||||||
}
|
|
||||||
@ -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",
|
|
||||||
)
|
|
||||||
@ -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",),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -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"
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -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",
|
|
||||||
),
|
|
||||||
]
|
|
||||||
@ -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()
|
|
||||||
@ -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"),
|
|
||||||
]
|
|
||||||
@ -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"),
|
|
||||||
]
|
|
||||||
@ -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,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@ -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,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@ -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",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
@ -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"],
|
|
||||||
)
|
|
||||||
@ -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",
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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()
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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"))
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -27,6 +27,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<td>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block sub_content %}
|
{% block sub_content %}
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
@ -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
2
go.mod
@ -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
4
go.sum
@ -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=
|
||||||
|
|||||||
@ -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"
|
||||||
|
|||||||
@ -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.
@ -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.
@ -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.
@ -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
4
package-lock.json
generated
@ -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",
|
||||||
|
|||||||
@ -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": {
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
172
packages/prettier-config/lib/imports.js
Normal file
172
packages/prettier-config/lib/imports.js
Normal 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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
1832
packages/prettier-config/package-lock.json
generated
1832
packages/prettier-config/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -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"
|
||||||
|
|||||||
@ -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",
|
||||||
|
|||||||
18
schema.yml
18
schema.yml
@ -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'
|
||||||
|
|||||||
@ -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
18
uv.lock
generated
@ -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]
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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";
|
||||||
|
|
||||||
|
|||||||
@ -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`.
|
||||||
*
|
*
|
||||||
|
|||||||
@ -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
46
web/package-lock.json
generated
@ -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",
|
||||||
|
|||||||
@ -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": {
|
||||||
|
|||||||
@ -7,6 +7,4 @@
|
|||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export {};
|
|
||||||
|
|
||||||
export default {};
|
export default {};
|
||||||
|
|||||||
@ -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" };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -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]";
|
||||||
|
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -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[] {
|
||||||
|
|||||||
@ -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>`;
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|||||||
@ -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")
|
||||||
|
|||||||
@ -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[] {
|
||||||
|
|||||||
@ -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 })
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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")
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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";
|
||||||
|
|||||||
@ -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[]> {
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
|
|||||||
@ -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() {
|
||||||
|
|||||||
@ -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>;
|
||||||
|
|||||||
@ -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 () => {
|
||||||
|
|||||||
@ -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" })
|
||||||
|
|||||||
@ -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 })
|
||||||
|
|||||||
@ -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
Reference in New Issue
Block a user