Compare commits
49 Commits
version/20
...
version/20
Author | SHA1 | Date | |
---|---|---|---|
430a207865 | |||
894873b373 | |||
1ce2a1b846 | |||
4731ccfafe | |||
3e9c28d0a4 | |||
12d4394d73 | |||
b872e7072d | |||
b0ea657b18 | |||
a5f26b2ce0 | |||
c1b9b5c5e2 | |||
b288393cd4 | |||
767ffc09d0 | |||
446dc0a17b | |||
c85474ec37 | |||
3a59b75f4a | |||
8deac81364 | |||
98485c528e | |||
1a5b626f96 | |||
5736a1542c | |||
43854dc828 | |||
64af78110a | |||
59be3c7746 | |||
9e30f01fce | |||
fc8fe5317a | |||
92090ced9f | |||
ce47d4cf39 | |||
c11367553e | |||
c61529e4d4 | |||
8709f3300c | |||
e78bc1b32f | |||
89c4a7b4a4 | |||
9701907b82 | |||
7ac73bfcf9 | |||
1423d5d45b | |||
768ff67e8c | |||
b13deefd91 | |||
69e445211e | |||
ada8fc2a55 | |||
d9cc45f9ce | |||
515a402db7 | |||
813f70b806 | |||
a302a72379 | |||
e390f5b2d1 | |||
f09305a444 | |||
60189ce9ca | |||
fdc445e6a1 | |||
e3f8afcf80 | |||
9e2e8132a6 | |||
26f9bbeefa |
@ -1,5 +1,5 @@
|
||||
[bumpversion]
|
||||
current_version = 2023.1.0
|
||||
current_version = 2023.1.1
|
||||
tag = True
|
||||
commit = True
|
||||
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)
|
||||
|
@ -38,6 +38,14 @@ runs:
|
||||
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
|
||||
```
|
||||
|
||||
For arm64, use these values:
|
||||
|
||||
```shell
|
||||
AUTHENTIK_IMAGE=ghcr.io/goauthentik/dev-server
|
||||
AUTHENTIK_TAG=${{ inputs.tag }}-arm64
|
||||
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
|
||||
```
|
||||
|
||||
Afterwards, run the upgrade commands from the latest release notes.
|
||||
</details>
|
||||
<details>
|
||||
@ -54,6 +62,17 @@ runs:
|
||||
tag: ${{ inputs.tag }}
|
||||
```
|
||||
|
||||
For arm64, use these values:
|
||||
|
||||
```yaml
|
||||
authentik:
|
||||
outposts:
|
||||
container_image_base: ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
|
||||
image:
|
||||
repository: ghcr.io/goauthentik/dev-server
|
||||
tag: ${{ inputs.tag }}-arm64
|
||||
```
|
||||
|
||||
Afterwards, run the upgrade commands from the latest release notes.
|
||||
</details>
|
||||
edit-mode: replace
|
||||
|
@ -17,6 +17,9 @@ outputs:
|
||||
sha:
|
||||
description: "sha"
|
||||
value: ${{ steps.ev.outputs.sha }}
|
||||
shortHash:
|
||||
description: "shortHash"
|
||||
value: ${{ steps.ev.outputs.shortHash }}
|
||||
version:
|
||||
description: "version"
|
||||
value: ${{ steps.ev.outputs.version }}
|
||||
@ -53,6 +56,7 @@ runs:
|
||||
print("branchNameContainer=%s" % safe_branch_name, file=_output)
|
||||
print("timestamp=%s" % int(time()), file=_output)
|
||||
print("sha=%s" % os.environ["GITHUB_SHA"], file=_output)
|
||||
print("shortHash=%s" % os.environ["GITHUB_SHA"][:7], file=_output)
|
||||
print("shouldBuild=%s" % should_build, file=_output)
|
||||
print("version=%s" % version, file=_output)
|
||||
print("versionFamily=%s" % version_family, file=_output)
|
||||
|
53
.github/workflows/ci-main.yml
vendored
53
.github/workflows/ci-main.yml
vendored
@ -118,13 +118,13 @@ jobs:
|
||||
- name: proxy
|
||||
glob: tests/e2e/test_provider_proxy*
|
||||
- name: oauth
|
||||
glob: tests/e2e/test_provider_oauth2_!(oidc) tests/e2e/test_source_oauth*
|
||||
glob: tests/e2e/test_provider_oauth2* tests/e2e/test_source_oauth*
|
||||
- name: oauth-oidc
|
||||
glob: tests/e2e/test_provider_oauth2_oidc*
|
||||
glob: tests/e2e/test_provider_oidc*
|
||||
- name: saml
|
||||
glob: tests/e2e/test_provider_saml* tests/e2e/test_source_saml*
|
||||
- name: ldap
|
||||
glob: tests/e2e/test_provider_ldap*
|
||||
glob: tests/e2e/test_provider_ldap* tests/e2e/test_source_ldap*
|
||||
- name: flows
|
||||
glob: tests/e2e/test_flows*
|
||||
steps:
|
||||
@ -148,7 +148,6 @@ jobs:
|
||||
npm run build
|
||||
- name: run e2e
|
||||
run: |
|
||||
shopt -s extglob
|
||||
poetry run coverage run manage.py test ${{ matrix.job.glob }}
|
||||
poetry run coverage xml
|
||||
- if: ${{ always() }}
|
||||
@ -170,11 +169,6 @@ jobs:
|
||||
needs: ci-core-mark
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 120
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
arch:
|
||||
- 'linux/amd64'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up QEMU
|
||||
@ -202,14 +196,49 @@ jobs:
|
||||
push: ${{ steps.ev.outputs.shouldBuild == 'true' }}
|
||||
tags: |
|
||||
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}
|
||||
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.sha }}
|
||||
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.shortHash }}
|
||||
build-args: |
|
||||
GIT_BUILD_HASH=${{ steps.ev.outputs.sha }}
|
||||
VERSION_FAMILY=${{ steps.ev.outputs.versionFamily }}
|
||||
platforms: ${{ matrix.arch }}
|
||||
- name: Comment on PR
|
||||
if: github.event_name == 'pull_request'
|
||||
continue-on-error: true
|
||||
uses: ./.github/actions/comment-pr-instructions
|
||||
with:
|
||||
tag: gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.sha }}
|
||||
tag: gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.shortHash }}
|
||||
build-arm64:
|
||||
needs: ci-core-mark
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 120
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2.1.0
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
- name: prepare variables
|
||||
uses: ./.github/actions/docker-push-variables
|
||||
id: ev
|
||||
env:
|
||||
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
|
||||
- name: Login to Container Registry
|
||||
uses: docker/login-action@v2
|
||||
if: ${{ steps.ev.outputs.shouldBuild == 'true' }}
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Build Docker Image
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
secrets: |
|
||||
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
|
||||
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
|
||||
push: ${{ steps.ev.outputs.shouldBuild == 'true' }}
|
||||
tags: |
|
||||
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}-arm64
|
||||
ghcr.io/goauthentik/dev-server:gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}-${{ steps.ev.outputs.shortHash }}-arm64
|
||||
build-args: |
|
||||
GIT_BUILD_HASH=${{ steps.ev.outputs.sha }}
|
||||
VERSION_FAMILY=${{ steps.ev.outputs.versionFamily }}
|
||||
platforms: linux/arm64
|
||||
|
3
.github/workflows/ci-outpost.yml
vendored
3
.github/workflows/ci-outpost.yml
vendored
@ -28,6 +28,8 @@ jobs:
|
||||
run: make gen-client-go
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v3
|
||||
with:
|
||||
args: --timeout 5000s
|
||||
test-unittest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@ -86,7 +88,6 @@ jobs:
|
||||
push: ${{ steps.ev.outputs.shouldBuild == 'true' }}
|
||||
tags: |
|
||||
ghcr.io/goauthentik/dev-${{ matrix.type }}:gh-${{ steps.ev.outputs.branchNameContainer }}
|
||||
ghcr.io/goauthentik/dev-${{ matrix.type }}:gh-${{ steps.ev.outputs.branchNameContainer }}-${{ steps.ev.outputs.timestamp }}
|
||||
ghcr.io/goauthentik/dev-${{ matrix.type }}:gh-${{ steps.ev.outputs.sha }}
|
||||
file: ${{ matrix.type }}.Dockerfile
|
||||
build-args: |
|
||||
|
5
.github/workflows/release-publish.yml
vendored
5
.github/workflows/release-publish.yml
vendored
@ -31,7 +31,7 @@ jobs:
|
||||
uses: docker/build-push-action@v3
|
||||
with:
|
||||
push: ${{ github.event_name == 'release' }}
|
||||
secrets:
|
||||
secrets: |
|
||||
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
|
||||
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
|
||||
tags: |
|
||||
@ -88,9 +88,6 @@ jobs:
|
||||
ghcr.io/goauthentik/${{ matrix.type }}:latest
|
||||
file: ${{ matrix.type }}.Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
secrets: |
|
||||
GEOIPUPDATE_ACCOUNT_ID=${{ secrets.GEOIPUPDATE_ACCOUNT_ID }}
|
||||
GEOIPUPDATE_LICENSE_KEY=${{ secrets.GEOIPUPDATE_LICENSE_KEY }}
|
||||
build-args: |
|
||||
VERSION_FAMILY=${{ steps.ev.outputs.versionFamily }}
|
||||
build-outpost-binary:
|
||||
|
4
.github/workflows/release-tag.yml
vendored
4
.github/workflows/release-tag.yml
vendored
@ -26,14 +26,14 @@ jobs:
|
||||
id: get_version
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github-token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
script: |
|
||||
return context.payload.ref.replace(/\/refs\/tags\/version\//, '');
|
||||
- name: Create Release
|
||||
id: create_release
|
||||
uses: actions/create-release@v1.1.4
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: Release ${{ steps.get_version.outputs.result }}
|
||||
|
4
.github/workflows/translation-compile.yml
vendored
4
.github/workflows/translation-compile.yml
vendored
@ -19,6 +19,8 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
- name: Setup authentik env
|
||||
uses: ./.github/actions/setup
|
||||
- name: run compile
|
||||
@ -27,7 +29,7 @@ jobs:
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
id: cpr
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.BOT_GITHUB_TOKEN }}
|
||||
branch: compile-backend-translation
|
||||
commit-message: "core: compile backend translations"
|
||||
title: "core: compile backend translations"
|
||||
|
@ -6,8 +6,8 @@ Authentik takes security very seriously. We follow the rules of [responsible dis
|
||||
|
||||
| Version | Supported |
|
||||
| --------- | ------------------ |
|
||||
| 2022.11.x | :white_check_mark: |
|
||||
| 2022.12.x | :white_check_mark: |
|
||||
| 2023.1.x | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
from os import environ
|
||||
from typing import Optional
|
||||
|
||||
__version__ = "2023.1.0"
|
||||
__version__ = "2023.1.1"
|
||||
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"
|
||||
|
||||
|
||||
|
@ -235,9 +235,11 @@ class CertificateKeyPairViewSet(UsedByMixin, ModelViewSet):
|
||||
data = CertificateGenerationSerializer(data=request.data)
|
||||
if not data.is_valid():
|
||||
return Response(data.errors, status=400)
|
||||
raw_san = data.validated_data.get("subject_alt_name", "")
|
||||
sans = raw_san.split(",") if raw_san != "" else []
|
||||
builder = CertificateBuilder(data.validated_data["common_name"])
|
||||
builder.build(
|
||||
subject_alt_names=data.validated_data.get("subject_alt_name", "").split(","),
|
||||
subject_alt_names=sans,
|
||||
validity_days=int(data.validated_data["validity_days"]),
|
||||
)
|
||||
instance = builder.save()
|
||||
|
@ -57,7 +57,10 @@ class CertificateBuilder:
|
||||
one_day = datetime.timedelta(1, 0, 0)
|
||||
self.__private_key = self.generate_private_key()
|
||||
self.__public_key = self.__private_key.public_key()
|
||||
alt_names: list[x509.GeneralName] = [x509.DNSName(x) for x in subject_alt_names or []]
|
||||
alt_names: list[x509.GeneralName] = []
|
||||
for alt_name in subject_alt_names or []:
|
||||
if alt_name.strip() != "":
|
||||
alt_names.append(x509.DNSName(alt_name))
|
||||
self.__builder = (
|
||||
x509.CertificateBuilder()
|
||||
.subject_name(
|
||||
@ -76,12 +79,15 @@ class CertificateBuilder:
|
||||
]
|
||||
)
|
||||
)
|
||||
.add_extension(x509.SubjectAlternativeName(alt_names), critical=True)
|
||||
.not_valid_before(datetime.datetime.today() - one_day)
|
||||
.not_valid_after(datetime.datetime.today() + datetime.timedelta(days=validity_days))
|
||||
.serial_number(int(uuid.uuid4()))
|
||||
.public_key(self.__public_key)
|
||||
)
|
||||
if alt_names:
|
||||
self.__builder = self.__builder.add_extension(
|
||||
x509.SubjectAlternativeName(alt_names), critical=True
|
||||
)
|
||||
self.__certificate = self.__builder.sign(
|
||||
private_key=self.__private_key,
|
||||
algorithm=hashes.SHA256(),
|
||||
|
@ -4,6 +4,8 @@ from json import loads
|
||||
from os import makedirs
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
from cryptography.x509.extensions import SubjectAlternativeName
|
||||
from cryptography.x509.general_name import DNSName
|
||||
from django.urls import reverse
|
||||
from rest_framework.test import APITestCase
|
||||
|
||||
@ -70,11 +72,43 @@ class TestCrypto(APITestCase):
|
||||
def test_builder_api(self):
|
||||
"""Test Builder (via API)"""
|
||||
self.client.force_login(create_test_admin_user())
|
||||
name = generate_id()
|
||||
self.client.post(
|
||||
reverse("authentik_api:certificatekeypair-generate"),
|
||||
data={"common_name": "foo", "subject_alt_name": "bar,baz", "validity_days": 3},
|
||||
data={"common_name": name, "subject_alt_name": "bar,baz", "validity_days": 3},
|
||||
)
|
||||
self.assertTrue(CertificateKeyPair.objects.filter(name="foo").exists())
|
||||
key = CertificateKeyPair.objects.filter(name=name).first()
|
||||
self.assertIsNotNone(key)
|
||||
ext: SubjectAlternativeName = key.certificate.extensions[0].value
|
||||
self.assertIsInstance(ext, SubjectAlternativeName)
|
||||
self.assertIsInstance(ext[0], DNSName)
|
||||
self.assertEqual(ext[0].value, "bar")
|
||||
self.assertIsInstance(ext[1], DNSName)
|
||||
self.assertEqual(ext[1].value, "baz")
|
||||
|
||||
def test_builder_api_empty_san(self):
|
||||
"""Test Builder (via API)"""
|
||||
self.client.force_login(create_test_admin_user())
|
||||
name = generate_id()
|
||||
self.client.post(
|
||||
reverse("authentik_api:certificatekeypair-generate"),
|
||||
data={"common_name": name, "subject_alt_name": "", "validity_days": 3},
|
||||
)
|
||||
key = CertificateKeyPair.objects.filter(name=name).first()
|
||||
self.assertIsNotNone(key)
|
||||
self.assertEqual(len(key.certificate.extensions), 0)
|
||||
|
||||
def test_builder_api_empty_san_multiple(self):
|
||||
"""Test Builder (via API)"""
|
||||
self.client.force_login(create_test_admin_user())
|
||||
name = generate_id()
|
||||
self.client.post(
|
||||
reverse("authentik_api:certificatekeypair-generate"),
|
||||
data={"common_name": name, "subject_alt_name": ", ", "validity_days": 3},
|
||||
)
|
||||
key = CertificateKeyPair.objects.filter(name=name).first()
|
||||
self.assertIsNotNone(key)
|
||||
self.assertEqual(len(key.certificate.extensions), 0)
|
||||
|
||||
def test_builder_api_invalid(self):
|
||||
"""Test Builder (via API) (invalid)"""
|
||||
|
@ -448,7 +448,7 @@ class NotificationTransport(SerializerModel):
|
||||
# pyright: reportGeneralTypeIssues=false
|
||||
return send_mail(mail.__dict__) # pylint: disable=no-value-for-parameter
|
||||
except (SMTPException, ConnectionError, OSError) as exc:
|
||||
raise NotificationTransportError from exc
|
||||
raise NotificationTransportError(exc) from exc
|
||||
|
||||
@property
|
||||
def serializer(self) -> "Serializer":
|
||||
|
@ -1,14 +1,42 @@
|
||||
"""JWKS tests"""
|
||||
import base64
|
||||
import json
|
||||
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
from cryptography.x509 import load_der_x509_certificate
|
||||
from django.urls.base import reverse
|
||||
from jwt import PyJWKSet
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.core.tests.utils import create_test_cert, create_test_flow
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.providers.oauth2.models import OAuth2Provider
|
||||
from authentik.providers.oauth2.tests.utils import OAuthTestCase
|
||||
|
||||
TEST_CORDS_CERT = """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIB6jCCAZCgAwIBAgIRAOsdE3N7zETzs+7shTXGj5wwCgYIKoZIzj0EAwIwHjEc
|
||||
MBoGA1UEAwwTYXV0aGVudGlrIDIwMjIuMTIuMjAeFw0yMzAxMTYyMjU2MjVaFw0y
|
||||
NDAxMTIyMjU2MjVaMHgxTDBKBgNVBAMMQ0NsbDR2TzFJSGxvdFFhTGwwMHpES2tM
|
||||
WENYdzRPUFF2eEtZN1NrczAuc2VsZi1zaWduZWQuZ29hdXRoZW50aWsuaW8xEjAQ
|
||||
BgNVBAoMCWF1dGhlbnRpazEUMBIGA1UECwwLU2VsZi1zaWduZWQwWTATBgcqhkjO
|
||||
PQIBBggqhkjOPQMBBwNCAAQAwOGam7AKOi5LKmb9lK1rAzA2JTppqrFiIaUdjqmH
|
||||
ZICJP00Wt0dfqOtEjgMEv1Hhu1DmKZn2ehvpxwPSzBr5o1UwUzBRBgNVHREBAf8E
|
||||
RzBFgkNCNkw4YlI0UldJRU42NUZLamdUTzV1YmRvNUZWdkpNS2lxdjFZeTRULnNl
|
||||
bGYtc2lnbmVkLmdvYXV0aGVudGlrLmlvMAoGCCqGSM49BAMCA0gAMEUCIC/JAfnl
|
||||
uC30ihqepbiMCaTaPMbL8Ka2Lk92IYfMhf46AiEAz9Kmv6HF2D4MK54iwhz2WqvF
|
||||
8vo+OiGdTQ1Qoj7fgYU=
|
||||
-----END CERTIFICATE-----
|
||||
"""
|
||||
TEST_CORDS_KEY = """
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
MHcCAQEEIKy6mPLJc5v71InMMvYaxyXI3xXpwQTPLyAYWVFnZHVioAoGCCqGSM49
|
||||
AwEHoUQDQgAEAMDhmpuwCjouSypm/ZStawMwNiU6aaqxYiGlHY6ph2SAiT9NFrdH
|
||||
X6jrRI4DBL9R4btQ5imZ9nob6ccD0swa+Q==
|
||||
-----END EC PRIVATE KEY-----
|
||||
"""
|
||||
|
||||
|
||||
class TestJWKS(OAuthTestCase):
|
||||
"""Test JWKS view"""
|
||||
@ -29,6 +57,8 @@ class TestJWKS(OAuthTestCase):
|
||||
body = json.loads(response.content.decode())
|
||||
self.assertEqual(len(body["keys"]), 1)
|
||||
PyJWKSet.from_dict(body)
|
||||
key = body["keys"][0]
|
||||
load_der_x509_certificate(base64.b64decode(key["x5c"][0]), default_backend()).public_key()
|
||||
|
||||
def test_hs256(self):
|
||||
"""Test JWKS request with HS256"""
|
||||
@ -60,3 +90,25 @@ class TestJWKS(OAuthTestCase):
|
||||
body = json.loads(response.content.decode())
|
||||
self.assertEqual(len(body["keys"]), 1)
|
||||
PyJWKSet.from_dict(body)
|
||||
|
||||
def test_ecdsa_coords_mismatched(self):
|
||||
"""Test JWKS request with ES256"""
|
||||
cert = CertificateKeyPair.objects.create(
|
||||
name=generate_id(),
|
||||
key_data=TEST_CORDS_KEY,
|
||||
certificate_data=TEST_CORDS_CERT,
|
||||
)
|
||||
provider = OAuth2Provider.objects.create(
|
||||
name="test",
|
||||
client_id="test",
|
||||
authorization_flow=create_test_flow(),
|
||||
redirect_uris="http://local.invalid",
|
||||
signing_key=cert,
|
||||
)
|
||||
app = Application.objects.create(name="test", slug="test", provider=provider)
|
||||
response = self.client.get(
|
||||
reverse("authentik_providers_oauth2:jwks", kwargs={"application_slug": app.slug})
|
||||
)
|
||||
body = json.loads(response.content.decode())
|
||||
self.assertEqual(len(body["keys"]), 1)
|
||||
PyJWKSet.from_dict(body)
|
||||
|
@ -15,27 +15,49 @@ from cryptography.hazmat.primitives.serialization import Encoding
|
||||
from django.http import HttpRequest, HttpResponse, JsonResponse
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.views import View
|
||||
from jwt.utils import base64url_encode
|
||||
|
||||
from authentik.core.models import Application
|
||||
from authentik.crypto.models import CertificateKeyPair
|
||||
from authentik.providers.oauth2.models import JWTAlgorithms, OAuth2Provider
|
||||
|
||||
|
||||
def b64_enc(number: int) -> str:
|
||||
"""Convert number to base64-encoded octet-value"""
|
||||
length = ((number).bit_length() + 7) // 8
|
||||
number_bytes = number.to_bytes(length, "big")
|
||||
final = urlsafe_b64encode(number_bytes).rstrip(b"=")
|
||||
return final.decode("ascii")
|
||||
|
||||
|
||||
# See https://notes.salrahman.com/generate-es256-es384-es512-private-keys/
|
||||
# and _CURVE_TYPES in the same file as the below curve files
|
||||
ec_crv_map = {
|
||||
SECP256R1: "P-256",
|
||||
SECP384R1: "P-384",
|
||||
SECP521R1: "P-512",
|
||||
SECP521R1: "P-521",
|
||||
}
|
||||
min_length_map = {
|
||||
SECP256R1: 32,
|
||||
SECP384R1: 48,
|
||||
SECP521R1: 66,
|
||||
}
|
||||
|
||||
# https://github.com/jpadilla/pyjwt/issues/709
|
||||
def bytes_from_int(val: int, min_length: int = 0) -> bytes:
|
||||
"""Custom bytes_from_int that accepts a minimum length"""
|
||||
remaining = val
|
||||
byte_length = 0
|
||||
|
||||
while remaining != 0:
|
||||
remaining >>= 8
|
||||
byte_length += 1
|
||||
length = max([byte_length, min_length])
|
||||
return val.to_bytes(length, "big", signed=False)
|
||||
|
||||
|
||||
def to_base64url_uint(val: int, min_length: int = 0) -> bytes:
|
||||
"""Custom to_base64url_uint that accepts a minimum length"""
|
||||
if val < 0:
|
||||
raise ValueError("Must be a positive integer")
|
||||
|
||||
int_bytes = bytes_from_int(val, min_length)
|
||||
|
||||
if len(int_bytes) == 0:
|
||||
int_bytes = b"\x00"
|
||||
|
||||
return base64url_encode(int_bytes)
|
||||
|
||||
|
||||
class JWKSView(View):
|
||||
@ -51,24 +73,25 @@ class JWKSView(View):
|
||||
public_key: RSAPublicKey = private_key.public_key()
|
||||
public_numbers = public_key.public_numbers()
|
||||
key_data = {
|
||||
"kid": key.kid,
|
||||
"kty": "RSA",
|
||||
"alg": JWTAlgorithms.RS256,
|
||||
"use": "sig",
|
||||
"kid": key.kid,
|
||||
"n": b64_enc(public_numbers.n),
|
||||
"e": b64_enc(public_numbers.e),
|
||||
"n": to_base64url_uint(public_numbers.n).decode(),
|
||||
"e": to_base64url_uint(public_numbers.e).decode(),
|
||||
}
|
||||
elif isinstance(private_key, EllipticCurvePrivateKey):
|
||||
public_key: EllipticCurvePublicKey = private_key.public_key()
|
||||
public_numbers = public_key.public_numbers()
|
||||
curve_type = type(public_key.curve)
|
||||
key_data = {
|
||||
"kid": key.kid,
|
||||
"kty": "EC",
|
||||
"alg": JWTAlgorithms.ES256,
|
||||
"use": "sig",
|
||||
"kid": key.kid,
|
||||
"x": b64_enc(public_numbers.x),
|
||||
"y": b64_enc(public_numbers.y),
|
||||
"crv": ec_crv_map.get(type(public_key.curve), public_key.curve.name),
|
||||
"x": to_base64url_uint(public_numbers.x, min_length_map[curve_type]).decode(),
|
||||
"y": to_base64url_uint(public_numbers.y, min_length_map[curve_type]).decode(),
|
||||
"crv": ec_crv_map.get(curve_type, public_key.curve.name),
|
||||
}
|
||||
else:
|
||||
return key_data
|
||||
|
@ -38,7 +38,6 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer):
|
||||
try:
|
||||
defaults = self.build_group_properties(group_dn, **attributes)
|
||||
defaults["parent"] = self._source.sync_parent_group
|
||||
self._logger.debug("Creating group with attributes", **defaults)
|
||||
if "name" not in defaults:
|
||||
raise IntegrityError("Name was not set by propertymappings")
|
||||
# Special check for `users` field, as this is an M2M relation, and cannot be sync'd
|
||||
@ -51,6 +50,7 @@ class GroupLDAPSynchronizer(BaseLDAPSynchronizer):
|
||||
},
|
||||
defaults,
|
||||
)
|
||||
self._logger.debug("Created group with attributes", **defaults)
|
||||
except (IntegrityError, FieldError, TypeError, AttributeError) as exc:
|
||||
Event.new(
|
||||
EventAction.CONFIGURATION_ERROR,
|
||||
|
@ -33,11 +33,10 @@ class LDAPSyncTests(TestCase):
|
||||
"""Test Cached auth"""
|
||||
self.source.property_mappings.set(
|
||||
LDAPPropertyMapping.objects.filter(
|
||||
Q(name__startswith="authentik default LDAP Mapping")
|
||||
| Q(name__startswith="authentik default Active Directory Mapping")
|
||||
Q(managed__startswith="goauthentik.io/sources/ldap/default-")
|
||||
| Q(managed__startswith="goauthentik.io/sources/ldap/ms-")
|
||||
)
|
||||
)
|
||||
self.source.save()
|
||||
connection = PropertyMock(return_value=mock_ad_connection(LDAP_PASSWORD))
|
||||
with patch("authentik.sources.ldap.models.LDAPSource.connection", connection):
|
||||
user_sync = UserLDAPSynchronizer(self.source)
|
||||
|
@ -1,5 +1,5 @@
|
||||
"""Duo stage"""
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.http import HttpResponse
|
||||
from django.utils.timezone import now
|
||||
from rest_framework.fields import CharField
|
||||
|
||||
@ -10,7 +10,6 @@ from authentik.flows.challenge import (
|
||||
ChallengeTypes,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.flows.views.executor import InvalidStageError
|
||||
from authentik.stages.authenticator_duo.models import AuthenticatorDuoStage, DuoDevice
|
||||
@ -68,13 +67,6 @@ class AuthenticatorDuoStageView(ChallengeStageView):
|
||||
}
|
||||
)
|
||||
|
||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||
user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)
|
||||
if not user:
|
||||
self.logger.debug("No pending user, continuing")
|
||||
return self.executor.stage_ok()
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
|
||||
# Duo Challenge has already been validated
|
||||
stage: AuthenticatorDuoStage = self.executor.current_stage
|
||||
|
@ -76,13 +76,17 @@ class AuthenticatorSMSStage(ConfigurableStage, Stage):
|
||||
return self.send_generic(token, device)
|
||||
raise ValueError(f"invalid provider {self.provider}")
|
||||
|
||||
def get_message(self, token: str) -> str:
|
||||
"""Get SMS message"""
|
||||
return _("Use this code to authenticate in authentik: %(token)s" % {"token": token})
|
||||
|
||||
def send_twilio(self, token: str, device: "SMSDevice"):
|
||||
"""send sms via twilio provider"""
|
||||
client = Client(self.account_sid, self.auth)
|
||||
|
||||
try:
|
||||
message = client.messages.create(
|
||||
to=device.phone_number, from_=self.from_number, body=token
|
||||
to=device.phone_number, from_=self.from_number, body=self.get_message(token)
|
||||
)
|
||||
LOGGER.debug("Sent SMS", to=device, message=message.sid)
|
||||
except TwilioRestException as exc:
|
||||
@ -95,6 +99,7 @@ class AuthenticatorSMSStage(ConfigurableStage, Stage):
|
||||
"From": self.from_number,
|
||||
"To": device.phone_number,
|
||||
"Body": token,
|
||||
"Message": self.get_message(token),
|
||||
}
|
||||
|
||||
if self.mapping:
|
||||
|
@ -12,9 +12,9 @@ from authentik.flows.challenge import (
|
||||
Challenge,
|
||||
ChallengeResponse,
|
||||
ChallengeTypes,
|
||||
ErrorDetailSerializer,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.stages.authenticator_sms.models import (
|
||||
AuthenticatorSMSStage,
|
||||
@ -47,15 +47,9 @@ class AuthenticatorSMSChallengeResponse(ChallengeResponse):
|
||||
|
||||
def validate(self, attrs: dict) -> dict:
|
||||
"""Check"""
|
||||
stage: AuthenticatorSMSStage = self.device.stage
|
||||
if "code" not in attrs:
|
||||
self.device.phone_number = attrs["phone_number"]
|
||||
hashed_number = hash_phone_number(self.device.phone_number)
|
||||
query = Q(phone_number=hashed_number) | Q(phone_number=self.device.phone_number)
|
||||
if SMSDevice.objects.filter(query, stage=self.stage.executor.current_stage.pk).exists():
|
||||
raise ValidationError(_("Invalid phone number"))
|
||||
# No code yet, but we have a phone number, so send a verification message
|
||||
stage.send(self.device.token, self.device)
|
||||
self.stage.validate_and_send(attrs["phone_number"])
|
||||
return super().validate(attrs)
|
||||
if not self.device.verify_token(str(attrs["code"])):
|
||||
raise ValidationError(_("Code does not match"))
|
||||
@ -68,6 +62,17 @@ class AuthenticatorSMSStageView(ChallengeStageView):
|
||||
|
||||
response_class = AuthenticatorSMSChallengeResponse
|
||||
|
||||
def validate_and_send(self, phone_number: str):
|
||||
"""Validate phone number and send message"""
|
||||
stage: AuthenticatorSMSStage = self.executor.current_stage
|
||||
hashed_number = hash_phone_number(phone_number)
|
||||
query = Q(phone_number=hashed_number) | Q(phone_number=phone_number)
|
||||
if SMSDevice.objects.filter(query, stage=stage.pk).exists():
|
||||
raise ValidationError(_("Invalid phone number"))
|
||||
# No code yet, but we have a phone number, so send a verification message
|
||||
device: SMSDevice = self.request.session[SESSION_KEY_SMS_DEVICE]
|
||||
stage.send(device.token, device)
|
||||
|
||||
def _has_phone_number(self) -> Optional[str]:
|
||||
context = self.executor.plan.context
|
||||
if "phone" in context.get(PLAN_CONTEXT_PROMPT, {}):
|
||||
@ -95,24 +100,23 @@ class AuthenticatorSMSStageView(ChallengeStageView):
|
||||
return response
|
||||
|
||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||
user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)
|
||||
if not user:
|
||||
self.logger.debug("No pending user, continuing")
|
||||
return self.executor.stage_ok()
|
||||
|
||||
# Currently, this stage only supports one device per user. If the user already
|
||||
# has a device, just skip to the next stage
|
||||
if SMSDevice.objects.filter(user=user).exists():
|
||||
return self.executor.stage_ok()
|
||||
user = self.get_pending_user()
|
||||
|
||||
stage: AuthenticatorSMSStage = self.executor.current_stage
|
||||
|
||||
if SESSION_KEY_SMS_DEVICE not in self.request.session:
|
||||
device = SMSDevice(user=user, confirmed=False, stage=stage, name="SMS Device")
|
||||
device.generate_token(commit=False)
|
||||
self.request.session[SESSION_KEY_SMS_DEVICE] = device
|
||||
if phone_number := self._has_phone_number():
|
||||
device.phone_number = phone_number
|
||||
self.request.session[SESSION_KEY_SMS_DEVICE] = device
|
||||
try:
|
||||
self.validate_and_send(phone_number)
|
||||
except ValidationError as exc:
|
||||
response = AuthenticatorSMSChallengeResponse()
|
||||
response._errors.setdefault("phone_number", [])
|
||||
response._errors["phone_number"].append(ErrorDetailSerializer(exc.detail))
|
||||
return self.challenge_invalid(response)
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def challenge_valid(self, response: ChallengeResponse) -> HttpResponse:
|
||||
|
@ -80,6 +80,39 @@ class AuthenticatorSMSStageTests(FlowTestCase):
|
||||
phone_number_required=False,
|
||||
)
|
||||
|
||||
def test_stage_context_data(self):
|
||||
"""test stage context data"""
|
||||
self.client.get(
|
||||
reverse("authentik_flows:configure", kwargs={"stage_uuid": self.stage.stage_uuid}),
|
||||
)
|
||||
sms_send_mock = MagicMock()
|
||||
with (
|
||||
patch(
|
||||
(
|
||||
"authentik.stages.authenticator_sms.stage."
|
||||
"AuthenticatorSMSStageView._has_phone_number"
|
||||
),
|
||||
MagicMock(
|
||||
return_value="1234",
|
||||
),
|
||||
),
|
||||
patch(
|
||||
"authentik.stages.authenticator_sms.models.AuthenticatorSMSStage.send",
|
||||
sms_send_mock,
|
||||
),
|
||||
):
|
||||
response = self.client.get(
|
||||
reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug}),
|
||||
)
|
||||
sms_send_mock.assert_called_once()
|
||||
self.assertStageResponse(
|
||||
response,
|
||||
self.flow,
|
||||
self.user,
|
||||
component="ak-stage-authenticator-sms",
|
||||
phone_number_required=False,
|
||||
)
|
||||
|
||||
def test_stage_submit_full(self):
|
||||
"""test stage (submit)"""
|
||||
self.client.get(
|
||||
|
@ -1,7 +1,8 @@
|
||||
"""TOTP Setup stage"""
|
||||
from urllib.parse import quote
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.http.request import QueryDict
|
||||
from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_otp.plugins.otp_totp.models import TOTPDevice
|
||||
from rest_framework.fields import CharField, IntegerField
|
||||
@ -56,7 +57,7 @@ class AuthenticatorTOTPStageView(ChallengeStageView):
|
||||
data={
|
||||
"type": ChallengeTypes.NATIVE.value,
|
||||
"config_url": device.config_url.replace(
|
||||
OTP_TOTP_ISSUER, slugify(self.request.tenant.branding_title)
|
||||
OTP_TOTP_ISSUER, quote(self.request.tenant.branding_title)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
@ -376,7 +376,7 @@ class AuthenticatorValidateStageView(ChallengeStageView):
|
||||
|
||||
def challenge_valid(self, response: AuthenticatorValidationChallengeResponse) -> HttpResponse:
|
||||
# All validation is done by the serializer
|
||||
user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)
|
||||
user = self.get_pending_user()
|
||||
if not user:
|
||||
if "webauthn" not in response.data:
|
||||
return self.executor.stage_invalid()
|
||||
|
@ -26,7 +26,6 @@ from authentik.flows.challenge import (
|
||||
ChallengeTypes,
|
||||
WithUserInfoChallenge,
|
||||
)
|
||||
from authentik.flows.planner import PLAN_CONTEXT_PENDING_USER
|
||||
from authentik.flows.stage import ChallengeStageView
|
||||
from authentik.stages.authenticator_webauthn.models import AuthenticateWebAuthnStage, WebAuthnDevice
|
||||
from authentik.stages.authenticator_webauthn.utils import get_origin, get_rp_id
|
||||
@ -113,13 +112,6 @@ class AuthenticatorWebAuthnStageView(ChallengeStageView):
|
||||
}
|
||||
)
|
||||
|
||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse:
|
||||
user = self.executor.plan.context.get(PLAN_CONTEXT_PENDING_USER)
|
||||
if not user:
|
||||
self.logger.debug("No pending user, continuing")
|
||||
return self.executor.stage_ok()
|
||||
return super().get(request, *args, **kwargs)
|
||||
|
||||
def get_response_instance(self, data: QueryDict) -> AuthenticatorWebAuthnChallengeResponse:
|
||||
response: AuthenticatorWebAuthnChallengeResponse = super().get_response_instance(data)
|
||||
response.request = self.request
|
||||
|
@ -17,7 +17,7 @@
|
||||
<tr>
|
||||
<td class="content-block">
|
||||
{% blocktrans %}
|
||||
You recently requested to change your password for you authentik account. Use the button below to set a new password.
|
||||
You recently requested to change your password for your authentik account. Use the button below to set a new password.
|
||||
{% endblocktrans %}
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -62,9 +62,7 @@ class TestEmailStage(FlowTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
self.assertEqual(mail.outbox[0].subject, "authentik")
|
||||
self.assertNotIn(
|
||||
"You recently requested to change your password", mail.outbox[0].alternatives[0][0]
|
||||
)
|
||||
self.assertNotIn("Password Reset", mail.outbox[0].alternatives[0][0])
|
||||
|
||||
def test_without_user(self):
|
||||
"""Test without pending user"""
|
||||
|
@ -2,6 +2,7 @@
|
||||
from typing import Optional
|
||||
|
||||
from deepmerge import always_merger
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
@ -41,7 +42,11 @@ class InvitationStageView(StageView):
|
||||
token = self.get_token()
|
||||
if not token:
|
||||
return None
|
||||
invite: Invitation = Invitation.objects.filter(pk=token).first()
|
||||
try:
|
||||
invite: Invitation = Invitation.objects.filter(pk=token).first()
|
||||
except ValidationError:
|
||||
self.logger.debug("invalid invitation", token=token)
|
||||
return None
|
||||
if not invite:
|
||||
self.logger.debug("invalid invitation", token=token)
|
||||
return None
|
||||
|
@ -33,7 +33,7 @@ entries:
|
||||
type: email
|
||||
id: prompt-field-email
|
||||
identifiers:
|
||||
field_key: email
|
||||
field_key: admin_email
|
||||
label: Email
|
||||
model: authentik_stages_prompt.prompt
|
||||
- attrs:
|
||||
@ -66,6 +66,8 @@ entries:
|
||||
# by injecting "pending_user"
|
||||
akadmin = ak_user_by(username="akadmin")
|
||||
context["flow_plan"].context["pending_user"] = akadmin
|
||||
# Remap the email value
|
||||
context["prompt_data"]["email"] = context["prompt_data"]["admin_email"]
|
||||
return True
|
||||
id: policy-default-oobe-prefill-user
|
||||
identifiers:
|
||||
|
@ -32,7 +32,7 @@ services:
|
||||
volumes:
|
||||
- redis:/data
|
||||
server:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.0}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.1}
|
||||
restart: unless-stopped
|
||||
command: server
|
||||
environment:
|
||||
@ -47,10 +47,10 @@ services:
|
||||
env_file:
|
||||
- .env
|
||||
ports:
|
||||
- "0.0.0.0:${AUTHENTIK_PORT_HTTP:-9000}:9000"
|
||||
- "0.0.0.0:${AUTHENTIK_PORT_HTTPS:-9443}:9443"
|
||||
- "${AUTHENTIK_PORT_HTTP:-9000}:9000"
|
||||
- "${AUTHENTIK_PORT_HTTPS:-9443}:9443"
|
||||
worker:
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.0}
|
||||
image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2023.1.1}
|
||||
restart: unless-stopped
|
||||
command: worker
|
||||
environment:
|
||||
|
2
go.mod
2
go.mod
@ -25,7 +25,7 @@ require (
|
||||
github.com/quasoft/memstore v0.0.0-20191010062613-2bce066d2b0b
|
||||
github.com/sirupsen/logrus v1.9.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
goauthentik.io/api/v3 v3.2022122.8
|
||||
goauthentik.io/api/v3 v3.2023010.1
|
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b
|
||||
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f
|
||||
gopkg.in/boj/redistore.v1 v1.0.0-20160128113310-fc113767cd6b
|
||||
|
4
go.sum
4
go.sum
@ -382,8 +382,8 @@ go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZp
|
||||
go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ=
|
||||
go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk=
|
||||
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
|
||||
goauthentik.io/api/v3 v3.2022122.8 h1:6yJ7w1K7/h79IJC9VDUV0pb12oSQnIOcghzCCPz3sEU=
|
||||
goauthentik.io/api/v3 v3.2022122.8/go.mod h1:QM9J32HgYE4gL71lWAfAoXSPdSmLVLW08itfLI3Mo10=
|
||||
goauthentik.io/api/v3 v3.2023010.1 h1:DQuf201pD+OKVnzpLKCaKw8IS397ewzMzFIGXyhmQ3w=
|
||||
goauthentik.io/api/v3 v3.2023010.1/go.mod h1:QM9J32HgYE4gL71lWAfAoXSPdSmLVLW08itfLI3Mo10=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE=
|
||||
|
@ -29,4 +29,4 @@ func UserAgent() string {
|
||||
return fmt.Sprintf("authentik@%s", FullVersion())
|
||||
}
|
||||
|
||||
const VERSION = "2023.1.0"
|
||||
const VERSION = "2023.1.1"
|
||||
|
@ -95,7 +95,12 @@ func IncludeObjectClass(searchOC string, ocs map[string]bool) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
return ocs[searchOC]
|
||||
for key, value := range ocs {
|
||||
if strings.EqualFold(key, searchOC) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func GetContainerEntry(filterOC string, dn string, ou string) *ldap.Entry {
|
||||
|
@ -70,19 +70,28 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore
|
||||
ks = oidc.NewRemoteKeySet(ctx, p.OidcConfiguration.JwksUri)
|
||||
}
|
||||
|
||||
var verifier = oidc.NewVerifier(p.OidcConfiguration.Issuer, ks, &oidc.Config{
|
||||
ClientID: *p.ClientId,
|
||||
SupportedSigningAlgs: []string{"RS256", "HS256"},
|
||||
})
|
||||
|
||||
redirectUri, _ := url.Parse(p.ExternalHost)
|
||||
redirectUri.Path = path.Join(redirectUri.Path, "/outpost.goauthentik.io/callback")
|
||||
redirectUri.RawQuery = url.Values{
|
||||
CallbackSignature: []string{"true"},
|
||||
}.Encode()
|
||||
|
||||
managed := false
|
||||
if m := ak.Outpost.Managed.Get(); m != nil {
|
||||
managed = *m == "goauthentik.io/outposts/embedded"
|
||||
}
|
||||
// Configure an OpenID Connect aware OAuth2 client.
|
||||
endpoint := GetOIDCEndpoint(p, ak.Outpost.Config["authentik_host"].(string))
|
||||
endpoint := GetOIDCEndpoint(
|
||||
p,
|
||||
ak.Outpost.Config["authentik_host"].(string),
|
||||
managed,
|
||||
)
|
||||
|
||||
verifier := oidc.NewVerifier(endpoint.Issuer, ks, &oidc.Config{
|
||||
ClientID: *p.ClientId,
|
||||
SupportedSigningAlgs: []string{"RS256", "HS256"},
|
||||
})
|
||||
|
||||
oauth2Config := oauth2.Config{
|
||||
ClientID: *p.ClientId,
|
||||
ClientSecret: *p.ClientSecret,
|
||||
|
@ -15,11 +15,23 @@ type OIDCEndpoint struct {
|
||||
TokenIntrospection string
|
||||
EndSessionEndpoint string
|
||||
JwksUri string
|
||||
Issuer string
|
||||
}
|
||||
|
||||
func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoint {
|
||||
func updateURL(rawUrl string, scheme string, host string) string {
|
||||
u, err := url.Parse(rawUrl)
|
||||
if err != nil {
|
||||
return rawUrl
|
||||
}
|
||||
u.Host = host
|
||||
u.Scheme = scheme
|
||||
return u.String()
|
||||
}
|
||||
|
||||
func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string, embedded bool) OIDCEndpoint {
|
||||
authUrl := p.OidcConfiguration.AuthorizationEndpoint
|
||||
endUrl := p.OidcConfiguration.EndSessionEndpoint
|
||||
tokenUrl := p.OidcConfiguration.TokenEndpoint
|
||||
jwksUrl := p.OidcConfiguration.JwksUri
|
||||
if browserHost, found := os.LookupEnv("AUTHENTIK_HOST_BROWSER"); found && browserHost != "" {
|
||||
host := os.Getenv("AUTHENTIK_HOST")
|
||||
@ -30,26 +42,15 @@ func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoin
|
||||
ep := OIDCEndpoint{
|
||||
Endpoint: oauth2.Endpoint{
|
||||
AuthURL: authUrl,
|
||||
TokenURL: p.OidcConfiguration.TokenEndpoint,
|
||||
TokenURL: tokenUrl,
|
||||
AuthStyle: oauth2.AuthStyleInParams,
|
||||
},
|
||||
EndSessionEndpoint: endUrl,
|
||||
JwksUri: jwksUrl,
|
||||
TokenIntrospection: p.OidcConfiguration.IntrospectionEndpoint,
|
||||
Issuer: p.OidcConfiguration.Issuer,
|
||||
}
|
||||
authU, err := url.Parse(authUrl)
|
||||
if err != nil {
|
||||
return ep
|
||||
}
|
||||
endU, err := url.Parse(endUrl)
|
||||
if err != nil {
|
||||
return ep
|
||||
}
|
||||
jwksU, err := url.Parse(jwksUrl)
|
||||
if err != nil {
|
||||
return ep
|
||||
}
|
||||
if authU.Host != "localhost:8000" {
|
||||
if !embedded {
|
||||
return ep
|
||||
}
|
||||
if authentikHost == "" {
|
||||
@ -60,14 +61,10 @@ func GetOIDCEndpoint(p api.ProxyOutpostConfig, authentikHost string) OIDCEndpoin
|
||||
if err != nil {
|
||||
return ep
|
||||
}
|
||||
authU.Host = aku.Host
|
||||
authU.Scheme = aku.Scheme
|
||||
endU.Host = aku.Host
|
||||
endU.Scheme = aku.Scheme
|
||||
jwksU.Host = aku.Host
|
||||
jwksU.Scheme = aku.Scheme
|
||||
ep.AuthURL = authU.String()
|
||||
ep.EndSessionEndpoint = endU.String()
|
||||
ep.JwksUri = jwksU.String()
|
||||
ep.AuthURL = updateURL(authUrl, aku.Scheme, aku.Host)
|
||||
ep.EndSessionEndpoint = updateURL(endUrl, aku.Scheme, aku.Host)
|
||||
ep.JwksUri = updateURL(jwksUrl, aku.Scheme, aku.Host)
|
||||
ep.TokenURL = updateURL(tokenUrl, aku.Scheme, aku.Host)
|
||||
ep.Issuer = updateURL(ep.Issuer, aku.Scheme, aku.Host)
|
||||
return ep
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2023-01-13 14:37+0000\n"
|
||||
"POT-Creation-Date: 2023-01-23 09:41+0000\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
@ -18,7 +18,7 @@ msgstr ""
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: authentik/admin/api/tasks.py:126
|
||||
#: authentik/admin/api/tasks.py:124
|
||||
#, python-format
|
||||
msgid "Successfully re-scheduled Task %(name)s!"
|
||||
msgstr ""
|
||||
@ -177,26 +177,26 @@ msgstr ""
|
||||
msgid "Authenticated Sessions"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/sources/flow_manager.py:198
|
||||
#: authentik/core/sources/flow_manager.py:197
|
||||
msgid "source"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/sources/flow_manager.py:250
|
||||
#: authentik/core/sources/flow_manager.py:248
|
||||
msgid "Configured flow does not exist."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/sources/flow_manager.py:281
|
||||
#: authentik/core/sources/flow_manager.py:333
|
||||
#: authentik/core/sources/flow_manager.py:278
|
||||
#: authentik/core/sources/flow_manager.py:330
|
||||
#, python-format
|
||||
msgid "Successfully authenticated with %(source)s!"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/sources/flow_manager.py:305
|
||||
#: authentik/core/sources/flow_manager.py:302
|
||||
#, python-format
|
||||
msgid "Successfully linked %(source)s!"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/sources/flow_manager.py:324
|
||||
#: authentik/core/sources/flow_manager.py:321
|
||||
msgid "Source is not configured for enrollment."
|
||||
msgstr ""
|
||||
|
||||
@ -255,9 +255,9 @@ msgid "Powered by authentik"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/core/views/apps.py:48
|
||||
#: authentik/providers/oauth2/views/authorize.py:358
|
||||
#: authentik/providers/oauth2/views/authorize.py:357
|
||||
#: authentik/providers/oauth2/views/device_init.py:68
|
||||
#: authentik/providers/saml/views/sso.py:69
|
||||
#: authentik/providers/saml/views/sso.py:68
|
||||
#, python-format
|
||||
msgid "You're about to sign into %(application)s."
|
||||
msgstr ""
|
||||
@ -284,89 +284,89 @@ msgstr ""
|
||||
msgid "Certificate-Key Pairs"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:288
|
||||
#: authentik/events/models.py:287
|
||||
msgid "Event"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:289
|
||||
#: authentik/events/models.py:288
|
||||
msgid "Events"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:295
|
||||
#: authentik/events/models.py:294
|
||||
msgid "authentik inbuilt notifications"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:296
|
||||
#: authentik/events/models.py:295
|
||||
msgid "Generic Webhook"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:297
|
||||
#: authentik/events/models.py:296
|
||||
msgid "Slack Webhook (Slack/Discord)"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:298
|
||||
#: authentik/events/models.py:297
|
||||
msgid "Email"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:316
|
||||
#: authentik/events/models.py:315
|
||||
msgid ""
|
||||
"Only send notification once, for example when sending a webhook into a chat "
|
||||
"channel."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:376
|
||||
#: authentik/events/models.py:375
|
||||
msgid "Severity"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:381
|
||||
#: authentik/events/models.py:380
|
||||
msgid "Dispatched for user"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:465
|
||||
#: authentik/events/models.py:464
|
||||
msgid "Notification Transport"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:466
|
||||
#: authentik/events/models.py:465
|
||||
msgid "Notification Transports"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:472
|
||||
#: authentik/events/models.py:471
|
||||
msgid "Notice"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:473
|
||||
#: authentik/events/models.py:472
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:474
|
||||
#: authentik/events/models.py:473
|
||||
msgid "Alert"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:500
|
||||
#: authentik/events/models.py:499
|
||||
msgid "Notification"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:501
|
||||
#: authentik/events/models.py:500
|
||||
msgid "Notifications"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:521
|
||||
#: authentik/events/models.py:520
|
||||
msgid "Controls which severity level the created notifications will have."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:547
|
||||
#: authentik/events/models.py:546
|
||||
msgid "Notification Rule"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:548
|
||||
#: authentik/events/models.py:547
|
||||
msgid "Notification Rules"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:569
|
||||
#: authentik/events/models.py:568
|
||||
msgid "Webhook Mapping"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/events/models.py:570
|
||||
#: authentik/events/models.py:569
|
||||
msgid "Webhook Mappings"
|
||||
msgstr ""
|
||||
|
||||
@ -374,7 +374,7 @@ msgstr ""
|
||||
msgid "Task has not been run yet."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/flows/api/flows.py:297
|
||||
#: authentik/flows/api/flows.py:292
|
||||
#, python-format
|
||||
msgid "Flow not applicable to current user/request: %(messages)s"
|
||||
msgstr ""
|
||||
@ -490,12 +490,12 @@ msgstr ""
|
||||
msgid "%(value)s is not in the correct format of 'hours=3;minutes=1'."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/outposts/api/service_connections.py:132
|
||||
#: authentik/outposts/api/service_connections.py:131
|
||||
msgid ""
|
||||
"You can only use an empty kubeconfig when connecting to a local cluster."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/outposts/api/service_connections.py:140
|
||||
#: authentik/outposts/api/service_connections.py:139
|
||||
msgid "Invalid kubeconfig"
|
||||
msgstr ""
|
||||
|
||||
@ -925,7 +925,7 @@ msgstr ""
|
||||
msgid "Device Tokens"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/oauth2/views/authorize.py:412
|
||||
#: authentik/providers/oauth2/views/authorize.py:411
|
||||
#: authentik/providers/saml/views/flows.py:88
|
||||
#, python-format
|
||||
msgid "Redirecting to %(app)s..."
|
||||
@ -974,36 +974,42 @@ msgid ""
|
||||
"with internal_host."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/proxy/models.py:79
|
||||
#: authentik/providers/proxy/models.py:80
|
||||
msgid ""
|
||||
"When enabled, this provider will intercept the authorization header and "
|
||||
"authenticate requests based on its value."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/proxy/models.py:86
|
||||
msgid "Set HTTP-Basic Authentication"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/proxy/models.py:81
|
||||
#: authentik/providers/proxy/models.py:88
|
||||
msgid ""
|
||||
"Set a custom HTTP-Basic Authentication header based on values from authentik."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/proxy/models.py:86
|
||||
#: authentik/providers/proxy/models.py:93
|
||||
msgid "HTTP-Basic Username Key"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/proxy/models.py:96
|
||||
#: authentik/providers/proxy/models.py:103
|
||||
msgid "HTTP-Basic Password Key"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/proxy/models.py:152
|
||||
#: authentik/providers/proxy/models.py:159
|
||||
msgid "Proxy Provider"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/proxy/models.py:153
|
||||
#: authentik/providers/proxy/models.py:160
|
||||
msgid "Proxy Providers"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/saml/api/providers.py:261
|
||||
#: authentik/providers/saml/api/providers.py:260
|
||||
msgid "Invalid XML Syntax"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/providers/saml/api/providers.py:271
|
||||
#: authentik/providers/saml/api/providers.py:270
|
||||
#, python-format
|
||||
msgid "Failed to import Metadata: %(message)s"
|
||||
msgstr ""
|
||||
@ -1174,7 +1180,7 @@ msgstr ""
|
||||
msgid "LDAP Property Mappings"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/sources/ldap/signals.py:58
|
||||
#: authentik/sources/ldap/signals.py:56
|
||||
msgid "Password does not match Active Directory Complexity."
|
||||
msgstr ""
|
||||
|
||||
@ -1323,7 +1329,7 @@ msgstr ""
|
||||
msgid "User OAuth Source Connections"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/sources/oauth/views/callback.py:103
|
||||
#: authentik/sources/oauth/views/callback.py:100
|
||||
#, python-format
|
||||
msgid "Authentication failed: %(reason)s"
|
||||
msgstr ""
|
||||
@ -1460,30 +1466,35 @@ msgstr ""
|
||||
msgid "Optionally modify the payload being sent to custom providers."
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/models.py:176
|
||||
#: authentik/stages/authenticator_sms/models.py:81
|
||||
#, python-format
|
||||
msgid "Use this code to authenticate in authentik: %(token)s"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/models.py:181
|
||||
msgid "SMS Authenticator Setup Stage"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/models.py:177
|
||||
#: authentik/stages/authenticator_sms/models.py:182
|
||||
msgid "SMS Authenticator Setup Stages"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/models.py:222
|
||||
#: authentik/stages/authenticator_sms/models.py:227
|
||||
msgid "SMS Device"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/models.py:223
|
||||
#: authentik/stages/authenticator_sms/models.py:228
|
||||
msgid "SMS Devices"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/stage.py:56
|
||||
msgid "Invalid phone number"
|
||||
#: authentik/stages/authenticator_sms/stage.py:55
|
||||
#: authentik/stages/authenticator_totp/stage.py:42
|
||||
#: authentik/stages/authenticator_totp/stage.py:45
|
||||
msgid "Code does not match"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_sms/stage.py:61
|
||||
#: authentik/stages/authenticator_totp/stage.py:41
|
||||
#: authentik/stages/authenticator_totp/stage.py:44
|
||||
msgid "Code does not match"
|
||||
#: authentik/stages/authenticator_sms/stage.py:71
|
||||
msgid "Invalid phone number"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/authenticator_static/models.py:47
|
||||
@ -1694,7 +1705,7 @@ msgstr ""
|
||||
#: authentik/stages/email/templates/email/password_reset.html:19
|
||||
msgid ""
|
||||
"\n"
|
||||
" You recently requested to change your password for you "
|
||||
" You recently requested to change your password for your "
|
||||
"authentik account. Use the button below to set a new password.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
@ -1794,7 +1805,7 @@ msgstr ""
|
||||
msgid "Invitations"
|
||||
msgstr ""
|
||||
|
||||
#: authentik/stages/invitation/stage.py:61
|
||||
#: authentik/stages/invitation/stage.py:66
|
||||
msgid "Invalid invite/invite not found"
|
||||
msgstr ""
|
||||
|
||||
|
BIN
locale/ko_KR/LC_MESSAGES/django.mo
Normal file
BIN
locale/ko_KR/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
BIN
locale/pl/LC_MESSAGES/django.mo
Normal file
BIN
locale/pl/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
BIN
locale/pl_PL/LC_MESSAGES/django.mo
Normal file
BIN
locale/pl_PL/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
BIN
locale/pt_PT/LC_MESSAGES/django.mo
Normal file
BIN
locale/pt_PT/LC_MESSAGES/django.mo
Normal file
Binary file not shown.
20
poetry.lock
generated
20
poetry.lock
generated
@ -2084,27 +2084,25 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "paramiko"
|
||||
version = "2.12.0"
|
||||
version = "3.0.0"
|
||||
description = "SSH2 protocol library"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "paramiko-2.12.0-py2.py3-none-any.whl", hash = "sha256:b2df1a6325f6996ef55a8789d0462f5b502ea83b3c990cbb5bbe57345c6812c4"},
|
||||
{file = "paramiko-2.12.0.tar.gz", hash = "sha256:376885c05c5d6aa6e1f4608aac2a6b5b0548b1add40274477324605903d9cd49"},
|
||||
{file = "paramiko-3.0.0-py3-none-any.whl", hash = "sha256:6bef55b882c9d130f8015b9a26f4bd93f710e90fe7478b9dcc810304e79b3cd8"},
|
||||
{file = "paramiko-3.0.0.tar.gz", hash = "sha256:fedc9b1dd43bc1d45f67f1ceca10bc336605427a46dcdf8dec6bfea3edf57965"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
bcrypt = ">=3.1.3"
|
||||
cryptography = ">=2.5"
|
||||
pynacl = ">=1.0.1"
|
||||
six = "*"
|
||||
bcrypt = ">=3.2"
|
||||
cryptography = ">=3.3"
|
||||
pynacl = ">=1.5"
|
||||
|
||||
[package.extras]
|
||||
all = ["bcrypt (>=3.1.3)", "gssapi (>=1.4.1)", "invoke (>=1.3)", "pyasn1 (>=0.1.7)", "pynacl (>=1.0.1)", "pywin32 (>=2.1.8)"]
|
||||
ed25519 = ["bcrypt (>=3.1.3)", "pynacl (>=1.0.1)"]
|
||||
all = ["gssapi (>=1.4.1)", "invoke (>=2.0)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"]
|
||||
gssapi = ["gssapi (>=1.4.1)", "pyasn1 (>=0.1.7)", "pywin32 (>=2.1.8)"]
|
||||
invoke = ["invoke (>=1.3)"]
|
||||
invoke = ["invoke (>=2.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
|
@ -107,10 +107,14 @@ DJANGO_SETTINGS_MODULE = "authentik.root.settings"
|
||||
python_files = ["tests.py", "test_*.py", "*_tests.py"]
|
||||
junit_family = "xunit2"
|
||||
addopts = "-p no:celery --junitxml=unittest.xml"
|
||||
filterwarnings = [
|
||||
"ignore:defusedxml.lxml is no longer supported and will be removed in a future release.:DeprecationWarning",
|
||||
"ignore:SelectableGroups dict interface is deprecated. Use select.:DeprecationWarning",
|
||||
]
|
||||
|
||||
[tool.poetry]
|
||||
name = "authentik"
|
||||
version = "2023.1.0"
|
||||
version = "2023.1.1"
|
||||
description = ""
|
||||
authors = ["authentik Team <hello@goauthentik.io>"]
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: authentik
|
||||
version: 2023.1.0
|
||||
version: 2023.1.1
|
||||
description: Making authentication simple.
|
||||
contact:
|
||||
email: hello@goauthentik.io
|
||||
|
165
tests/e2e/test_source_ldap_samba.py
Normal file
165
tests/e2e/test_source_ldap_samba.py
Normal file
@ -0,0 +1,165 @@
|
||||
"""test LDAP Source"""
|
||||
from typing import Any, Optional
|
||||
|
||||
from django.db.models import Q
|
||||
|
||||
from authentik.blueprints.tests import apply_blueprint
|
||||
from authentik.core.models import Group, User
|
||||
from authentik.lib.generators import generate_id, generate_key
|
||||
from authentik.sources.ldap.auth import LDAPBackend
|
||||
from authentik.sources.ldap.models import LDAPPropertyMapping, LDAPSource
|
||||
from authentik.sources.ldap.sync.groups import GroupLDAPSynchronizer
|
||||
from authentik.sources.ldap.sync.membership import MembershipLDAPSynchronizer
|
||||
from authentik.sources.ldap.sync.users import UserLDAPSynchronizer
|
||||
from tests.e2e.utils import SeleniumTestCase, retry
|
||||
|
||||
|
||||
class TestSourceLDAPSamba(SeleniumTestCase):
|
||||
"""test LDAP Source"""
|
||||
|
||||
def setUp(self):
|
||||
self.admin_password = generate_key()
|
||||
super().setUp()
|
||||
|
||||
def get_container_specs(self) -> Optional[dict[str, Any]]:
|
||||
return {
|
||||
"image": "ghcr.io/beryju/test-samba-dc:latest",
|
||||
"detach": True,
|
||||
"cap_add": ["SYS_ADMIN"],
|
||||
"ports": {
|
||||
"389": "389/tcp",
|
||||
},
|
||||
"auto_remove": True,
|
||||
"environment": {
|
||||
"SMB_DOMAIN": "test.goauthentik.io",
|
||||
"SMB_NETBIOS": "goauthentik",
|
||||
"SMB_ADMIN_PASSWORD": self.admin_password,
|
||||
},
|
||||
}
|
||||
|
||||
@retry()
|
||||
@apply_blueprint(
|
||||
"system/sources-ldap.yaml",
|
||||
)
|
||||
def test_source_sync(self):
|
||||
"""Test Sync"""
|
||||
source = LDAPSource.objects.create(
|
||||
name=generate_id(),
|
||||
slug=generate_id(),
|
||||
server_uri="ldap://localhost",
|
||||
bind_cn="administrator@test.goauthentik.io",
|
||||
bind_password=self.admin_password,
|
||||
base_dn="dc=test,dc=goauthentik,dc=io",
|
||||
additional_user_dn="ou=users",
|
||||
additional_group_dn="ou=groups",
|
||||
)
|
||||
source.property_mappings.set(
|
||||
LDAPPropertyMapping.objects.filter(
|
||||
Q(managed__startswith="goauthentik.io/sources/ldap/default-")
|
||||
| Q(managed__startswith="goauthentik.io/sources/ldap/ms-")
|
||||
)
|
||||
)
|
||||
source.property_mappings_group.set(
|
||||
LDAPPropertyMapping.objects.filter(name="goauthentik.io/sources/ldap/default-name")
|
||||
)
|
||||
UserLDAPSynchronizer(source).sync()
|
||||
self.assertTrue(User.objects.filter(username="bob").exists())
|
||||
self.assertTrue(User.objects.filter(username="james").exists())
|
||||
self.assertTrue(User.objects.filter(username="john").exists())
|
||||
self.assertTrue(User.objects.filter(username="harry").exists())
|
||||
|
||||
@retry()
|
||||
@apply_blueprint(
|
||||
"system/sources-ldap.yaml",
|
||||
)
|
||||
def test_source_sync_group(self):
|
||||
"""Test Sync"""
|
||||
source = LDAPSource.objects.create(
|
||||
name=generate_id(),
|
||||
slug=generate_id(),
|
||||
server_uri="ldap://localhost",
|
||||
bind_cn="administrator@test.goauthentik.io",
|
||||
bind_password=self.admin_password,
|
||||
base_dn="dc=test,dc=goauthentik,dc=io",
|
||||
additional_user_dn="ou=users",
|
||||
additional_group_dn="ou=groups",
|
||||
)
|
||||
source.property_mappings.set(
|
||||
LDAPPropertyMapping.objects.filter(
|
||||
Q(managed__startswith="goauthentik.io/sources/ldap/default-")
|
||||
| Q(managed__startswith="goauthentik.io/sources/ldap/ms-")
|
||||
)
|
||||
)
|
||||
source.property_mappings_group.set(
|
||||
LDAPPropertyMapping.objects.filter(managed="goauthentik.io/sources/ldap/default-name")
|
||||
)
|
||||
GroupLDAPSynchronizer(source).sync()
|
||||
UserLDAPSynchronizer(source).sync()
|
||||
MembershipLDAPSynchronizer(source).sync()
|
||||
self.assertIsNotNone(User.objects.get(username="bob"))
|
||||
self.assertIsNotNone(User.objects.get(username="james"))
|
||||
self.assertIsNotNone(User.objects.get(username="john"))
|
||||
self.assertIsNotNone(User.objects.get(username="harry"))
|
||||
self.assertIsNotNone(Group.objects.get(name="dev"))
|
||||
self.assertEqual(
|
||||
list(User.objects.get(username="bob").ak_groups.all()), [Group.objects.get(name="dev")]
|
||||
)
|
||||
self.assertEqual(list(User.objects.get(username="james").ak_groups.all()), [])
|
||||
self.assertEqual(
|
||||
list(User.objects.get(username="john").ak_groups.all().order_by("name")),
|
||||
[Group.objects.get(name="admins"), Group.objects.get(name="dev")],
|
||||
)
|
||||
self.assertEqual(list(User.objects.get(username="harry").ak_groups.all()), [])
|
||||
|
||||
@retry()
|
||||
@apply_blueprint(
|
||||
"system/sources-ldap.yaml",
|
||||
)
|
||||
def test_sync_password(self):
|
||||
"""Test Sync"""
|
||||
source = LDAPSource.objects.create(
|
||||
name=generate_id(),
|
||||
slug=generate_id(),
|
||||
server_uri="ldap://localhost",
|
||||
bind_cn="administrator@test.goauthentik.io",
|
||||
bind_password=self.admin_password,
|
||||
base_dn="dc=test,dc=goauthentik,dc=io",
|
||||
additional_user_dn="ou=users",
|
||||
additional_group_dn="ou=groups",
|
||||
)
|
||||
source.property_mappings.set(
|
||||
LDAPPropertyMapping.objects.filter(
|
||||
Q(managed__startswith="goauthentik.io/sources/ldap/default-")
|
||||
| Q(managed__startswith="goauthentik.io/sources/ldap/ms-")
|
||||
)
|
||||
)
|
||||
source.property_mappings_group.set(
|
||||
LDAPPropertyMapping.objects.filter(name="goauthentik.io/sources/ldap/default-name")
|
||||
)
|
||||
UserLDAPSynchronizer(source).sync()
|
||||
username = "bob"
|
||||
password = generate_id()
|
||||
result = self.container.exec_run(
|
||||
["samba-tool", "user", "setpassword", username, "--newpassword", password]
|
||||
)
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
user: User = User.objects.get(username=username)
|
||||
# Ensure user has an unusable password directly after sync
|
||||
self.assertFalse(user.has_usable_password())
|
||||
# Auth (which will fallback to bind)
|
||||
LDAPBackend().auth_user(source, password, username=username)
|
||||
user.refresh_from_db()
|
||||
# User should now have a usable password in the database
|
||||
self.assertTrue(user.has_usable_password())
|
||||
self.assertTrue(user.check_password(password))
|
||||
# Set new password
|
||||
new_password = generate_id()
|
||||
result = self.container.exec_run(
|
||||
["samba-tool", "user", "setpassword", username, "--newpassword", new_password]
|
||||
)
|
||||
self.assertEqual(result.exit_code, 0)
|
||||
# Sync again
|
||||
UserLDAPSynchronizer(source).sync()
|
||||
user.refresh_from_db()
|
||||
# Since password in samba was checked, it should be invalidated here too
|
||||
self.assertFalse(user.has_usable_password())
|
@ -54,7 +54,6 @@ class SeleniumTestCase(StaticLiveServerTestCase):
|
||||
self.maxDiff = None
|
||||
self.wait_timeout = 60
|
||||
self.driver = self._get_driver()
|
||||
self.driver.maximize_window()
|
||||
self.driver.implicitly_wait(30)
|
||||
self.wait = WebDriverWait(self.driver, self.wait_timeout)
|
||||
self.logger = get_logger()
|
||||
@ -77,7 +76,9 @@ class SeleniumTestCase(StaticLiveServerTestCase):
|
||||
def _start_container(self, specs: dict[str, Any]) -> Container:
|
||||
client: DockerClient = from_env()
|
||||
container = client.containers.run(**specs)
|
||||
if "healthcheck" not in specs:
|
||||
container.reload()
|
||||
state = container.attrs.get("State", {})
|
||||
if "Health" not in state:
|
||||
return container
|
||||
while True:
|
||||
container.reload()
|
||||
@ -100,12 +101,18 @@ class SeleniumTestCase(StaticLiveServerTestCase):
|
||||
|
||||
def _get_driver(self) -> WebDriver:
|
||||
count = 0
|
||||
try:
|
||||
return webdriver.Chrome()
|
||||
except WebDriverException:
|
||||
pass
|
||||
while count < RETRIES:
|
||||
try:
|
||||
return webdriver.Remote(
|
||||
driver = webdriver.Remote(
|
||||
command_executor="http://localhost:4444/wd/hub",
|
||||
options=webdriver.ChromeOptions(),
|
||||
)
|
||||
driver.maximize_window()
|
||||
return driver
|
||||
except WebDriverException:
|
||||
count += 1
|
||||
raise ValueError(f"Webdriver failed after {RETRIES}.")
|
||||
|
264
web/package-lock.json
generated
264
web/package-lock.json
generated
@ -10,7 +10,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/plugin-proposal-decorators": "^7.20.7",
|
||||
"@babel/plugin-proposal-decorators": "^7.20.13",
|
||||
"@babel/plugin-transform-runtime": "^7.19.6",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
@ -21,18 +21,18 @@
|
||||
"@codemirror/legacy-modes": "^6.3.1",
|
||||
"@formatjs/intl-listformat": "^7.1.7",
|
||||
"@fortawesome/fontawesome-free": "^6.2.1",
|
||||
"@goauthentik/api": "^2022.12.2-1673978239",
|
||||
"@goauthentik/api": "^2023.1.0-1674058489",
|
||||
"@hcaptcha/types": "^1.0.3",
|
||||
"@jackfranklin/rollup-plugin-markdown": "^0.4.0",
|
||||
"@lingui/cli": "^3.15.0",
|
||||
"@lingui/core": "^3.15.0",
|
||||
"@lingui/detect-locale": "^3.15.0",
|
||||
"@lingui/macro": "^3.15.0",
|
||||
"@lingui/cli": "^3.16.0",
|
||||
"@lingui/core": "^3.16.0",
|
||||
"@lingui/detect-locale": "^3.16.0",
|
||||
"@lingui/macro": "^3.16.0",
|
||||
"@patternfly/patternfly": "^4.222.4",
|
||||
"@polymer/iron-form": "^3.0.1",
|
||||
"@polymer/paper-input": "^3.2.1",
|
||||
"@rollup/plugin-babel": "^6.0.3",
|
||||
"@rollup/plugin-commonjs": "^24.0.0",
|
||||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@rollup/plugin-typescript": "^11.0.0",
|
||||
@ -49,11 +49,11 @@
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"babel-plugin-tsconfig-paths": "^1.0.3",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.1.2",
|
||||
"chart.js": "^4.2.0",
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"construct-style-sheets-polyfill": "^3.1.0",
|
||||
"core-js": "^3.27.1",
|
||||
"core-js": "^3.27.2",
|
||||
"country-flag-icons": "^1.5.5",
|
||||
"eslint": "^8.32.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
@ -214,9 +214,9 @@
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
|
||||
},
|
||||
"node_modules/@babel/helper-create-class-features-plugin": {
|
||||
"version": "7.20.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.7.tgz",
|
||||
"integrity": "sha512-LtoWbDXOaidEf50hmdDqn9g8VEzsorMexoWMQdQODbvmqYmaF23pBP5VNPAGIFHsFQCIeKokDiz3CH5Y2jlY6w==",
|
||||
"version": "7.20.12",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
|
||||
"integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
|
||||
"dependencies": {
|
||||
"@babel/helper-annotate-as-pure": "^7.18.6",
|
||||
"@babel/helper-environment-visitor": "^7.18.9",
|
||||
@ -224,6 +224,7 @@
|
||||
"@babel/helper-member-expression-to-functions": "^7.20.7",
|
||||
"@babel/helper-optimise-call-expression": "^7.18.6",
|
||||
"@babel/helper-replace-supers": "^7.20.7",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6"
|
||||
},
|
||||
"engines": {
|
||||
@ -410,11 +411,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
|
||||
"version": "7.18.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz",
|
||||
"integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==",
|
||||
"version": "7.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz",
|
||||
"integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.18.9"
|
||||
"@babel/types": "^7.20.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
@ -585,11 +586,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/plugin-proposal-decorators": {
|
||||
"version": "7.20.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.7.tgz",
|
||||
"integrity": "sha512-JB45hbUweYpwAGjkiM7uCyXMENH2lG+9r3G2E+ttc2PRXAoEkpfd/KW5jDg4j8RS6tLtTG1jZi9LbHZVSfs1/A==",
|
||||
"version": "7.20.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.13.tgz",
|
||||
"integrity": "sha512-7T6BKHa9Cpd7lCueHBBzP0nkXNina+h5giOZw+a8ZpMfPFY19VjJAjIxyFHuWkhCWgL6QMqRiY/wB1fLXzm6Mw==",
|
||||
"dependencies": {
|
||||
"@babel/helper-create-class-features-plugin": "^7.20.7",
|
||||
"@babel/helper-create-class-features-plugin": "^7.20.12",
|
||||
"@babel/helper-plugin-utils": "^7.20.2",
|
||||
"@babel/helper-replace-supers": "^7.20.7",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
||||
@ -1960,9 +1961,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@goauthentik/api": {
|
||||
"version": "2022.12.2-1673978239",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2022.12.2-1673978239.tgz",
|
||||
"integrity": "sha512-VQOn3ySAcjvdeEI5yKbpFQfGD3lh+C1t81SafjwlsDhpFWhbEIaWRyokiw7XYb9b2LyHn3SZTbJjoIhrPEvPow=="
|
||||
"version": "2023.1.0-1674058489",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2023.1.0-1674058489.tgz",
|
||||
"integrity": "sha512-k100Z1Tx4o7EsIq+tezavHSSddpr51NlGJZyR9QHsaQq6K+BpxZVcozR7xau7zK615JAwljWeG4yfEq9to++rw=="
|
||||
},
|
||||
"node_modules/@hcaptcha/types": {
|
||||
"version": "1.0.3",
|
||||
@ -2214,31 +2215,32 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/babel-plugin-extract-messages": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.15.0.tgz",
|
||||
"integrity": "sha512-iMQmJIkC18Zwc/IDpm3Oclj3KMDQuvipCS2yVHr0MyaeOCeOZ3ZoLVeaa8pfE5pImzlHJ0ss8RRm/St54JElhw==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.16.0.tgz",
|
||||
"integrity": "sha512-Wxfp9cJfVjwhVigufIssoDntaTm4a8XXkmsV9gTMCr2xJL6ZowoC80TltBLOu0Dt829e6pdy+TFuwuKwAvnmrA==",
|
||||
"dependencies": {
|
||||
"@babel/generator": "^7.11.6",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@lingui/conf": "^3.15.0",
|
||||
"@lingui/conf": "3.16.0",
|
||||
"mkdirp": "^1.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/cli": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.15.0.tgz",
|
||||
"integrity": "sha512-6arKc0Mc1z3ABHobjPkhViV+7VUjBhwFwoU0VlT7HBmtrOYad9CBwWEiD+oiEhiHYzLTR7lHTVf674IjTuVvJQ==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.16.0.tgz",
|
||||
"integrity": "sha512-6sUVpA6UB4BwNtLjC9aG62QvxkhHwVmDOi9vO8kb9W4SKPBaMdHuaxEsVVBuD1ZWcFZULcNUmPh9kKAnMRkHHw==",
|
||||
"dependencies": {
|
||||
"@babel/generator": "^7.11.6",
|
||||
"@babel/parser": "^7.11.5",
|
||||
"@babel/plugin-syntax-jsx": "^7.10.4",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@babel/types": "^7.11.5",
|
||||
"@lingui/babel-plugin-extract-messages": "^3.15.0",
|
||||
"@lingui/conf": "^3.15.0",
|
||||
"@lingui/babel-plugin-extract-messages": "3.16.0",
|
||||
"@lingui/conf": "3.16.0",
|
||||
"@lingui/core": "3.16.0",
|
||||
"babel-plugin-macros": "^3.0.1",
|
||||
"bcp-47": "^1.0.7",
|
||||
"chalk": "^4.1.0",
|
||||
@ -2251,7 +2253,6 @@
|
||||
"glob": "^7.1.4",
|
||||
"inquirer": "^7.3.3",
|
||||
"make-plural": "^6.2.2",
|
||||
"messageformat-parser": "^4.1.3",
|
||||
"micromatch": "4.0.2",
|
||||
"mkdirp": "^1.0.4",
|
||||
"node-gettext": "^3.0.0",
|
||||
@ -2265,10 +2266,10 @@
|
||||
"ramda": "^0.27.1"
|
||||
},
|
||||
"bin": {
|
||||
"lingui": "lingui.js"
|
||||
"lingui": "build/lingui.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@babel/core": "^7.0.0",
|
||||
@ -2341,9 +2342,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/conf": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.15.0.tgz",
|
||||
"integrity": "sha512-gDGBbqWo6+B3PNjxTGl2asVdd8hC6w+iGsEPonvMw7GFmXb99qybBGdV2ofDlwlT9vChcPwMVtrYE6H0fTZuzA==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.16.0.tgz",
|
||||
"integrity": "sha512-65X3TySGzeYjVNE3YZDpF6LTYxpUiSRSyTJjEGB7ZSPpuL6VDMEUGCDsnur2ix8D+I8w0ife6ks4HPQt6owZmw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"chalk": "^4.1.0",
|
||||
@ -2353,7 +2354,7 @@
|
||||
"lodash.get": "^4.4.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/conf/node_modules/ansi-styles": {
|
||||
@ -2421,42 +2422,42 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/core": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.15.0.tgz",
|
||||
"integrity": "sha512-owjYOn/3xaWVW01p32Ylt3cXkCP79oudJCHdcNOn4noxd/9BhyFX2wLiVf02DxGYnkAgAD3KCp3Z4iyKlueymg==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.16.0.tgz",
|
||||
"integrity": "sha512-2uZvxHv4IWF7xIRG1o4oXDFCrAhE0945Ses1eALmv/NqQ8BslXWWSq0Zf51qt+ZqQ3RfzCdl4kslZEqdGRe0gw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"make-plural": "^6.2.2",
|
||||
"messageformat-parser": "^4.1.3"
|
||||
"@messageformat/parser": "^5.0.0",
|
||||
"make-plural": "^6.2.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/detect-locale": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.15.0.tgz",
|
||||
"integrity": "sha512-+4yLIAyk8asygMGLbR271qHCAT2HQ2AyjljH/xvwMua0sqVX+ES3fwStggJOsCk0zC1yfjMrjV4lAMTPHy5XoA==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.16.0.tgz",
|
||||
"integrity": "sha512-7FQy1ccPnVe0/GNAzTmEDrsPHZV1/nSsK6fRKyuOFUkiItc1bVDmlpVfM4UXerERx6Nez+N99Z6Vjc6rg3LARw==",
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/macro": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.15.0.tgz",
|
||||
"integrity": "sha512-3+txZQM5UmC+t1zkoYeYkg3r5pIGo9KdD+csX0u4F0IUE2GJkjy+sG917hOhw3QsDUqiCIqDJ503AdSfFbO+uA==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.16.0.tgz",
|
||||
"integrity": "sha512-3HfP1Bqr4i60P3LoQq/ukhDvel4a5oBSMPRuYBUpwqdnKOAbZuN5vnZmu3TrlXntWTYOvrwa71D8SYGmvevelw==",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@lingui/conf": "^3.15.0",
|
||||
"@lingui/conf": "3.16.0",
|
||||
"ramda": "^0.27.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@lingui/core": "^3.13.0",
|
||||
"@lingui/react": "^3.13.0",
|
||||
"babel-plugin-macros": "2 || 3"
|
||||
"babel-plugin-macros": "2 || 3"
|
||||
}
|
||||
},
|
||||
"node_modules/@lingui/react": {
|
||||
@ -2488,6 +2489,14 @@
|
||||
"@lit-labs/ssr-dom-shim": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@messageformat/parser": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.0.0.tgz",
|
||||
"integrity": "sha512-WiDKhi8F0zQaFU8cXgqq69eYFarCnTVxKcvhAONufKf0oUxbqLMW6JX6rV4Hqh+BEQWGyKKKHY4g1XA6bCLylA==",
|
||||
"dependencies": {
|
||||
"moo": "^0.5.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@mrmlnc/readdir-enhanced": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
||||
@ -2717,9 +2726,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-commonjs": {
|
||||
"version": "24.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.0.tgz",
|
||||
"integrity": "sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==",
|
||||
"version": "24.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.1.tgz",
|
||||
"integrity": "sha512-15LsiWRZk4eOGqvrJyu3z3DaBu5BhXIMeWnijSRvd8irrrg9SHpQ1pH+BUK4H6Z9wL9yOxZJMTLU+Au86XHxow==",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"commondir": "^1.0.1",
|
||||
@ -4218,9 +4227,9 @@
|
||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
||||
},
|
||||
"node_modules/chart.js": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.1.2.tgz",
|
||||
"integrity": "sha512-9L1w6WLPq6ztiWVVOYtDtpo0CUsBKDWPrUEdwChAyzczaikqeSwNKEv3QpJ7EO4ICcLSi6UDVhgvcnUhRJidRA==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.0.tgz",
|
||||
"integrity": "sha512-wbtcV+QKeH0F7gQZaCJEIpsNriFheacouJQTVIjITi3eQA8bTlIBoknz0+dgV79aeKLNMAX+nDslIVE/nJ3rzA==",
|
||||
"dependencies": {
|
||||
"@kurkle/color": "^0.3.0"
|
||||
},
|
||||
@ -4530,9 +4539,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/core-js": {
|
||||
"version": "3.27.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz",
|
||||
"integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==",
|
||||
"version": "3.27.2",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.2.tgz",
|
||||
"integrity": "sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w==",
|
||||
"hasInstallScript": true,
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
@ -7399,11 +7408,6 @@
|
||||
"uuid": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/messageformat-parser": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz",
|
||||
"integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg=="
|
||||
},
|
||||
"node_modules/micromatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
||||
@ -7483,6 +7487,11 @@
|
||||
"resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.24.0.tgz",
|
||||
"integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ=="
|
||||
},
|
||||
"node_modules/moo": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
|
||||
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
@ -10209,9 +10218,9 @@
|
||||
}
|
||||
},
|
||||
"@babel/helper-create-class-features-plugin": {
|
||||
"version": "7.20.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.7.tgz",
|
||||
"integrity": "sha512-LtoWbDXOaidEf50hmdDqn9g8VEzsorMexoWMQdQODbvmqYmaF23pBP5VNPAGIFHsFQCIeKokDiz3CH5Y2jlY6w==",
|
||||
"version": "7.20.12",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
|
||||
"integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
|
||||
"requires": {
|
||||
"@babel/helper-annotate-as-pure": "^7.18.6",
|
||||
"@babel/helper-environment-visitor": "^7.18.9",
|
||||
@ -10219,6 +10228,7 @@
|
||||
"@babel/helper-member-expression-to-functions": "^7.20.7",
|
||||
"@babel/helper-optimise-call-expression": "^7.18.6",
|
||||
"@babel/helper-replace-supers": "^7.20.7",
|
||||
"@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6"
|
||||
}
|
||||
},
|
||||
@ -10351,11 +10361,11 @@
|
||||
}
|
||||
},
|
||||
"@babel/helper-skip-transparent-expression-wrappers": {
|
||||
"version": "7.18.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz",
|
||||
"integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==",
|
||||
"version": "7.20.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz",
|
||||
"integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==",
|
||||
"requires": {
|
||||
"@babel/types": "^7.18.9"
|
||||
"@babel/types": "^7.20.0"
|
||||
}
|
||||
},
|
||||
"@babel/helper-split-export-declaration": {
|
||||
@ -10466,11 +10476,11 @@
|
||||
}
|
||||
},
|
||||
"@babel/plugin-proposal-decorators": {
|
||||
"version": "7.20.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.7.tgz",
|
||||
"integrity": "sha512-JB45hbUweYpwAGjkiM7uCyXMENH2lG+9r3G2E+ttc2PRXAoEkpfd/KW5jDg4j8RS6tLtTG1jZi9LbHZVSfs1/A==",
|
||||
"version": "7.20.13",
|
||||
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.13.tgz",
|
||||
"integrity": "sha512-7T6BKHa9Cpd7lCueHBBzP0nkXNina+h5giOZw+a8ZpMfPFY19VjJAjIxyFHuWkhCWgL6QMqRiY/wB1fLXzm6Mw==",
|
||||
"requires": {
|
||||
"@babel/helper-create-class-features-plugin": "^7.20.7",
|
||||
"@babel/helper-create-class-features-plugin": "^7.20.12",
|
||||
"@babel/helper-plugin-utils": "^7.20.2",
|
||||
"@babel/helper-replace-supers": "^7.20.7",
|
||||
"@babel/helper-split-export-declaration": "^7.18.6",
|
||||
@ -11427,9 +11437,9 @@
|
||||
"integrity": "sha512-viouXhegu/TjkvYQoiRZK3aax69dGXxgEjpvZW81wIJdxm5Fnvp3VVIP4VHKqX4SvFw6qpmkILkD4RJWAdrt7A=="
|
||||
},
|
||||
"@goauthentik/api": {
|
||||
"version": "2022.12.2-1673978239",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2022.12.2-1673978239.tgz",
|
||||
"integrity": "sha512-VQOn3ySAcjvdeEI5yKbpFQfGD3lh+C1t81SafjwlsDhpFWhbEIaWRyokiw7XYb9b2LyHn3SZTbJjoIhrPEvPow=="
|
||||
"version": "2023.1.0-1674058489",
|
||||
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2023.1.0-1674058489.tgz",
|
||||
"integrity": "sha512-k100Z1Tx4o7EsIq+tezavHSSddpr51NlGJZyR9QHsaQq6K+BpxZVcozR7xau7zK615JAwljWeG4yfEq9to++rw=="
|
||||
},
|
||||
"@hcaptcha/types": {
|
||||
"version": "1.0.3",
|
||||
@ -11640,28 +11650,29 @@
|
||||
}
|
||||
},
|
||||
"@lingui/babel-plugin-extract-messages": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.15.0.tgz",
|
||||
"integrity": "sha512-iMQmJIkC18Zwc/IDpm3Oclj3KMDQuvipCS2yVHr0MyaeOCeOZ3ZoLVeaa8pfE5pImzlHJ0ss8RRm/St54JElhw==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-extract-messages/-/babel-plugin-extract-messages-3.16.0.tgz",
|
||||
"integrity": "sha512-Wxfp9cJfVjwhVigufIssoDntaTm4a8XXkmsV9gTMCr2xJL6ZowoC80TltBLOu0Dt829e6pdy+TFuwuKwAvnmrA==",
|
||||
"requires": {
|
||||
"@babel/generator": "^7.11.6",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@lingui/conf": "^3.15.0",
|
||||
"@lingui/conf": "3.16.0",
|
||||
"mkdirp": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"@lingui/cli": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.15.0.tgz",
|
||||
"integrity": "sha512-6arKc0Mc1z3ABHobjPkhViV+7VUjBhwFwoU0VlT7HBmtrOYad9CBwWEiD+oiEhiHYzLTR7lHTVf674IjTuVvJQ==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/cli/-/cli-3.16.0.tgz",
|
||||
"integrity": "sha512-6sUVpA6UB4BwNtLjC9aG62QvxkhHwVmDOi9vO8kb9W4SKPBaMdHuaxEsVVBuD1ZWcFZULcNUmPh9kKAnMRkHHw==",
|
||||
"requires": {
|
||||
"@babel/generator": "^7.11.6",
|
||||
"@babel/parser": "^7.11.5",
|
||||
"@babel/plugin-syntax-jsx": "^7.10.4",
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@babel/types": "^7.11.5",
|
||||
"@lingui/babel-plugin-extract-messages": "^3.15.0",
|
||||
"@lingui/conf": "^3.15.0",
|
||||
"@lingui/babel-plugin-extract-messages": "3.16.0",
|
||||
"@lingui/conf": "3.16.0",
|
||||
"@lingui/core": "3.16.0",
|
||||
"babel-plugin-macros": "^3.0.1",
|
||||
"bcp-47": "^1.0.7",
|
||||
"chalk": "^4.1.0",
|
||||
@ -11674,7 +11685,6 @@
|
||||
"glob": "^7.1.4",
|
||||
"inquirer": "^7.3.3",
|
||||
"make-plural": "^6.2.2",
|
||||
"messageformat-parser": "^4.1.3",
|
||||
"micromatch": "4.0.2",
|
||||
"mkdirp": "^1.0.4",
|
||||
"node-gettext": "^3.0.0",
|
||||
@ -11734,9 +11744,9 @@
|
||||
}
|
||||
},
|
||||
"@lingui/conf": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.15.0.tgz",
|
||||
"integrity": "sha512-gDGBbqWo6+B3PNjxTGl2asVdd8hC6w+iGsEPonvMw7GFmXb99qybBGdV2ofDlwlT9vChcPwMVtrYE6H0fTZuzA==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-3.16.0.tgz",
|
||||
"integrity": "sha512-65X3TySGzeYjVNE3YZDpF6LTYxpUiSRSyTJjEGB7ZSPpuL6VDMEUGCDsnur2ix8D+I8w0ife6ks4HPQt6owZmw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"chalk": "^4.1.0",
|
||||
@ -11792,27 +11802,27 @@
|
||||
}
|
||||
},
|
||||
"@lingui/core": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.15.0.tgz",
|
||||
"integrity": "sha512-owjYOn/3xaWVW01p32Ylt3cXkCP79oudJCHdcNOn4noxd/9BhyFX2wLiVf02DxGYnkAgAD3KCp3Z4iyKlueymg==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/core/-/core-3.16.0.tgz",
|
||||
"integrity": "sha512-2uZvxHv4IWF7xIRG1o4oXDFCrAhE0945Ses1eALmv/NqQ8BslXWWSq0Zf51qt+ZqQ3RfzCdl4kslZEqdGRe0gw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"make-plural": "^6.2.2",
|
||||
"messageformat-parser": "^4.1.3"
|
||||
"@messageformat/parser": "^5.0.0",
|
||||
"make-plural": "^6.2.2"
|
||||
}
|
||||
},
|
||||
"@lingui/detect-locale": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.15.0.tgz",
|
||||
"integrity": "sha512-+4yLIAyk8asygMGLbR271qHCAT2HQ2AyjljH/xvwMua0sqVX+ES3fwStggJOsCk0zC1yfjMrjV4lAMTPHy5XoA=="
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/detect-locale/-/detect-locale-3.16.0.tgz",
|
||||
"integrity": "sha512-7FQy1ccPnVe0/GNAzTmEDrsPHZV1/nSsK6fRKyuOFUkiItc1bVDmlpVfM4UXerERx6Nez+N99Z6Vjc6rg3LARw=="
|
||||
},
|
||||
"@lingui/macro": {
|
||||
"version": "3.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.15.0.tgz",
|
||||
"integrity": "sha512-3+txZQM5UmC+t1zkoYeYkg3r5pIGo9KdD+csX0u4F0IUE2GJkjy+sG917hOhw3QsDUqiCIqDJ503AdSfFbO+uA==",
|
||||
"version": "3.16.0",
|
||||
"resolved": "https://registry.npmjs.org/@lingui/macro/-/macro-3.16.0.tgz",
|
||||
"integrity": "sha512-3HfP1Bqr4i60P3LoQq/ukhDvel4a5oBSMPRuYBUpwqdnKOAbZuN5vnZmu3TrlXntWTYOvrwa71D8SYGmvevelw==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@lingui/conf": "^3.15.0",
|
||||
"@lingui/conf": "3.16.0",
|
||||
"ramda": "^0.27.1"
|
||||
}
|
||||
},
|
||||
@ -11839,6 +11849,14 @@
|
||||
"@lit-labs/ssr-dom-shim": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@messageformat/parser": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@messageformat/parser/-/parser-5.0.0.tgz",
|
||||
"integrity": "sha512-WiDKhi8F0zQaFU8cXgqq69eYFarCnTVxKcvhAONufKf0oUxbqLMW6JX6rV4Hqh+BEQWGyKKKHY4g1XA6bCLylA==",
|
||||
"requires": {
|
||||
"moo": "^0.5.1"
|
||||
}
|
||||
},
|
||||
"@mrmlnc/readdir-enhanced": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
|
||||
@ -12031,9 +12049,9 @@
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-commonjs": {
|
||||
"version": "24.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.0.tgz",
|
||||
"integrity": "sha512-0w0wyykzdyRRPHOb0cQt14mIBLujfAv6GgP6g8nvg/iBxEm112t3YPPq+Buqe2+imvElTka+bjNlJ/gB56TD8g==",
|
||||
"version": "24.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-24.0.1.tgz",
|
||||
"integrity": "sha512-15LsiWRZk4eOGqvrJyu3z3DaBu5BhXIMeWnijSRvd8irrrg9SHpQ1pH+BUK4H6Z9wL9yOxZJMTLU+Au86XHxow==",
|
||||
"requires": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"commondir": "^1.0.1",
|
||||
@ -13111,9 +13129,9 @@
|
||||
"integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA=="
|
||||
},
|
||||
"chart.js": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.1.2.tgz",
|
||||
"integrity": "sha512-9L1w6WLPq6ztiWVVOYtDtpo0CUsBKDWPrUEdwChAyzczaikqeSwNKEv3QpJ7EO4ICcLSi6UDVhgvcnUhRJidRA==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.2.0.tgz",
|
||||
"integrity": "sha512-wbtcV+QKeH0F7gQZaCJEIpsNriFheacouJQTVIjITi3eQA8bTlIBoknz0+dgV79aeKLNMAX+nDslIVE/nJ3rzA==",
|
||||
"requires": {
|
||||
"@kurkle/color": "^0.3.0"
|
||||
}
|
||||
@ -13357,9 +13375,9 @@
|
||||
"integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40="
|
||||
},
|
||||
"core-js": {
|
||||
"version": "3.27.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz",
|
||||
"integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww=="
|
||||
"version": "3.27.2",
|
||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.2.tgz",
|
||||
"integrity": "sha512-9ashVQskuh5AZEZ1JdQWp1GqSoC1e1G87MzRqg2gIfVAQ7Qn9K+uFj8EcniUFA4P2NLZfV+TOlX1SzoKfo+s7w=="
|
||||
},
|
||||
"core-js-compat": {
|
||||
"version": "3.25.1",
|
||||
@ -15487,11 +15505,6 @@
|
||||
"uuid": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"messageformat-parser": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-4.1.3.tgz",
|
||||
"integrity": "sha512-2fU3XDCanRqeOCkn7R5zW5VQHWf+T3hH65SzuqRvjatBK7r4uyFa5mEX+k6F9Bd04LVM5G4/BHBTUJsOdW7uyg=="
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
||||
@ -15550,6 +15563,11 @@
|
||||
"resolved": "https://registry.npmjs.org/moment-mini/-/moment-mini-2.24.0.tgz",
|
||||
"integrity": "sha512-9ARkWHBs+6YJIvrIp0Ik5tyTTtP9PoV0Ssu2Ocq5y9v8+NOOpWiRshAp8c4rZVWTOe+157on/5G+zj5pwIQFEQ=="
|
||||
},
|
||||
"moo": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/moo/-/moo-0.5.2.tgz",
|
||||
"integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q=="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||
|
@ -54,7 +54,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.20.12",
|
||||
"@babel/plugin-proposal-decorators": "^7.20.7",
|
||||
"@babel/plugin-proposal-decorators": "^7.20.13",
|
||||
"@babel/plugin-transform-runtime": "^7.19.6",
|
||||
"@babel/preset-env": "^7.20.2",
|
||||
"@babel/preset-typescript": "^7.18.6",
|
||||
@ -65,18 +65,18 @@
|
||||
"@codemirror/legacy-modes": "^6.3.1",
|
||||
"@formatjs/intl-listformat": "^7.1.7",
|
||||
"@fortawesome/fontawesome-free": "^6.2.1",
|
||||
"@goauthentik/api": "^2022.12.2-1673978239",
|
||||
"@goauthentik/api": "^2023.1.0-1674058489",
|
||||
"@hcaptcha/types": "^1.0.3",
|
||||
"@jackfranklin/rollup-plugin-markdown": "^0.4.0",
|
||||
"@lingui/cli": "^3.15.0",
|
||||
"@lingui/core": "^3.15.0",
|
||||
"@lingui/detect-locale": "^3.15.0",
|
||||
"@lingui/macro": "^3.15.0",
|
||||
"@lingui/cli": "^3.16.0",
|
||||
"@lingui/core": "^3.16.0",
|
||||
"@lingui/detect-locale": "^3.16.0",
|
||||
"@lingui/macro": "^3.16.0",
|
||||
"@patternfly/patternfly": "^4.222.4",
|
||||
"@polymer/iron-form": "^3.0.1",
|
||||
"@polymer/paper-input": "^3.2.1",
|
||||
"@rollup/plugin-babel": "^6.0.3",
|
||||
"@rollup/plugin-commonjs": "^24.0.0",
|
||||
"@rollup/plugin-commonjs": "^24.0.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-replace": "^5.0.2",
|
||||
"@rollup/plugin-typescript": "^11.0.0",
|
||||
@ -93,11 +93,11 @@
|
||||
"babel-plugin-macros": "^3.1.0",
|
||||
"babel-plugin-tsconfig-paths": "^1.0.3",
|
||||
"base64-js": "^1.5.1",
|
||||
"chart.js": "^4.1.2",
|
||||
"chart.js": "^4.2.0",
|
||||
"chartjs-adapter-moment": "^1.0.1",
|
||||
"codemirror": "^6.0.1",
|
||||
"construct-style-sheets-polyfill": "^3.1.0",
|
||||
"core-js": "^3.27.1",
|
||||
"core-js": "^3.27.2",
|
||||
"country-flag-icons": "^1.5.5",
|
||||
"eslint": "^8.32.0",
|
||||
"eslint-config-google": "^0.14.0",
|
||||
|
@ -1,4 +1,4 @@
|
||||
Contact: mailto:security@goauthentik.io
|
||||
Expires: Mon, 1 Jan 2024 00:00 +0200
|
||||
Preferred-Languages: en, de
|
||||
Policy: https://github.com/goauthentik/authentik/blob/main/SECURITY.md
|
||||
Policy: https://goauthentik.io/docs/security/policy
|
||||
|
@ -255,7 +255,7 @@ new?labels=bug,from_authentik&title=${encodeURIComponent(title)}
|
||||
<div class="pf-l-flex">
|
||||
<div class="pf-l-flex__item">
|
||||
<h3>${t`Exception`}</h3>
|
||||
<code>${this.event.context.message}</code>
|
||||
<pre>${this.event.context.message}</pre>
|
||||
</div>
|
||||
</div>
|
||||
<ak-expand>${this.defaultResponse()}</ak-expand>`;
|
||||
@ -263,7 +263,7 @@ new?labels=bug,from_authentik&title=${encodeURIComponent(title)}
|
||||
return html`<div class="pf-l-flex">
|
||||
<div class="pf-l-flex__item">
|
||||
<h3>${t`Exception`}</h3>
|
||||
<code>${this.event.context.message || this.event.context.error}</code>
|
||||
<pre>${this.event.context.message || this.event.context.error}</pre>
|
||||
</div>
|
||||
<div class="pf-l-flex__item">
|
||||
<h3>${t`Expression`}</h3>
|
||||
@ -393,6 +393,13 @@ new?labels=bug,from_authentik&title=${encodeURIComponent(title)}
|
||||
return html`<span>${t`No additional data available.`}</span>`;
|
||||
}
|
||||
return this.defaultResponse();
|
||||
case EventActions.SystemTaskException:
|
||||
return html`<div class="pf-l-flex">
|
||||
<div class="pf-l-flex__item">
|
||||
<h3>${t`Exception`}</h3>
|
||||
<pre>${this.event.context.message}</pre>
|
||||
</div>
|
||||
</div>`;
|
||||
default:
|
||||
return this.defaultResponse();
|
||||
}
|
||||
|
@ -14,7 +14,20 @@ import { t } from "@lingui/macro";
|
||||
import { TemplateResult, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
|
||||
import { EventsApi, NotificationRule } from "@goauthentik/api";
|
||||
import { EventsApi, NotificationRule, SeverityEnum } from "@goauthentik/api";
|
||||
|
||||
export function SeverityToLabel(severity: SeverityEnum | null | undefined): string {
|
||||
if (!severity) return t`Unknown severity`;
|
||||
switch (severity) {
|
||||
case SeverityEnum.Alert:
|
||||
return t`Alert`;
|
||||
case SeverityEnum.Notice:
|
||||
return t`Notice`;
|
||||
case SeverityEnum.Warning:
|
||||
return t`Warning`;
|
||||
}
|
||||
return t`Unknown severity`;
|
||||
}
|
||||
|
||||
@customElement("ak-event-rule-list")
|
||||
export class RuleListPage extends TablePage<NotificationRule> {
|
||||
@ -80,8 +93,10 @@ export class RuleListPage extends TablePage<NotificationRule> {
|
||||
row(item: NotificationRule): TemplateResult[] {
|
||||
return [
|
||||
html`${item.name}`,
|
||||
html`${item.severity}`,
|
||||
html`${item.groupObj?.name || t`None (rule disabled)`}`,
|
||||
html`${SeverityToLabel(item.severity)}`,
|
||||
html`${item.groupObj
|
||||
? html`<a href="#/identity/groups/${item.groupObj.pk}">${item.groupObj.name}</a>`
|
||||
: t`None (rule disabled)`}`,
|
||||
html`<ak-forms-modal>
|
||||
<span slot="submit"> ${t`Update`} </span>
|
||||
<span slot="header"> ${t`Update Notification Rule`} </span>
|
||||
|
@ -61,7 +61,7 @@ export class ExpressionPolicyForm extends ModelForm<ExpressionPolicy, string> {
|
||||
<input
|
||||
class="pf-c-switch__input"
|
||||
type="checkbox"
|
||||
?checked=${first(this.instance?.executionLogging, true)}
|
||||
?checked=${first(this.instance?.executionLogging, false)}
|
||||
/>
|
||||
<span class="pf-c-switch__toggle">
|
||||
<span class="pf-c-switch__toggle-icon">
|
||||
|
@ -373,10 +373,10 @@ export class PlexSourceForm extends ModelForm<PlexSource, string> {
|
||||
return flow?.pk;
|
||||
}}
|
||||
.selected=${(flow: Flow): boolean => {
|
||||
let selected = this.instance?.enrollmentFlow === flow.pk;
|
||||
let selected = this.instance?.authenticationFlow === flow.pk;
|
||||
if (
|
||||
!this.instance?.pk &&
|
||||
!this.instance?.enrollmentFlow &&
|
||||
!this.instance?.authenticationFlow &&
|
||||
flow.slug === "default-source-authentication"
|
||||
) {
|
||||
selected = true;
|
||||
|
@ -3,7 +3,7 @@ export const SUCCESS_CLASS = "pf-m-success";
|
||||
export const ERROR_CLASS = "pf-m-danger";
|
||||
export const PROGRESS_CLASS = "pf-m-in-progress";
|
||||
export const CURRENT_CLASS = "pf-m-current";
|
||||
export const VERSION = "2023.1.0";
|
||||
export const VERSION = "2023.1.1";
|
||||
export const TITLE_DEFAULT = "authentik";
|
||||
export const ROUTE_SEPARATOR = ";";
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { EVENT_LOCALE_CHANGE } from "@goauthentik/common/constants";
|
||||
import { globalAK } from "@goauthentik/common/global";
|
||||
import { PluralCategory } from "make-plural";
|
||||
|
||||
import { Messages, i18n } from "@lingui/core";
|
||||
import { detect, fromNavigator, fromUrl } from "@lingui/detect-locale";
|
||||
@ -7,7 +8,7 @@ import { t } from "@lingui/macro";
|
||||
|
||||
interface Locale {
|
||||
locale: Messages;
|
||||
plurals: (n: string | number, ord?: boolean | undefined) => string;
|
||||
plurals: (n: string | number, ord?: boolean | undefined) => PluralCategory;
|
||||
}
|
||||
|
||||
export const LOCALES: {
|
||||
|
@ -160,8 +160,8 @@ export class SearchSelect<T> extends AKElement {
|
||||
shouldRenderGroups = false;
|
||||
groupedItems = [["", []]];
|
||||
}
|
||||
const renderGroup = (items: T[]): TemplateResult => {
|
||||
return html`${items.map((obj) => {
|
||||
const renderGroup = (items: T[], tabIndexStart: number): TemplateResult => {
|
||||
return html`${items.map((obj, index) => {
|
||||
let desc = undefined;
|
||||
if (this.renderDescription) {
|
||||
desc = this.renderDescription(obj);
|
||||
@ -177,6 +177,7 @@ export class SearchSelect<T> extends AKElement {
|
||||
this.selectedObject = obj;
|
||||
this.open = false;
|
||||
}}
|
||||
tabindex=${index + tabIndexStart}
|
||||
>
|
||||
${desc === undefined
|
||||
? this.renderElement(obj)
|
||||
@ -205,6 +206,7 @@ export class SearchSelect<T> extends AKElement {
|
||||
role="listbox"
|
||||
style="max-height:50vh;overflow-y:auto;"
|
||||
id=${this.dropdownUID}
|
||||
tabindex="0"
|
||||
>
|
||||
${this.blankable
|
||||
? html`
|
||||
@ -216,6 +218,7 @@ export class SearchSelect<T> extends AKElement {
|
||||
this.selectedObject = undefined;
|
||||
this.open = false;
|
||||
}}
|
||||
tabindex="0"
|
||||
>
|
||||
${this.emptyOption}
|
||||
</button>
|
||||
@ -223,17 +226,17 @@ export class SearchSelect<T> extends AKElement {
|
||||
`
|
||||
: html``}
|
||||
${shouldRenderGroups
|
||||
? html`${groupedItems.map(([group, items]) => {
|
||||
? html`${groupedItems.map(([group, items], idx) => {
|
||||
return html`
|
||||
<section class="pf-c-dropdown__group">
|
||||
<h1 class="pf-c-dropdown__group-title">${group}</h1>
|
||||
<ul>
|
||||
${renderGroup(items)}
|
||||
${renderGroup(items, idx)}
|
||||
</ul>
|
||||
</section>
|
||||
`;
|
||||
})}`
|
||||
: html`${renderGroup(groupedItems[0][1])}`}
|
||||
: html`${renderGroup(groupedItems[0][1], 0)}`}
|
||||
</ul>
|
||||
</div>`,
|
||||
this.dropdownContainer,
|
||||
@ -259,6 +262,11 @@ export class SearchSelect<T> extends AKElement {
|
||||
this.renderMenu();
|
||||
}}
|
||||
@blur=${(ev: FocusEvent) => {
|
||||
// For Safari, we get the <ul> element itself here when clicking on one of
|
||||
// it's buttons, as the container has tabindex set
|
||||
if ((ev.relatedTarget as HTMLElement).id === this.dropdownUID) {
|
||||
return;
|
||||
}
|
||||
// Check if we're losing focus to one of our dropdown items, and if such don't blur
|
||||
if (ev.relatedTarget instanceof HTMLButtonElement) {
|
||||
const parentMenu = ev.relatedTarget.closest(
|
||||
|
@ -20,6 +20,7 @@ import AKGlobal from "@goauthentik/common/styles/authentik.css";
|
||||
import PFButton from "@patternfly/patternfly/components/Button/button.css";
|
||||
import PFDropdown from "@patternfly/patternfly/components/Dropdown/dropdown.css";
|
||||
import PFPagination from "@patternfly/patternfly/components/Pagination/pagination.css";
|
||||
import PFSwitch from "@patternfly/patternfly/components/Switch/switch.css";
|
||||
import PFTable from "@patternfly/patternfly/components/Table/table.css";
|
||||
import PFToolbar from "@patternfly/patternfly/components/Toolbar/toolbar.css";
|
||||
import PFBullseye from "@patternfly/patternfly/layouts/Bullseye/bullseye.css";
|
||||
@ -153,6 +154,7 @@ export abstract class Table<T> extends AKElement {
|
||||
PFTable,
|
||||
PFBullseye,
|
||||
PFButton,
|
||||
PFSwitch,
|
||||
PFToolbar,
|
||||
PFDropdown,
|
||||
PFPagination,
|
||||
|
@ -11,7 +11,6 @@ import { ifDefined } from "lit/directives/if-defined.js";
|
||||
import PFContent from "@patternfly/patternfly/components/Content/content.css";
|
||||
import PFPage from "@patternfly/patternfly/components/Page/page.css";
|
||||
import PFSidebar from "@patternfly/patternfly/components/Sidebar/sidebar.css";
|
||||
import PFSwitch from "@patternfly/patternfly/components/Switch/switch.css";
|
||||
|
||||
export abstract class TablePage<T> extends Table<T> {
|
||||
abstract pageTitle(): string;
|
||||
@ -19,7 +18,7 @@ export abstract class TablePage<T> extends Table<T> {
|
||||
abstract pageIcon(): string;
|
||||
|
||||
static get styles(): CSSResult[] {
|
||||
return super.styles.concat(PFPage, PFContent, PFSwitch, PFSidebar);
|
||||
return super.styles.concat(PFPage, PFContent, PFSidebar);
|
||||
}
|
||||
|
||||
renderSidebarBefore(): TemplateResult {
|
||||
|
@ -26,7 +26,7 @@ import "@goauthentik/flow/stages/password/PasswordStage";
|
||||
|
||||
import { t } from "@lingui/macro";
|
||||
|
||||
import { CSSResult, TemplateResult, css, html } from "lit";
|
||||
import { CSSResult, TemplateResult, css, html, render } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { unsafeHTML } from "lit/directives/unsafe-html.js";
|
||||
import { until } from "lit/directives/until.js";
|
||||
@ -458,38 +458,43 @@ export class FlowExecutor extends AKElement implements StageHost {
|
||||
}
|
||||
}
|
||||
|
||||
renderBackgroundOverlay(): TemplateResult {
|
||||
const overlaySVG = html`<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="pf-c-background-image__filter"
|
||||
width="0"
|
||||
height="0"
|
||||
style="display:none;"
|
||||
>
|
||||
<filter id="image_overlay">
|
||||
<feColorMatrix
|
||||
in="SourceGraphic"
|
||||
type="matrix"
|
||||
values="1.3 0 0 0 0 0 1.3 0 0 0 0 0 1.3 0 0 0 0 0 1 0"
|
||||
/>
|
||||
<feComponentTransfer color-interpolation-filters="sRGB" result="duotone">
|
||||
<feFuncR
|
||||
type="table"
|
||||
tableValues="0.086274509803922 0.43921568627451"
|
||||
></feFuncR>
|
||||
<feFuncG
|
||||
type="table"
|
||||
tableValues="0.086274509803922 0.43921568627451"
|
||||
></feFuncG>
|
||||
<feFuncB
|
||||
type="table"
|
||||
tableValues="0.086274509803922 0.43921568627451"
|
||||
></feFuncB>
|
||||
<feFuncA type="table" tableValues="0 1"></feFuncA>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
</svg>`;
|
||||
render(overlaySVG, document.body);
|
||||
return overlaySVG;
|
||||
}
|
||||
|
||||
render(): TemplateResult {
|
||||
return html`<div class="pf-c-background-image">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="pf-c-background-image__filter"
|
||||
width="0"
|
||||
height="0"
|
||||
>
|
||||
<filter id="image_overlay">
|
||||
<feColorMatrix
|
||||
in="SourceGraphic"
|
||||
type="matrix"
|
||||
values="1.3 0 0 0 0 0 1.3 0 0 0 0 0 1.3 0 0 0 0 0 1 0"
|
||||
/>
|
||||
<feComponentTransfer color-interpolation-filters="sRGB" result="duotone">
|
||||
<feFuncR
|
||||
type="table"
|
||||
tableValues="0.086274509803922 0.43921568627451"
|
||||
></feFuncR>
|
||||
<feFuncG
|
||||
type="table"
|
||||
tableValues="0.086274509803922 0.43921568627451"
|
||||
></feFuncG>
|
||||
<feFuncB
|
||||
type="table"
|
||||
tableValues="0.086274509803922 0.43921568627451"
|
||||
></feFuncB>
|
||||
<feFuncA type="table" tableValues="0 1"></feFuncA>
|
||||
</feComponentTransfer>
|
||||
</filter>
|
||||
</svg>
|
||||
</div>
|
||||
return html`<div class="pf-c-background-image">${this.renderBackgroundOverlay()}</div>
|
||||
<div class="pf-c-page__drawer">
|
||||
<div class="pf-c-drawer ${this.inspectorOpen ? "pf-m-expanded" : "pf-m-collapsed"}">
|
||||
<div class="pf-c-drawer__main">
|
||||
|
@ -396,9 +396,9 @@ msgstr "Erweiterte Einstellungen"
|
||||
msgid "Affected model:"
|
||||
msgstr "Betroffenes Modell:"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr "Alarm"
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alarm"
|
||||
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
#~ msgstr "Algorithmus, der zum Signieren der JWT-Token verwendet wird."
|
||||
@ -2366,6 +2366,7 @@ msgstr ""
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr "Ausnahme"
|
||||
|
||||
@ -3171,6 +3172,10 @@ msgstr "Integrationsschlüssel"
|
||||
msgid "Intent"
|
||||
msgstr "Zweck"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
@ -4078,6 +4083,7 @@ msgid "Not you?"
|
||||
msgstr "Nicht Sie?"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr "Hinweis"
|
||||
|
||||
@ -6732,6 +6738,11 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr ""
|
||||
@ -7311,6 +7322,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Warnung"
|
||||
@ -7411,6 +7423,10 @@ msgstr "Bei der Verbindung zu einem LDAP-Server mit TLS werden Zertifikate stand
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr "Bei Verbindung via SSH wird dieses Schlüsselpaar zur Authentifizierung genutzt."
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr "Wenn diese Option aktiviert ist, werden die globalen E-Mail Verbindungseinstellungen benutzt und die unten angegebenen Einstellungen ignoriert"
|
||||
|
@ -378,9 +378,9 @@ msgstr "Advanced settings"
|
||||
msgid "Affected model:"
|
||||
msgstr "Affected model:"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr "Alert"
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alert"
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
@ -2398,6 +2398,7 @@ msgstr "Example SAML attributes"
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr "Exception"
|
||||
|
||||
@ -3219,6 +3220,10 @@ msgstr "Integration key"
|
||||
msgid "Intent"
|
||||
msgstr "Intent"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr "Intercept header authentication"
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr "Internal"
|
||||
@ -4137,6 +4142,7 @@ msgid "Not you?"
|
||||
msgstr "Not you?"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr "Notice"
|
||||
|
||||
@ -6880,6 +6886,11 @@ msgstr "Unknown provider type"
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr "Unknown proxy mode"
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr "Unknown severity"
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr "Unknown type"
|
||||
@ -7467,6 +7478,7 @@ msgstr "Waiting for authentication..."
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Warning"
|
||||
@ -7570,6 +7582,10 @@ msgstr "When connecting to an LDAP Server with TLS, certificates are not checked
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr "When connecting via SSH, this keypair is used for authentication."
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
|
@ -374,9 +374,9 @@ msgstr "Configuraciones avanzadas"
|
||||
msgid "Affected model:"
|
||||
msgstr "Modelo afectado:"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr "Alerta"
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alerta"
|
||||
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
#~ msgstr "Algoritmo utilizado para firmar los tokens JWT."
|
||||
@ -2342,6 +2342,7 @@ msgstr ""
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr "Excepción"
|
||||
|
||||
@ -3145,6 +3146,10 @@ msgstr "Clave de integración"
|
||||
msgid "Intent"
|
||||
msgstr "Intención"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
@ -4054,6 +4059,7 @@ msgid "Not you?"
|
||||
msgstr "¿No eres tú?"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr "Notificación"
|
||||
|
||||
@ -6708,6 +6714,11 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr ""
|
||||
@ -7287,6 +7298,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Aviso"
|
||||
@ -7387,6 +7399,10 @@ msgstr "Al conectarse a un servidor LDAP con TLS, los certificados no se comprue
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr "Cuando se conecta a través de SSH, este par de claves se usa para la autenticación."
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr "Cuando se habilita, se utilizará la configuración global de conexión de correo electrónico y se ignorarán las configuraciones de conexión que se indican a continuación"
|
||||
|
@ -379,9 +379,9 @@ msgstr "Paramètres avancés"
|
||||
msgid "Affected model:"
|
||||
msgstr "Modèle affecté :"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr "Alerte"
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alerte"
|
||||
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
#~ msgstr "Algorithme de signature utilisé pour les jetons JWT"
|
||||
@ -2345,6 +2345,7 @@ msgstr ""
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr "Exception"
|
||||
|
||||
@ -3148,6 +3149,10 @@ msgstr "Clé d'intégration"
|
||||
msgid "Intent"
|
||||
msgstr "Intention"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
@ -4055,6 +4060,7 @@ msgid "Not you?"
|
||||
msgstr "Pas vous ?"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr "Note"
|
||||
|
||||
@ -6699,6 +6705,11 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr ""
|
||||
@ -7278,6 +7289,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Avertissement"
|
||||
@ -7378,6 +7390,10 @@ msgstr ""
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr "Si activé, les paramètres globaux de connexion email seront utilisés et les paramètres de connexion ci-dessous seront ignorés."
|
||||
|
@ -378,9 +378,9 @@ msgstr "Zaawansowane ustawienia"
|
||||
msgid "Affected model:"
|
||||
msgstr "Model, którego dotyczy problem:"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr "Alert"
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alert"
|
||||
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
#~ msgstr "Algorytm używany do podpisywania tokenów JWT."
|
||||
@ -2348,6 +2348,7 @@ msgstr ""
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr "Wyjątek"
|
||||
|
||||
@ -3153,6 +3154,10 @@ msgstr "Klucz integracji"
|
||||
msgid "Intent"
|
||||
msgstr "Przeznaczenie"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
@ -4062,6 +4067,7 @@ msgid "Not you?"
|
||||
msgstr "Nie ty?"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr "Uwaga"
|
||||
|
||||
@ -6718,6 +6724,11 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr ""
|
||||
@ -7297,6 +7308,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Ostrzeżenie"
|
||||
@ -7399,6 +7411,10 @@ msgstr "Podczas łączenia się z serwerem LDAP za pomocą TLS, certyfikaty nie
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr "Podczas łączenia przez SSH ta para kluczy jest używana do uwierzytelniania."
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr "Po włączeniu będą używane globalne ustawienia połączenia poczty e-mail, a poniższe ustawienia połączenia będą ignorowane."
|
||||
|
@ -374,9 +374,9 @@ msgstr ""
|
||||
msgid "Affected model:"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr ""
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/providers/oauth2/OAuth2ProviderForm.ts
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
@ -2384,6 +2384,7 @@ msgstr ""
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr ""
|
||||
|
||||
@ -3203,6 +3204,10 @@ msgstr ""
|
||||
msgid "Intent"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
@ -4119,6 +4124,7 @@ msgid "Not you?"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr ""
|
||||
|
||||
@ -6850,6 +6856,11 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr ""
|
||||
@ -7437,6 +7448,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr ""
|
||||
@ -7538,6 +7550,10 @@ msgstr ""
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr ""
|
||||
|
@ -374,9 +374,9 @@ msgstr "Gelişmiş ayarlar"
|
||||
msgid "Affected model:"
|
||||
msgstr "Etkilenen model:"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr "Alarm"
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr "Alarm"
|
||||
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
#~ msgstr "JWT Belirteçlerini imzalamak için kullanılan algoritma."
|
||||
@ -2342,6 +2342,7 @@ msgstr ""
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr "Hata"
|
||||
|
||||
@ -3145,6 +3146,10 @@ msgstr "Entegrasyon anahtarı"
|
||||
msgid "Intent"
|
||||
msgstr "Niyet"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
@ -4054,6 +4059,7 @@ msgid "Not you?"
|
||||
msgstr "Sen değil mi?"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr "Uyarı"
|
||||
|
||||
@ -6708,6 +6714,11 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr ""
|
||||
@ -7287,6 +7298,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "Uyarı"
|
||||
@ -7387,6 +7399,10 @@ msgstr "TLS ile bir LDAP Sunucusuna bağlanırken, sertifikalar varsayılan olar
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr "SSH üzerinden bağlanırken, bu anahtar çifti kimlik doğrulama için kullanılır."
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr "Etkinleştirildiğinde, genel E-posta bağlantısı ayarları kullanılır ve aşağıdaki bağlantı ayarları yoksayılır."
|
||||
|
@ -380,9 +380,9 @@ msgstr "高级设置"
|
||||
msgid "Affected model:"
|
||||
msgstr "受影响的模型:"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr "注意"
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr "注意"
|
||||
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
#~ msgstr "用于签名 JWT 令牌的算法。"
|
||||
@ -2350,6 +2350,7 @@ msgstr ""
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr "异常"
|
||||
|
||||
@ -3153,6 +3154,10 @@ msgstr "集成密钥"
|
||||
msgid "Intent"
|
||||
msgstr "意图"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
@ -4062,6 +4067,7 @@ msgid "Not you?"
|
||||
msgstr "不是您?"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr "通知"
|
||||
|
||||
@ -6716,6 +6722,11 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr ""
|
||||
@ -7295,6 +7306,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "警告"
|
||||
@ -7397,6 +7409,10 @@ msgstr "使用 TLS 连接到 LDAP 服务器时,默认情况下不检查证书
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr "通过 SSH 连接时,此密钥对用于身份验证。"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr "启用后,将使用全局电子邮件连接设置,下面的连接设置将被忽略。"
|
||||
|
@ -380,9 +380,9 @@ msgstr "高级设置"
|
||||
msgid "Affected model:"
|
||||
msgstr "受影响的模型:"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr "注意"
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr "注意"
|
||||
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
#~ msgstr "用于对JWT令牌进行签名的算法。"
|
||||
@ -2350,6 +2350,7 @@ msgstr ""
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr "例外"
|
||||
|
||||
@ -3153,6 +3154,10 @@ msgstr "集成密钥"
|
||||
msgid "Intent"
|
||||
msgstr "意图"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
@ -4062,6 +4067,7 @@ msgid "Not you?"
|
||||
msgstr "不是你?"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr "注意"
|
||||
|
||||
@ -6716,6 +6722,11 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr ""
|
||||
@ -7295,6 +7306,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "警告"
|
||||
@ -7397,6 +7409,10 @@ msgstr "使用 TLS 连接到 LDAP 服务器时,默认情况下不检查证书
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr "通过 SSH 连接时,此密钥对用于身份验证。"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr "启用后,将使用全局电子邮件连接设置,而下面的连接设置将被忽略。"
|
||||
|
@ -380,9 +380,9 @@ msgstr "高级设置"
|
||||
msgid "Affected model:"
|
||||
msgstr "受影响的模型:"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#~ msgid "Alert"
|
||||
#~ msgstr "注意"
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Alert"
|
||||
msgstr "注意"
|
||||
|
||||
#~ msgid "Algorithm used to sign the JWT Tokens."
|
||||
#~ msgstr "用于对JWT令牌进行签名的算法。"
|
||||
@ -2350,6 +2350,7 @@ msgstr ""
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
#: src/admin/events/EventInfo.ts
|
||||
msgid "Exception"
|
||||
msgstr "例外"
|
||||
|
||||
@ -3153,6 +3154,10 @@ msgstr "集成密钥"
|
||||
msgid "Intent"
|
||||
msgstr "意图"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "Intercept header authentication"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/blueprints/BlueprintForm.ts
|
||||
msgid "Internal"
|
||||
msgstr ""
|
||||
@ -4062,6 +4067,7 @@ msgid "Not you?"
|
||||
msgstr "不是你?"
|
||||
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Notice"
|
||||
msgstr "注意"
|
||||
|
||||
@ -6716,6 +6722,11 @@ msgstr ""
|
||||
msgid "Unknown proxy mode"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
msgid "Unknown severity"
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/outposts/OutpostListPage.ts
|
||||
msgid "Unknown type"
|
||||
msgstr ""
|
||||
@ -7295,6 +7306,7 @@ msgstr ""
|
||||
#: src/admin/admin-overview/cards/SystemStatusCard.ts
|
||||
#: src/admin/blueprints/BlueprintListPage.ts
|
||||
#: src/admin/events/RuleForm.ts
|
||||
#: src/admin/events/RuleListPage.ts
|
||||
#: src/admin/system-tasks/SystemTaskListPage.ts
|
||||
msgid "Warning"
|
||||
msgstr "警告"
|
||||
@ -7397,6 +7409,10 @@ msgstr "使用 TLS 连接到 LDAP 服务器时,默认情况下不检查证书
|
||||
msgid "When connecting via SSH, this keypair is used for authentication."
|
||||
msgstr "通过 SSH 连接时,此密钥对用于身份验证。"
|
||||
|
||||
#: src/admin/providers/proxy/ProxyProviderForm.ts
|
||||
msgid "When enabled, authentik will intercept the Authorization header to authenticate the request."
|
||||
msgstr ""
|
||||
|
||||
#: src/admin/stages/email/EmailStageForm.ts
|
||||
msgid "When enabled, global Email connection settings will be used and connection settings below will be ignored."
|
||||
msgstr "启用后,将使用全局电子邮件连接设置,而下面的连接设置将被忽略。"
|
||||
|
@ -8,4 +8,4 @@ The following stages are supported:
|
||||
|
||||
- [**identification**](../stages/identification/)
|
||||
- [**password**](../stages/password/)
|
||||
- [**authenticator_validate**](../stages/authenticator_validate/) (currently only DUO devices are supported)
|
||||
- [**authenticator_validate**](../stages/authenticator_validate/)
|
||||
|
@ -53,3 +53,32 @@ Requires authentik 2022.6
|
||||
:::
|
||||
|
||||
To only verify the validity of a users' phone number, without saving it in an easily accessible way, you can enable this option. Phone numbers from devices enrolled through this stage will only have their hashed phone number saved. These devices can also not be used with the [Authenticator validation](../authenticator_validate/) stage.
|
||||
|
||||
## Limiting phone numbers
|
||||
|
||||
To limit phone numbers (for example to a specific region code), you can create an expression policy to validate the phone number, and use a prompt stage for input.
|
||||
|
||||
### Expression policy
|
||||
|
||||
Create an expression policy to check the phone number:
|
||||
|
||||
```python
|
||||
# Trim all whitespace in and around the user input
|
||||
phone_number = regex_replace(request.context["prompt_data"]["phone"], r'\s+', '')
|
||||
|
||||
# Only allow a specific region code
|
||||
if phone_number.startswith("+1234"):
|
||||
return True
|
||||
ak_message("Invalid phone number or missing region code")
|
||||
return False
|
||||
```
|
||||
|
||||
### Prompt stage
|
||||
|
||||
Create a text prompt field with the _field key_ set to `phone`. Make sure it is selected as a required field.
|
||||
|
||||
Create a prompt stage with the phone field you created above, and select the expression policy created above as validation policy.
|
||||
|
||||
### Flow
|
||||
|
||||
Create a new flow to enroll SMS devices. Bind the prompt stage created above as first stage, and create/bind a _SMS Authenticator Setup Stage_, and bind it to the flow as second stage. This stage will see the `phone` field in the flow's context's `prompt_data`, and not prompt the user for a phone number.
|
||||
|
@ -26,6 +26,8 @@ AUTHENTIK_TAG=gh-next
|
||||
AUTHENTIK_OUTPOSTS__CONTAINER_IMAGE_BASE=ghcr.io/goauthentik/dev-%(type)s:gh-%(build_hash)s
|
||||
```
|
||||
|
||||
The beta image is amd64 only. For arm64 platforms, append `-arm64` to the tag name.
|
||||
|
||||
Afterwards, run the upgrade commands from the latest release notes.
|
||||
|
||||
</TabItem>
|
||||
@ -43,6 +45,8 @@ image:
|
||||
pullPolicy: Always
|
||||
```
|
||||
|
||||
The beta image is amd64 only. For arm64 platforms, append `-arm64` to the tag name.
|
||||
|
||||
Afterwards, run the upgrade commands from the latest release notes.
|
||||
|
||||
</TabItem>
|
||||
|
@ -11,7 +11,7 @@ title: Generic Setup
|
||||
2. Create a new group for LDAP searches. In this example `ldapsearch`. Add the `ldapservice` user to this new group.
|
||||
|
||||
:::info
|
||||
Note: The `default-authentication-flow` validates MFA by default, and currently only Duo-based MFA devices are supported by LDAP. If you plan to use only dedicated service accounts to bind to LDAP, then you can use the default flow and skip the extra steps below and continue at [Create LDAP Provider](#create-ldap-provider)
|
||||
Note: The `default-authentication-flow` validates MFA by default, and currently everything but SMS-based devices are supported by LDAP. If you plan to use only dedicated service accounts to bind to LDAP, or don't use SMS-based authenticators, then you can use the default flow and skip the extra steps below and continue at [Create LDAP Provider](#create-ldap-provider)
|
||||
:::
|
||||
|
||||
### LDAP Flow
|
||||
|
@ -78,6 +78,10 @@ The following stages are supported:
|
||||
|
||||
SMS-based authenticators are not supported as they require a code to be sent from authentik, which is not possible during the bind.
|
||||
|
||||
- [User Logout](../../flow/stages/user_logout.md)
|
||||
- [User Login](../../flow/stages/user_login.md)
|
||||
- [Deny](../../flow/stages/deny.md)
|
||||
|
||||
#### Direct bind
|
||||
|
||||
In this mode, the outpost will always execute the configured flow when a new bind request is received.
|
||||
|
@ -93,6 +93,28 @@ image:
|
||||
- web/elements: fix pagination page button colours in dark mode
|
||||
- web/elements: use correct Action Label for user related events
|
||||
|
||||
## Fixed in 2023.1.1
|
||||
|
||||
- add tests to prevent empty SAN
|
||||
- blueprints: fix OOB email field overwriting user settings email field
|
||||
- ci: build beta for amd64 and arm64 (#4468)
|
||||
- crypto: ensure we don't generate an empty SAN certificate
|
||||
- crypto: fallback when no SAN values are given
|
||||
- outposts/ldap: fix queries filtering objectClass with non-lowercase values
|
||||
- outposts/proxy: fix panic due to IsSet misbehaving
|
||||
- providers/oauth2: more x5c and ecdsa x/y tests (#4463)
|
||||
- providers/proxy: fix issuer for embedded outpost (#4480)
|
||||
- sources/ldap: add e2e LDAP source tests (#4462)
|
||||
- stages: always use get_pending_user instead of getting context user
|
||||
- stages/authenticator_sms: fix code not being sent when phone_number is in context
|
||||
- web/admin: don't enable execution logging by default
|
||||
- web/admin: improve display of rule severity
|
||||
- web/admin: improve display of system task exception
|
||||
- web/admin: link group of notification rule
|
||||
- web/elements: fix pf-c-switch not rendering correctly in pure tables
|
||||
- web/elements: fix SearchSelect not working on safari
|
||||
- web/flows: fix flow executor background overlay in safari
|
||||
|
||||
## API Changes
|
||||
|
||||
#### What's Deleted
|
||||
|
@ -52,7 +52,7 @@ import TabItem from "@theme/TabItem";
|
||||
OPENID_AUTHORIZATION_ENDPOINT: https://authentik.company/application/o/authorize/
|
||||
OPENID_CLIENT_ID: # client ID from above
|
||||
OPENID_ISSUER: https://authentik.company/application/o/*Slug of the application from above*/
|
||||
OPENID_JWKS_ENDPOINT: https://authentik.company/application/o/*Slug of the application from above*/jwks/
|
||||
OPENID_JWKS_ENDPOINT: https://authentik.company/application/o/*Slug of the application from above*/jwks/?exclude_x5
|
||||
OPENID_REDIRECT_URI: https://guacamole.company/ # This must match the redirect URI above
|
||||
```
|
||||
|
||||
@ -64,7 +64,7 @@ OPENID_REDIRECT_URI: https://guacamole.company/ # This must match the redirect U
|
||||
openid-authorization-endpoint=https://authentik.company/application/o/authorize/
|
||||
openid-client-id=# client ID from above
|
||||
openid-issuer=https://authentik.company/application/o/*Slug of the application from above*/
|
||||
openid-jwks-endpoint=https://authentik.company/application/o/*Slug of the application from above*/jwks/
|
||||
openid-jwks-endpoint=https://authentik.company/application/o/*Slug of the application from above*/jwks/?exclude_x5
|
||||
openid-redirect-uri=https://guacamole.company/ # This must match the redirect URI above
|
||||
```
|
||||
|
||||
|
@ -220,13 +220,14 @@ module.exports = {
|
||||
description: "Release notes for recent authentik versions",
|
||||
},
|
||||
items: [
|
||||
"releases/2023/v2023.1",
|
||||
"releases/2022/v2022.12",
|
||||
"releases/2022/v2022.11",
|
||||
"releases/2022/v2022.10",
|
||||
{
|
||||
type: "category",
|
||||
label: "Previous versions",
|
||||
items: [
|
||||
"releases/2022/v2022.10",
|
||||
"releases/2022/v2022.9",
|
||||
"releases/2022/v2022.8",
|
||||
"releases/2022/v2022.7",
|
||||
|
Reference in New Issue
Block a user