Compare commits

..

162 Commits

Author SHA1 Message Date
86c1d60093 web: Flesh out static config exports. 2025-04-10 17:16:18 +02:00
e5e53f034e core: bump multidict from 6.2.0 to v6.4.2 (#13971) 2025-04-10 10:24:19 -04:00
71b87127d1 core: bump msgraph-sdk from 1.26.0 to v1.27.0 (#13970) 2025-04-10 10:23:42 -04:00
d5d67fe22d core: bump boto3 from 1.37.30 to v1.37.31 (#13968) 2025-04-10 10:23:18 -04:00
5d2685341d sources/ldap: lookup group memberships from user attribute (#12661)
* sources/ldap: add support for group lookups from user

* sources/ldap: implement working membership lookups

* sources/ldap: add schema changes

* sources/ldap: add group membership toggle ui element

* sources/ldap: lint changed files

* website/docs: add note about lookups to AD docs

* Update website/docs/users-sources/sources/directory-sync/active-directory/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Amélie Krejčí <amelie@krejci.vip>

* website/docs: simplify wording of attribute documentation

Follows suggestions from @jorhett

* sources/ldap: add missing spaces in docstrings

Follows suggestions from @jorhett

* Add a test for memberof attribute

* sources/ldap: implement test

* format

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* re-migrate

Signed-off-by: Jens Langhammer <jens@goauthentik.io>

* revert website changes in favor of #13966

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

* update frontend help text

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

---------

Signed-off-by: Amélie Krejčí <amelie@krejci.vip>
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Co-authored-by: Shawn Weeks <sweeks@weeksconsulting.us>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Jo Rhett <geek@jorhett.com>
Co-authored-by: Jens Langhammer <jens@goauthentik.io>
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-10 14:37:38 +02:00
f1ac4ff9c9 translate: Updates for file web/xliff/en.xlf in it (#13956)
Translate web/xliff/en.xlf in it

100% translated source file: 'web/xliff/en.xlf'
on 'it'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-04-10 13:40:33 +02:00
79f4c66286 translate: Updates for file locale/en/LC_MESSAGES/django.po in it (#13957)
Translate locale/en/LC_MESSAGES/django.po in it

100% translated source file: 'locale/en/LC_MESSAGES/django.po'
on 'it'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-04-10 13:40:12 +02:00
1f82094c0b core: bump astral-sh/uv from 0.6.13 to 0.6.14 (#13964)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-10 13:36:27 +02:00
35440acba3 core: bump django from 5.0.13 to 5.0.14 (#13954)
bump django to 5.0.14
2025-04-10 12:55:27 +02:00
eca9901704 website/docs: Remove enterprise badge from Fleet integration (#13963)
website/docs: Remove enterprise badge.
2025-04-10 08:29:39 +01:00
6ddd5a3d5f website/integrations: add Homarr (#13818)
* Adding Homarr integration details

* Fixing typo in homarr doc

* Lint fix

* Update website/integrations/services/homarr/index.md

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Nate Fonseka <882236+nfons@users.noreply.github.com>

* Update website/integrations/services/homarr/index.md

Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Nate Fonseka <882236+nfons@users.noreply.github.com>

* Update website/integrations/services/homarr/index.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

---------

Signed-off-by: Nate Fonseka <882236+nfons@users.noreply.github.com>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: nfonseka <nfonseka@rxsense.com>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-04-10 08:15:15 +01:00
5664e62eca website/integration: update harbor integration document (#13816)
* Updates harbor integration doc to new template and fixes reported issue

* typo

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
2025-04-09 18:23:52 -05:00
1403f17d62 Fix redirect URL in wordpress integration guide (#13955)
Update wordpress integration guide to fix redirect URL

Signed-off-by: virtualboys <emanmomot@gmail.com>
2025-04-09 17:10:33 -05:00
1ac8989e81 lifecycle/aws: bump aws-cdk-lib (#13953) 2025-04-09 18:24:45 +00:00
b0a1db77e3 core: bump protobuf from 5.29.4 to v6.30.2 (#13950) 2025-04-09 18:01:53 +00:00
46da4cb59e core: bump pyasn1-modules from 0.4.1 to v0.4.2 (#13951) 2025-04-09 18:01:16 +00:00
154df5cdf7 core: bump microsoft-kiota-authentication-azure from 1.9.2 to v1.9.3 (#13948) 2025-04-09 18:00:55 +00:00
5b889456f6 core: bump microsoft-kiota-http from 1.9.2 to v1.9.3 (#13949) 2025-04-09 18:00:20 +00:00
3eaed82c48 core: bump trio-websocket from 0.11.1 to v0.12.2 (#13934) 2025-04-09 17:49:55 +00:00
feaf9d8bc9 core: bump msgraph-core from 1.3.1 to v1.3.3 (#13900) 2025-04-09 17:48:08 +00:00
2899668ae2 core: bump jsii from 1.109.0 to v1.111.0 (#13886) 2025-04-09 17:46:29 +00:00
4c25e1bb24 core: bump setuptools from 72.1.0 to v78.1.0 (#13928) 2025-04-09 19:29:15 +02:00
464ff3f5b1 core: bump kombu from 5.3.7 to v5.5.2 (#13888) 2025-04-09 19:27:57 +02:00
22eb5f56f1 core: bump msgpack from 1.0.8 to v1.1.0 (#13899) 2025-04-09 19:27:27 +02:00
7e48e87f49 core: bump msgraph-sdk from 1.24.0 to v1.26.0 (#13901) 2025-04-09 19:26:52 +02:00
8ce12f7850 core: bump proto-plus from 1.24.0 to v1.26.1 (#13910) 2025-04-09 19:26:37 +02:00
2514baabeb core: bump protobuf from 5.27.2 to v5.29.4 (#13911) 2025-04-09 19:26:16 +02:00
945930a507 core: bump pydantic from 2.10.6 to v2.11.3 (#13914) 2025-04-09 19:25:51 +02:00
537a80ad97 core: bump rich from 13.7.1 to v14.0.0 (#13922) 2025-04-09 19:25:26 +02:00
5c993e23fe core: bump twisted from 24.7.0 to v24.11.0 (#13936) 2025-04-09 19:25:02 +02:00
eb2db18494 core: bump watchfiles from 0.22.0 to v1.0.5 (#13941) 2025-04-09 19:24:40 +02:00
12a46a8426 core: bump typing-extensions from 4.12.2 to v4.13.1 (#13937) 2025-04-09 19:24:25 +02:00
4a1213310a core: bump multidict from 6.0.5 to v6.2.0 (#13902) 2025-04-09 19:24:11 +02:00
84c2097148 core: bump sentry-sdk from 2.22.0 to v2.25.1 (#13927) 2025-04-09 19:23:56 +02:00
c05dedc573 core: bump rpds-py from 0.19.1 to v0.24.0 (#13923) 2025-04-09 19:23:38 +02:00
18c197e75b core: bump propcache from 0.2.0 to v0.3.1 (#13909) 2025-04-09 19:23:29 +02:00
0c26a0bce2 core: bump pbr from 6.0.0 to v6.1.1 (#13905) 2025-04-09 19:23:17 +02:00
5fd6a4cead core: bump golang.org/x/sync from 0.12.0 to 0.13.0 (#13787)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 17:22:55 +00:00
51fb1bd8e7 core: bump ua-parser-builtins from 0.18.0 to v0.18.0.post1 (#13939) 2025-04-09 19:21:54 +02:00
4a30f87a42 core: bump msal from 1.30.0 to v1.32.0 (#13897) 2025-04-09 19:21:42 +02:00
8e6b6ede30 core: bump msal-extensions from 1.2.0 to v1.3.1 (#13898) 2025-04-09 19:21:33 +02:00
af30c2a68e core: bump prometheus-client from 0.20.0 to v0.21.1 (#13907) 2025-04-09 19:21:23 +02:00
9b65627a3e core: bump jsonschema-specifications from 2023.12.1 to v2024.10.1 (#13887) 2025-04-09 19:21:13 +02:00
4bad91c901 core: bump markupsafe from 2.1.5 to v3.0.2 (#13890) 2025-04-09 19:21:01 +02:00
f3c479d077 core: bump stevedore from 5.2.0 to v5.4.1 (#13932) 2025-04-09 19:20:47 +02:00
b024df9903 core: bump zope-interface from 6.4.post2 to v7.2 (#13946) 2025-04-09 19:20:30 +02:00
f6a6458088 core: bump websockets from 12.0 to v15.0.1 (#13942) 2025-04-09 19:18:14 +02:00
f0dc0e8900 core: bump platformdirs from 4.2.2 to v4.3.7 (#13906) 2025-04-09 19:17:21 +02:00
79e89b0376 core: bump selenium from 4.29.0 to v4.31.0 (#13926) 2025-04-09 19:17:11 +02:00
4cc7d91379 core: bump six from 1.16.0 to v1.17.0 (#13929) 2025-04-09 19:17:00 +02:00
245909e31a core: bump hpack from 4.0.0 to v4.1.0 (#13878) 2025-04-09 19:16:51 +02:00
997a1ddb3d core: bump iniconfig from 2.0.0 to v2.1.0 (#13885) 2025-04-09 19:16:34 +02:00
42335a60bf core: bump hyperframe from 6.0.1 to v6.1.0 (#13882) 2025-04-09 19:16:20 +02:00
fc539332e1 core: bump uvloop from 0.19.0 to v0.21.0 (#13940) 2025-04-09 19:16:05 +02:00
d9efb02078 core: bump httpx from 0.27.0 to v0.28.1 (#13880) 2025-04-09 19:15:53 +02:00
6212250e19 core: bump importlib-resources from 6.4.0 to v6.5.2 (#13884) 2025-04-09 19:15:40 +02:00
c18beefc8f core: bump zipp from 3.20.2 to v3.21.0 (#13945) 2025-04-09 19:15:30 +02:00
f23da6e402 core: bump trio from 0.26.0 to v0.29.0 (#13933) 2025-04-09 19:14:56 +02:00
e934b246c8 core: bump deprecated from 1.2.14 to v1.2.18 (#13866) 2025-04-09 19:14:29 +02:00
ead684a410 core: bump wrapt from 1.16.0 to v1.17.2 (#13943) 2025-04-09 19:14:04 +02:00
d782aadab7 core: bump h2 from 4.1.0 to v4.2.0 (#13877) 2025-04-09 19:13:50 +02:00
4ac6f83aea core: bump yarl from 1.17.2 to v1.19.0 (#13944) 2025-04-09 19:13:38 +02:00
6281d36a69 core: bump django-storages from 1.14.5 to v1.14.6 (#13869) 2025-04-09 17:10:57 +00:00
8129ad4ec0 core: bump github.com/coreos/go-oidc/v3 from 3.13.0 to 3.14.1 (#13772)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 19:01:47 +02:00
24eea415b2 core: bump golang.org/x/oauth2 from 0.28.0 to 0.29.0 (#13788)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 19:00:38 +02:00
a615ce8e95 web: bump API Client version (#13798)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
2025-04-09 18:59:59 +02:00
5b275cf7fb core: bump goauthentik.io/api/v3 from 3.2025023.4 to 3.2025024.1 (#13833)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 18:59:39 +02:00
d6e91c119f core, web: update translations (#13832)
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2025-04-09 18:59:17 +02:00
7841e47e74 core: bump celery from 5.4.0 to v5.5.1 (#13858) 2025-04-09 18:58:06 +02:00
ad2a4bea3e core: bump ruff from 0.9.10 to v0.11.4 (#13924) 2025-04-09 16:53:44 +00:00
a554c085c1 core: bump tzdata from 2024.1 to v2025.2 (#13938) 2025-04-09 16:20:39 +00:00
ff0d978754 core: bump std-uritemplate from 2.0.2 to v2.0.3 (#13931) 2025-04-09 16:19:54 +00:00
de48e62819 core: bump twilio from 9.5.0 to v9.5.2 (#13935) 2025-04-09 16:19:18 +00:00
e50e995d2f core: bump sqlparse from 0.5.1 to v0.5.3 (#13930) 2025-04-09 16:18:57 +00:00
3bf4156cb3 core: bump referencing from 0.35.1 to v0.36.2 (#13921) 2025-04-09 16:17:31 +00:00
89990facf5 core: bump pytest-django from 4.10.0 to v4.11.1 (#13917) 2025-04-09 16:17:26 +00:00
48545950ed core: bump redis from 5.0.7 to v5.2.1 (#13920) 2025-04-09 16:17:12 +00:00
0544aa5fae core: bump pyparsing from 3.1.2 to v3.2.3 (#13916) 2025-04-09 16:16:48 +00:00
5d69455b87 core: bump pytz from 2024.1 to v2025.2 (#13919) 2025-04-09 16:16:24 +00:00
3d291cf4da core: bump python-dotenv from 1.0.1 to v1.1.0 (#13918) 2025-04-09 16:15:36 +00:00
44d7c42dc7 core: bump pyasn1 from 0.6.0 to v0.6.1 (#13912) 2025-04-09 16:15:22 +00:00
4ea4e925e3 core: bump pygments from 2.18.0 to v2.19.1 (#13915) 2025-04-09 16:14:57 +00:00
169172c85f core: bump prompt-toolkit from 3.0.47 to v3.0.50 (#13908) 2025-04-09 16:14:52 +00:00
adea637fa4 core: bump pyasn1-modules from 0.4.0 to v0.4.1 (#13913) 2025-04-09 16:14:38 +00:00
0231277d9c core: bump opentelemetry-api from 1.31.0 to v1.31.1 (#13903) 2025-04-09 16:13:12 +00:00
45643ed1f6 core: bump microsoft-kiota-serialization-form from 1.9.2 to v1.9.3 (#13893) 2025-04-09 16:12:37 +00:00
3823d56dbd core: bump orjson from 3.10.6 to v3.10.16 (#13904) 2025-04-09 16:12:22 +00:00
43cfd59ac0 core: bump microsoft-kiota-serialization-text from 1.9.2 to v1.9.3 (#13896) 2025-04-09 16:11:24 +00:00
c8555bbf59 core: bump microsoft-kiota-serialization-json from 1.9.2 to v1.9.3 (#13894) 2025-04-09 16:11:07 +00:00
a4251a3410 core: bump microsoft-kiota-serialization-multipart from 1.9.2 to v1.9.3 (#13895) 2025-04-09 16:10:33 +00:00
50985f9b0b core: bump lxml from 5.3.1 to v5.3.2 (#13889) 2025-04-09 16:08:51 +00:00
9ec24528d4 core: bump maxminddb from 2.6.2 to v2.6.3 (#13891) 2025-04-09 16:08:41 +00:00
5eac38c0cc core: bump humanize from 4.10.0 to v4.12.2 (#13881) 2025-04-09 16:08:36 +00:00
010df0c31c core: bump httpcore from 1.0.5 to v1.0.7 (#13879) 2025-04-09 16:08:18 +00:00
7ba858eff3 core: bump django-pgactivity from 1.4.1 to v1.7.1 (#13868) 2025-04-09 16:08:00 +00:00
817d2d5ff8 core: bump googleapis-common-protos from 1.63.2 to v1.69.2 (#13876) 2025-04-09 16:07:37 +00:00
70e34e03b4 core: bump dnspython from 2.6.1 to v2.7.0 (#13870) 2025-04-09 16:07:18 +00:00
d61f9f6d57 core: bump google-api-core from 2.19.1 to v2.24.2 (#13873) 2025-04-09 16:07:03 +00:00
bdf81706b8 core: bump duo-client from 5.4.0 to v5.5.0 (#13871) 2025-04-09 16:06:47 +00:00
7b56602fc9 core: bump idna from 3.7 to v3.10 (#13883) 2025-04-09 16:06:32 +00:00
7c6e25a996 core: bump google-api-python-client from 2.164.0 to v2.166.0 (#13874) 2025-04-09 16:06:15 +00:00
0eeaeaf1ff core: bump google-auth from 2.32.0 to v2.38.0 (#13875) 2025-04-09 16:06:03 +00:00
9ce4337b11 core: bump coverage from 7.6.12 to v7.8.0 (#13864) 2025-04-09 16:05:37 +00:00
c6a3c7371c core: bump frozenlist from 1.4.1 to v1.5.0 (#13872) 2025-04-09 16:05:21 +00:00
42a7cf10f2 core: bump decorator from 5.1.1 to v5.2.1 (#13865) 2025-04-09 16:04:55 +00:00
bb4f7b1193 core: bump click from 8.1.7 to v8.1.8 (#13863) 2025-04-09 16:04:14 +00:00
3eecfb835b core: bump charset-normalizer from 3.3.2 to v3.4.1 (#13862) 2025-04-09 16:02:41 +00:00
92ab856bd3 core: bump channels from 4.2.0 to v4.2.2 (#13861) 2025-04-09 16:01:28 +00:00
178549a756 core: bump cffi from 1.16.0 to v1.17.1 (#13860) 2025-04-09 15:59:19 +00:00
67d178aa11 core: bump certifi from 2024.7.4 to v2025.1.31 (#13859) 2025-04-09 15:56:20 +00:00
ef53abace9 core: bump cattrs from 24.1.2 to v24.1.3 (#13857) 2025-04-09 15:46:55 +00:00
5effb3a0f6 core: bump cachetools from 5.4.0 to v5.5.2 (#13856) 2025-04-09 15:43:53 +00:00
3a37916a8f core: bump boto3 from 1.34.150 to v1.37.30 (#13854) 2025-04-09 15:36:10 +00:00
428d5ac9cf core: bump attrs from 23.2.0 to 25.3.0 (#13846) 2025-04-09 17:33:00 +02:00
7b4037fdda core: bump anyio from 4.4.0 to 4.9.0 (#13845) 2025-04-09 17:32:28 +02:00
2c7bbcc27b core: bump billiard from 4.2.0 to v4.2.1 (#13853) 2025-04-09 15:19:45 +00:00
19fb24de99 core: bump azure-core from 1.30.2 to 1.33.0 (#13850) 2025-04-09 15:18:54 +00:00
2709702896 core: bump bcrypt from 4.2.0 to v4.3.0 (#13852) 2025-04-09 15:18:39 +00:00
7d0d5a7dc2 core: bump azure-identity from 1.17.1 to 1.21.0 (#13851) 2025-04-09 15:17:46 +00:00
6a04a2ca69 core: bump automat from 22.10.0 to 24.8.1 (#13848) 2025-04-09 15:15:01 +00:00
ea561c9da6 core: bump amqp from 5.2.0 to 5.3.1 (#13844) 2025-04-09 15:08:00 +00:00
9b9c55f17c core: bump aiosignal from 1.3.1 to 1.3.2 (#13843) 2025-04-09 15:07:22 +00:00
bd5e78bd44 core: bump aiohttp-retry from 2.8.3 to 2.9.1 (#13842) 2025-04-09 15:07:10 +00:00
ab98028022 core: bump aiohttp from 3.10.11 to 3.11.16 (#13841) 2025-04-09 15:03:36 +00:00
813ff64ba1 core: bump autobahn from 23.6.2 to 24.4.2 (#13847) 2025-04-09 15:02:57 +00:00
c99e742214 core: bump aiohappyeyeballs from 2.3.5 to 2.6.1 (#13840) 2025-04-09 17:00:49 +02:00
dac6ad3cd6 core: bump github.com/prometheus/client_golang from 1.21.1 to 1.22.0 (#13834)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-09 15:48:58 +02:00
e4d2a53ccc release: 2025.2.4 (#13830)
* release: 2025.2.4

* bump version in uv.lock
2025-04-08 19:16:00 +00:00
3b6775fd9c website/integrations: rename Hoarder to Karakeep (#13789)
* Hoarder renamed to karakeep

The Hoarder app has been renamed to Karakeep recently. https://www.reddit.com/r/selfhosted/comments/1js667o/hoarder_is_rebranding_to_karakeep/

Signed-off-by: petrsimunek <49954958+petrsimunek@users.noreply.github.com>

* folder hoarder renamed to karakeep

* sidebar changed from hoarder to karakeep

---------

Signed-off-by: petrsimunek <49954958+petrsimunek@users.noreply.github.com>
2025-04-08 13:09:11 -05:00
5882e0b2cb website/docs: Add release notes for 2025.2.4 (#13829) 2025-04-08 18:08:03 +00:00
65f0b471d8 website/docs: Add release notes for 2024.12.5 (#13828)
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-08 17:56:15 +00:00
7d054db1a5 Revert "core: fix non-exploitable open redirect (#13696)" (#13824) 2025-04-08 17:10:12 +00:00
cb75ba2e5e translate: Updates for file web/xliff/en.xlf in fr (#13822)
Translate web/xliff/en.xlf in fr

100% translated source file: 'web/xliff/en.xlf'
on 'fr'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-04-08 16:56:13 +00:00
36cecc1391 translate: Updates for file web/xliff/en.xlf in zh_CN (#13820)
Translate web/xliff/en.xlf in zh_CN

100% translated source file: 'web/xliff/en.xlf'
on 'zh_CN'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-04-08 18:42:16 +02:00
81b91d8777 translate: Updates for file web/xliff/en.xlf in zh-Hans (#13821)
Translate web/xliff/en.xlf in zh-Hans

100% translated source file: 'web/xliff/en.xlf'
on 'zh-Hans'.

Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
2025-04-08 18:41:58 +02:00
41dc23b3c2 core: users API: add date_joined (#13817) 2025-04-08 13:26:11 +00:00
370eff1494 website/integrations: fix ArgoCD redirect paths (#13804) 2025-04-08 15:24:46 +02:00
0ff8def03b core, web: update translations (#13806)
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2025-04-08 15:23:29 +02:00
b01cafd9fe core: bump goauthentik.io/api/v3 from 3.2025023.2 to 3.2025023.4 (#13811)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-08 15:19:30 +02:00
90aa8abb80 core: bump astral-sh/uv from 0.6.12 to 0.6.13 (#13812)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-08 15:19:04 +02:00
fd21aae4f9 website/docs: Correcting IDP URLs on Mailcow integration page (#13803)
Updating URLs to correct IDP URLs

Signed-off-by: Adam Berry <adam.berry@racklab.io>
2025-04-08 08:35:55 +01:00
360223a2ff web: Flesh out configs. (#13801) 2025-04-08 01:21:05 +02:00
0e83de2697 web: Tidy temporal utilities. (#13755) 2025-04-07 18:37:03 +00:00
a23bac9d9b website/integrations: nextcloud: add warning about admin lockout (#13782)
* docs: add a danger warning in nextcloud integration

If a user follwoing the guide for OpenID integration. They can lock out their Admin users, if used the customer profile scope and select the **use unique user ID** option. 
So a danger box was added to let people know that can happen and why

Signed-off-by: Unfaehig <38919962+Unfaehig@users.noreply.github.com>

* docs: website/integrations/services/nextcloud/index.mdx

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Unfaehig <38919962+Unfaehig@users.noreply.github.com>

* chore: nextcloud integration fix formating

---------

Signed-off-by: Unfaehig <38919962+Unfaehig@users.noreply.github.com>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-04-07 13:13:41 -05:00
220378b3f2 web: Fix TypeScript compilation issues for mixins, events. (#13766) 2025-04-07 19:53:51 +02:00
363d655378 web: Normalize client-side error handling (#13595)
web: Clean up error handling. Prep for permission checks.

- Add clearer reporting for API and network errors.
- Tidy error checking.
- Partial type safety for events.
2025-04-07 19:50:41 +02:00
e93b2a1a75 website/integrations: Open Web UI: add OPENID_REDIRECT_URI environment variable (#13785)
added OPENID_REDIRECT_URI open webui environment variable

Signed-off-by: Yuval Ziv <44985263+yuval-ziv@users.noreply.github.com>
2025-04-07 12:02:21 -05:00
76665cf65e website/integrations: add knocknoc (#13764)
* Document explaining integration between authentik and knocknoc

* Clarified Knocknoc config

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Fixed typos

* fixed note markdown

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/knocknoc/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Fixed line breaks, clarified provider section, added protocol settings header and other formatting improvements

* Update website/integrations/services/knocknoc/index.md

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dominic R <dominic@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-04-07 12:00:43 -05:00
3ad7f4dc24 sources: move identifier to parent model (#13797)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-07 18:01:41 +02:00
c5045e8792 stages/email: fix for newlines in emails (#13799)
stages/email: fix for newlines in emails (#13712)

* Test fix for newlines in emails

* fix linting

* remove base64 names from email address

* Make better checks on message.to

* Remove unnecessary logger
2025-04-07 17:34:26 +02:00
a8c9b3a8ba sources/kerberos, saml: allow creation of connections from the API (#13794)
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-07 14:35:52 +00:00
148506639a website/docs: add skip object instructions (#13749)
* Beginning of work

* Added instructions for skipobject to each source

* removed saml

* removed oauth

* Updates

* Added provider SkipObject instructions

* combined examples into one

* modified kerberos python snippet as per suggestion from Marc

* Update website/docs/add-secure-apps/providers/property-mappings/index.md

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/docs/users-sources/sources/protocols/kerberos/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Clarified how to use the exception

* Update website/docs/add-secure-apps/providers/property-mappings/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/docs/add-secure-apps/providers/property-mappings/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* fixed missing ) after gws

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* fixed missing . from /scim

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* fixing broken links

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Fixed links

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dominic R <dominic@sdko.org>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-04-04 11:05:03 -05:00
53814d9919 website/integrations: jenkins: fix oidc redirect uri (#13771)
Signed-off-by: Dominic R <dominic@sdko.org>
2025-04-04 08:03:14 +01:00
08b04c32f5 website/docs: add log levels section to logs documentation (#13687)
* Added debugging section and removed timestamps option

* Added details on trace and debug modes

* changed file to .mdx format

* Updated to include all log levels and a warning about trace

* Modified trace section

* Applied suggestions from dominic

* Prettier update

* Fixed tabs and lowercased the headers

* More tab fixes - prettier causing issues

* Prettier fix

* removed headers from inside tab sections

* added tabs import

* Changed line positioning for tabs import

* Update website/docs/troubleshooting/logs.mdx

Co-authored-by: Dominic R <dominic@sdko.org>
Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

* Applied suggestions from Dominic and Tana

* .

* Added tabs to last 2 sections as per suggestion from Tana

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

---------

Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Co-authored-by: Dominic R <dominic@sdko.org>
2025-04-03 12:20:42 -05:00
1c1d97339d website/docs: Updated redirect URI setup for Synology DSM (#13761)
Updated redirect URI setup

Based on the feedback from Synology's developers, and testing: the redirect URI should not contain #/signup as it breaks authentication if multiple redirect URIs have to be set.

Based on DSM 7.2's code itself, Host and HTTPS headers are used internally to match the corresponding entry in the list.

Hope that can help, this is from days of testing + discussing with the support and dev teams.

Signed-off-by: Florent <Wr0ngName@users.noreply.github.com>
2025-04-03 09:17:19 -05:00
cafa9c1737 core: bump python-kadmin-rs from 0.5.3 to 0.6.0 (#13758)
* core: bump python-kadmin-rs from 0.5.3 to 0.6.0

Bumps [python-kadmin-rs](https://github.com/authentik-community/kadmin-rs) from 0.5.3 to 0.6.0.
- [Release notes](https://github.com/authentik-community/kadmin-rs/releases)
- [Commits](https://github.com/authentik-community/kadmin-rs/compare/kadmin/version/0.5.3...kadmin/version/0.6.0)

---
updated-dependencies:
- dependency-name: python-kadmin-rs
  dependency-version: 0.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

* fix

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
2025-04-03 13:06:03 +00:00
5f64347ba1 website/integrations: add sidero omni (#13675)
* Mostly documented

* Typo

* Added testing step and formatted URLs

* Removed unnecessary URL

* Updated to newer templater

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/omni/index.md

Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Edited code marks

* Bolded some UI elements

---------

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
2025-04-03 08:04:37 -05:00
45ef54480a website/integrations: add certificate instructions to apache guacamole (#13684)
* added self signed certs section

* Added mention of OS specific section

* Updated to include synology instructions

* Fixed typos

* Applied suggestions from Dominic and clarified the target of the commands

* Added headers

* Updated keytool documentation link to JDK21 (latest)

* Squashed commit of the following:

commit f0e58a6f49
Author: Dominic R <dominic@sdko.org>
Date:   Tue Apr 1 17:37:11 2025 -0400

    website/docs: sys-mgmt: service accounts (#13722)

    * website/docs: ops: service accounts

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Update website/docs/sys-mgmt/service-accounts.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Dominic R <dominic@sdko.org>

    * Dewi's suggestions

    ---------

    Signed-off-by: Dominic R <dominic@sdko.org>
    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>

commit a3d642c08e
Author: Ben <bmfk_m@yahoo.de>
Date:   Tue Apr 1 22:09:31 2025 +0200

    website/integrations: add mailcow (#13727)

    * Add mailcow to Applications

    * Update wording and layout

    * Update website/integrations/services/mailcow/index.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Ben <bmfk_m@yahoo.de>

    * Update website/integrations/services/mailcow/index.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Ben <bmfk_m@yahoo.de>

    * Update website/integrations/services/mailcow/index.md

    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Signed-off-by: Ben <bmfk_m@yahoo.de>

    * lint

    ---------

    Signed-off-by: Ben <bmfk_m@yahoo.de>
    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>

commit 5d42cb9185
Author: Tana M Berry <tanamarieberry@yahoo.com>
Date:   Tue Apr 1 15:00:18 2025 -0500

    website: edit menu items (#13747)

    for review

    Co-authored-by: Tana M Berry <tana@goauthentik.com>

commit 1fd0cc5bb5
Author: Dominic R <dominic@sdko.org>
Date:   Tue Apr 1 14:31:07 2025 -0400

    website/integrations: slack,pocketbase,tandoor: convert to new authentik configuration format (#13742)

    * website/integrations-all: update authentik configuration template

    * website/integrations: slack,pocketbase,tandoor: convert to new authentik configuration format

    * Revert "website/integrations-all: update authentik configuration template"

    Not for this PR. Don't want to cause merge conflicts later on.

    This reverts commit 8378502090.

commit deef365ff5
Author: Dominic R <dominic@sdko.org>
Date:   Tue Apr 1 12:51:31 2025 -0400

    website/integrations-all: update authentik configuration template (#13740)

commit d1ae6287f2
Author: Jens L. <jens@goauthentik.io>
Date:   Tue Apr 1 18:35:35 2025 +0200

    web/admin: fix custom scope mappings being selected by default in proxy provider (#13735)

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 2e152cd264
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Tue Apr 1 18:29:16 2025 +0200

    web: bump vite from 5.4.15 to 5.4.16 in /web (#13743)

    Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.4.15 to 5.4.16.
    - [Release notes](https://github.com/vitejs/vite/releases)
    - [Changelog](https://github.com/vitejs/vite/blob/v5.4.16/packages/vite/CHANGELOG.md)
    - [Commits](https://github.com/vitejs/vite/commits/v5.4.16/packages/vite)

    ---
    updated-dependencies:
    - dependency-name: vite
      dependency-version: 5.4.16
      dependency-type: indirect
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit f5941e403b
Author: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
Date:   Tue Apr 1 18:18:59 2025 +0200

    translate: Updates for file locale/en/LC_MESSAGES/django.po in zh_CN (#13736)

    Translate locale/en/LC_MESSAGES/django.po in zh_CN

    100% translated source file: 'locale/en/LC_MESSAGES/django.po'
    on 'zh_CN'.

    Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>

commit ff3cf8c10e
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Tue Apr 1 18:18:42 2025 +0200

    core: bump goauthentik.io/api/v3 from 3.2025023.1 to 3.2025023.2 (#13746)

    Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025023.1 to 3.2025023.2.
    - [Release notes](https://github.com/goauthentik/client-go/releases)
    - [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
    - [Commits](https://github.com/goauthentik/client-go/compare/v3.2025023.1...v3.2025023.2)

    ---
    updated-dependencies:
    - dependency-name: goauthentik.io/api/v3
      dependency-version: 3.2025023.2
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit bfa6328172
Author: Dominic R <dominic@sdko.org>
Date:   Tue Apr 1 09:46:29 2025 -0400

    web/common: utils: fix infinite value handling in getRelativeTime function (#13564)

    Squash sdko/closes-13562

commit 4c9691c932
Author: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
Date:   Tue Apr 1 12:58:43 2025 +0200

    stages/authenticator_webauthn: Update FIDO MDS3 & Passkey aaguid blobs (#13744)

    Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>

commit a0f1566b4c
Author: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
Date:   Tue Apr 1 02:15:47 2025 +0200

    web: bump API Client version (#13741)

    Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>

commit 46261a4f42
Author: Jens L. <jens@goauthentik.io>
Date:   Tue Apr 1 01:41:18 2025 +0200

    */saml: allow for domainless SAML URLs (#13737)

commit 8b42ff1e97
Author: Dominic R <dominic@sdko.org>
Date:   Mon Mar 31 12:36:14 2025 -0400

    core: fix error when viewing used_by for built-in source (#13588)

    Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
    Co-authored-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>

commit ca4cb0d251
Author: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>
Date:   Mon Mar 31 15:54:37 2025 +0000

    translate: Updates for file locale/en/LC_MESSAGES/django.po in fr (#13738)

    * Translate locale/en/LC_MESSAGES/django.po in fr

    100% translated source file: 'locale/en/LC_MESSAGES/django.po'
    on 'fr'.

    * Translate locale/en/LC_MESSAGES/django.po in fr

    100% translated source file: 'locale/en/LC_MESSAGES/django.po'
    on 'fr'.

    ---------

    Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com>

commit a5a0fa79dd
Author: Tana M Berry <tanamarieberry@yahoo.com>
Date:   Mon Mar 31 07:57:03 2025 -0500

    website/docs: style guide (#13704)

    * new word choices, tweaks

    * shockingly, a typo

    * tweaks

    * Update website/docs/developer-docs/docs/style-guide.mdx

    Co-authored-by: Dominic R <dominic@sdko.org>
    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    ---------

    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
    Co-authored-by: Tana M Berry <tana@goauthentik.com>
    Co-authored-by: Dominic R <dominic@sdko.org>
    Co-authored-by: Jens Langhammer <jens@goauthentik.io>

commit c06a871f61
Author: Marcel Kempf <marcel.kempf@tum.de>
Date:   Mon Mar 31 12:58:03 2025 +0200

    core: fix double slash in cache key (#13721)

commit 4a3df67134
Author: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
Date:   Mon Mar 31 12:57:16 2025 +0200

    core, web: update translations (#13728)

    Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>

commit 422ccf61fa
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Mon Mar 31 12:27:56 2025 +0200

    core: bump goauthentik.io/api/v3 from 3.2025022.6 to 3.2025023.1 (#13729)

    Bumps [goauthentik.io/api/v3](https://github.com/goauthentik/client-go) from 3.2025022.6 to 3.2025023.1.
    - [Release notes](https://github.com/goauthentik/client-go/releases)
    - [Changelog](https://github.com/goauthentik/client-go/blob/main/model_version_history.go)
    - [Commits](https://github.com/goauthentik/client-go/compare/v3.2025022.6...v3.2025023.1)

    ---
    updated-dependencies:
    - dependency-name: goauthentik.io/api/v3
      dependency-type: direct:production
      update-type: version-update:semver-minor
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit d989f23907
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Mon Mar 31 12:27:44 2025 +0200

    website: bump the build group in /website with 3 updates (#13730)

    Bumps the build group in /website with 3 updates: [@rspack/binding-darwin-arm64](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack), [@rspack/binding-linux-arm64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack) and [@rspack/binding-linux-x64-gnu](https://github.com/web-infra-dev/rspack/tree/HEAD/packages/rspack).

    Updates `@rspack/binding-darwin-arm64` from 1.2.8 to 1.3.0
    - [Release notes](https://github.com/web-infra-dev/rspack/releases)
    - [Commits](https://github.com/web-infra-dev/rspack/commits/v1.3.0/packages/rspack)

    Updates `@rspack/binding-linux-arm64-gnu` from 1.2.8 to 1.3.0
    - [Release notes](https://github.com/web-infra-dev/rspack/releases)
    - [Commits](https://github.com/web-infra-dev/rspack/commits/v1.3.0/packages/rspack)

    Updates `@rspack/binding-linux-x64-gnu` from 1.2.8 to 1.3.0
    - [Release notes](https://github.com/web-infra-dev/rspack/releases)
    - [Commits](https://github.com/web-infra-dev/rspack/commits/v1.3.0/packages/rspack)

    ---
    updated-dependencies:
    - dependency-name: "@rspack/binding-darwin-arm64"
      dependency-type: direct:production
      update-type: version-update:semver-minor
      dependency-group: build
    - dependency-name: "@rspack/binding-linux-arm64-gnu"
      dependency-type: direct:production
      update-type: version-update:semver-minor
      dependency-group: build
    - dependency-name: "@rspack/binding-linux-x64-gnu"
      dependency-type: direct:production
      update-type: version-update:semver-minor
      dependency-group: build
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit 059180edef
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Mon Mar 31 12:27:18 2025 +0200

    core: bump astral-sh/uv from 0.6.10 to 0.6.11 (#13733)

    Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.6.10 to 0.6.11.
    - [Release notes](https://github.com/astral-sh/uv/releases)
    - [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/astral-sh/uv/compare/0.6.10...0.6.11)

    ---
    updated-dependencies:
    - dependency-name: astral-sh/uv
      dependency-type: direct:production
      update-type: version-update:semver-patch
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit 22f30634a8
Author: garar <krystiankichewko@gmail.com>
Date:   Sun Mar 30 20:28:11 2025 +0200

    website/docs: Fix Caddy forward auth example (#13726)

commit 35ff418c42
Author: Jens L. <jens@goauthentik.io>
Date:   Sun Mar 30 19:56:03 2025 +0200

    policies: buffered policy access view for concurrent authorization attempts when unauthenticated (#13629)

    * policies: buffered policy access view for concurrent authorization attempts when unauthenticated

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * better cleanup

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * more polish

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * more cleanup

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * add tests

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * fix multiple redirects, add e2e test

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * unrelated: add sp initiated post test

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * add SAML parallel test

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * format

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * optimise detection of when authentication is in progress

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * better backoff timing

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    ---------

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 7826e7a605
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sun Mar 30 03:26:30 2025 +0200

    core: bump oss/go/microsoft/golang from 1.23-fips-bookworm to 1.24-fips-bookworm (#13027)

    * core: bump oss/go/microsoft/golang

    Bumps oss/go/microsoft/golang from 1.23-fips-bookworm to 1.24-fips-bookworm.

    ---
    updated-dependencies:
    - dependency-name: oss/go/microsoft/golang
      dependency-type: direct:production
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

    * upstream docker image, use native fips

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * bump go version

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    ---------

    Signed-off-by: dependabot[bot] <support@github.com>
    Signed-off-by: Jens Langhammer <jens@goauthentik.io>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Jens Langhammer <jens@goauthentik.io>

commit 64f1b8207d
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Sat Mar 29 00:51:08 2025 +0100

    web: bump tar-fs from 2.1.1 to 2.1.2 in /web (#13713)

    Bumps [tar-fs](https://github.com/mafintosh/tar-fs) from 2.1.1 to 2.1.2.
    - [Commits](https://github.com/mafintosh/tar-fs/compare/v2.1.1...v2.1.2)

    ---
    updated-dependencies:
    - dependency-name: tar-fs
      dependency-type: indirect
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit b2c13f0614
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 22:14:15 2025 +0100

    core: fix flaky tests introduced with is_superuser API fix (#13709)

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 6965628020
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 22:13:34 2025 +0100

    root: bump python patch version to 3.12.9 (#13710)

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 608f63e9a2
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 17:42:45 2025 +0100

    website/docs: add reference to setting in CVE (#13707)

    * website/docs: add reference to setting in CVE

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * reword

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    ---------

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 22fa3a7fba
Author: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>
Date:   Fri Mar 28 17:42:24 2025 +0100

    web: bump API Client version (#13708)

    Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
    Co-authored-by: authentik-automation[bot] <135050075+authentik-automation[bot]@users.noreply.github.com>

commit bcfd6fefa7
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 17:08:57 2025 +0100

    release: 2025.2.3 (#13705)

    * release: 2025.2.3

    * fix uv lock not being bumped

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    ---------

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit eae18d0016
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 14:55:56 2025 +0100

    website/docs: fix 2025 CVE category title (#13703)

    * website/docs: fix 2025 CVE category title

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * add sideeffect of changing session backend

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    ---------

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 4a12a57c5f
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 14:49:35 2025 +0100

    website/docs: update release notes for 2024.12 and 2025.2 (#13702)

    * website/docs: update release notes for 2025.2 and 2024.12

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * update

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * update v2

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * format

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    ---------

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 71294b7deb
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 14:20:09 2025 +0100

    security: fix CVE-2025-29928 (#13695)

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 5af907db0c
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 14:16:13 2025 +0100

    stages/identification: refresh captcha on failure (#13697)

    * refactor cleanup behavior after stage form submit

    * refresh captcha on failing Identification stage

    * Revert "stages/identification: check captcha after checking authentication (#13533)"

    This reverts commit b7beac6795.

    Including a Captcha stage in an Identification stage is partially to
    prevent password spraying attacks. The reverted commit negated this
    feature to fix a UX bug. After 6fde42a9170, the functionality can now be
    reinstated.

    ---------

    Co-authored-by: Simonyi Gergő <gergo@goauthentik.io>

commit 63a118a2ba
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 14:15:39 2025 +0100

    core: fix non-exploitable open redirect (#13696)

    discovered by @dominic-r

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit d9a3c34a44
Author: Jens L. <jens@goauthentik.io>
Date:   Fri Mar 28 14:00:13 2025 +0100

    core: fix core/user is_superuser filter (#13693)

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 23bdad7574
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Fri Mar 28 13:21:30 2025 +0100

    website: bump @types/semver from 7.5.8 to 7.7.0 in /website (#13682)

    Bumps [@types/semver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/semver) from 7.5.8 to 7.7.0.
    - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
    - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/semver)

    ---
    updated-dependencies:
    - dependency-name: "@types/semver"
      dependency-type: direct:development
      update-type: version-update:semver-minor
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

commit 8ee90826fc
Author: Jens L. <jens@goauthentik.io>
Date:   Thu Mar 27 19:07:36 2025 +0100

    enterprise/stages/source: set is_redirected in flow source stage redirects to (#13604)

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 8c7d4d2f5e
Author: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
Date:   Thu Mar 27 17:49:16 2025 +0100

    website/docs: Clarify frontend development. Document local overrides. (#13586)

    * website/docs: Clarify setup flow. Document local overrides.

    * Update website/docs/developer-docs/setup/frontend-dev-environment.md

    Co-authored-by: Dominic R <dominic@sdko.org>
    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    * Update website/docs/developer-docs/setup/frontend-dev-environment.md

    Co-authored-by: Dominic R <dominic@sdko.org>
    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    * Update website/docs/developer-docs/setup/frontend-dev-environment.md

    Co-authored-by: Dominic R <dominic@sdko.org>
    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    * Update website/docs/developer-docs/setup/frontend-dev-environment.md

    Co-authored-by: Dominic R <dominic@sdko.org>
    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    * Update website/docs/developer-docs/setup/frontend-dev-environment.md

    Co-authored-by: Dominic R <dominic@sdko.org>
    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    * Update website/docs/developer-docs/setup/frontend-dev-environment.md

    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    * Update website/docs/developer-docs/setup/full-dev-environment.mdx

    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    * Update website/docs/install-config/install/docker-compose.mdx

    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    * Update website/docs/developer-docs/setup/frontend-dev-environment.md

    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>

    * Update website/docs/developer-docs/setup/full-dev-environment.mdx

    Signed-off-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>

    * Update authentik/lib/default.yml

    Signed-off-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>

    * fix linting to please the ci check

    ---------

    Signed-off-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
    Signed-off-by: Tana M Berry <tanamarieberry@yahoo.com>
    Co-authored-by: Tana M Berry <tanamarieberry@yahoo.com>
    Co-authored-by: Dominic R <dominic@sdko.org>
    Co-authored-by: Marcelo Elizeche Landó <marcelo@goauthentik.io>

commit d72def0368
Author: Jens L. <jens@goauthentik.io>
Date:   Wed Mar 26 23:06:12 2025 +0000

    web/admin: add sync status refresh button (#13678)

    * web/admin: add refresh button to sync status card

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * auto-expand if there's just one task

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    ---------

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 5bcf501842
Author: Jens L. <jens@goauthentik.io>
Date:   Wed Mar 26 23:05:43 2025 +0000

    outposts/ldap: fix paginator going into infinite loop (#13677)

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

commit 13fc216c68
Author: Dominic R <dominic@sdko.org>
Date:   Wed Mar 26 17:38:57 2025 -0400

    website/integrations-all: convert authentik configuration to wizard (#13144)

    * init

    * 6 more

    * tana...

    * quick reformat

    * welp only time for one change

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * Revert "wip"

    This reverts commit e71f0d22e3f093350e8d12eaad5e5c0f9d38253c.

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * wip

    * a

commit 27aed4b315
Author: Dominic R <dominic@sdko.org>
Date:   Wed Mar 26 13:16:46 2025 -0400

    web: ensure wizard modal closes on first cancel click (#13636)

    The application wizard modal previously required two clicks of the cancel
    button to close when opened from the User Interface.
    This was caused by improper event handling where events
    would propagate up the DOM tree potentially triggering multiple handlers.

commit 84b5992e55
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Wed Mar 26 18:03:20 2025 +0100

    ci: bump golangci/golangci-lint-action from 6 to 7 (#13661)

    * ci: bump golangci/golangci-lint-action from 6 to 7

    Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 6 to 7.
    - [Release notes](https://github.com/golangci/golangci-lint-action/releases)
    - [Commits](https://github.com/golangci/golangci-lint-action/compare/v6...v7)

    ---
    updated-dependencies:
    - dependency-name: golangci/golangci-lint-action
      dependency-type: direct:production
      update-type: version-update:semver-major
    ...

    Signed-off-by: dependabot[bot] <support@github.com>

    * fix lint

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * fix v2

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    * fix v3

    Signed-off-by: Jens Langhammer <jens@goauthentik.io>

    ---------

    Signed-off-by: dependabot[bot] <support@github.com>
    Signed-off-by: Jens Langhammer <jens@goauthentik.io>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Jens Langhammer <jens@goauthentik.io>

commit 7eb985f636
Author: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Date:   Wed Mar 26 17:05:42 2025 +0100

    website: bump the build group in /website with 3 updates (#13660)

    Bumps the build group in /website with 3 updates: [@swc/core-darwin-arm64](https://github.com/swc-project/swc), [@swc/core-linux-arm64-gnu](https://github.com/swc-project/swc) and [@swc/core-linux-x64-gnu](https://github.com/swc-project/swc).

    Updates `@swc/core-darwin-arm64` from 1.11.12 to 1.11.13
    - [Release notes](https://github.com/swc-project/swc/releases)
    - [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/swc-project/swc/compare/v1.11.12...v1.11.13)

    Updates `@swc/core-linux-arm64-gnu` from 1.11.12 to 1.11.13
    - [Release notes](https://github.com/swc-project/swc/releases)
    - [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/swc-project/swc/compare/v1.11.12...v1.11.13)

    Updates `@swc/core-linux-x64-gnu` from 1.11.12 to 1.11.13
    - [Release notes](https://github.com/swc-project/swc/releases)
    - [Changelog](https://github.com/swc-project/swc/blob/main/CHANGELOG.md)
    - [Commits](https://github.com/swc-project/swc/compare/v1.11.12...v1.11.13)

    ---
    updated-dependencies:
    - dependency-name: "@swc/core-darwin-arm64"
      dependency-type: direct:production
      update-type: version-update:semver-patch
      dependency-group: build
    - dependency-name: "@swc/core-linux-arm64-gnu"
      dependency-type: direct:production
      update-type: version-update:semver-patch
      dependency-group: build
    - dependency-name: "@swc/core-linux-x64-gnu"
      dependency-type: direct:production
      update-type: version-update:semver-patch
      dependency-group: build
    ...

    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* deployment -> host
2025-04-03 08:03:17 -05:00
a3dc8af4c6 core, web: update translations (#13753)
Signed-off-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: rissson <18313093+rissson@users.noreply.github.com>
2025-04-03 14:27:34 +02:00
36933a0aca lifecycle/aws: bump aws-cdk from 2.1006.0 to 2.1007.0 in /lifecycle/aws (#13757)
Bumps [aws-cdk](https://github.com/aws/aws-cdk-cli/tree/HEAD/packages/aws-cdk) from 2.1006.0 to 2.1007.0.
- [Release notes](https://github.com/aws/aws-cdk-cli/releases)
- [Commits](https://github.com/aws/aws-cdk-cli/commits/aws-cdk@v2.1007.0/packages/aws-cdk)

---
updated-dependencies:
- dependency-name: aws-cdk
  dependency-version: 2.1007.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-03 14:15:50 +02:00
8f689890df core: bump astral-sh/uv from 0.6.11 to 0.6.12 (#13756)
Bumps [astral-sh/uv](https://github.com/astral-sh/uv) from 0.6.11 to 0.6.12.
- [Release notes](https://github.com/astral-sh/uv/releases)
- [Changelog](https://github.com/astral-sh/uv/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/uv/compare/0.6.11...0.6.12)

---
updated-dependencies:
- dependency-name: astral-sh/uv
  dependency-version: 0.6.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-03 14:13:43 +02:00
ec49b2e0e0 website/integrations: calibre-web: document (#12477)
* website/integrations: calibre-web: add to sidebar

Adds the calibre-web integration to the sidebar.

Signed-off-by: 4d62 <github-user@sdko.org>

* website/integrations: calibre-web: init

Initializes the documentation with the placeholder. I have a feeling this is going to be funnnnnnnnnnnnnnnnn

Signed-off-by: 4d62 <github-user@sdko.org>

* website/integrations: calibre-web: service configuration

Adds configuration documentation for calibre-web

PS: Never setup a LDAP outpost before and I don't have calibre web so uhhh yea im gonna take care of this after the holidays (probably)

Signed-off-by: 4d62 <github-user@sdko.org>

* Update index.md

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Changed proider pair instructions to new version

Signed-off-by: Dewi Roberts <dewi@goauthentik.io>

* Update website/integrations/services/calibre-web/index.md

Signed-off-by: Dominic R <dominic@sdko.org>

---------

Signed-off-by: 4d62 <github-user@sdko.org>
Signed-off-by: Dominic R <dominic@sdko.org>
Signed-off-by: Dewi Roberts <dewi@goauthentik.io>
Co-authored-by: Dewi Roberts <dewi@goauthentik.io>
2025-04-02 12:57:53 -05:00
390 changed files with 5967 additions and 3129 deletions

View File

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

1
.gitignore vendored
View File

@ -33,6 +33,7 @@ eggs/
lib64/
parts/
dist/
out/
sdist/
var/
wheels/

View File

@ -94,7 +94,7 @@ RUN --mount=type=secret,id=GEOIPUPDATE_ACCOUNT_ID \
/bin/sh -c "/usr/bin/entry.sh || echo 'Failed to get GeoIP database, disabling'; exit 0"
# Stage 5: Download uv
FROM ghcr.io/astral-sh/uv:0.6.11 AS uv
FROM ghcr.io/astral-sh/uv:0.6.14 AS uv
# Stage 6: Base python image
FROM ghcr.io/goauthentik/fips-python:3.12.9-slim-bookworm-fips AS python-base

View File

@ -2,7 +2,7 @@
from os import environ
__version__ = "2025.2.3"
__version__ = "2025.2.4"
ENV_GIT_HASH_KEY = "GIT_BUILD_HASH"

View File

@ -179,10 +179,13 @@ class UserSourceConnectionSerializer(SourceSerializer):
"user",
"source",
"source_obj",
"identifier",
"created",
"last_updated",
]
extra_kwargs = {
"created": {"read_only": True},
"last_updated": {"read_only": True},
}
@ -199,7 +202,7 @@ class UserSourceConnectionViewSet(
queryset = UserSourceConnection.objects.all()
serializer_class = UserSourceConnectionSerializer
filterset_fields = ["user", "source__slug"]
search_fields = ["source__slug"]
search_fields = ["user__username", "source__slug", "identifier"]
ordering = ["source__slug", "pk"]
owner_field = "user"
@ -218,9 +221,11 @@ class GroupSourceConnectionSerializer(SourceSerializer):
"source_obj",
"identifier",
"created",
"last_updated",
]
extra_kwargs = {
"created": {"read_only": True},
"last_updated": {"read_only": True},
}
@ -237,6 +242,5 @@ class GroupSourceConnectionViewSet(
queryset = GroupSourceConnection.objects.all()
serializer_class = GroupSourceConnectionSerializer
filterset_fields = ["group", "source__slug"]
search_fields = ["source__slug"]
search_fields = ["group__name", "source__slug", "identifier"]
ordering = ["source__slug", "pk"]
owner_field = "user"

View File

@ -228,6 +228,7 @@ class UserSerializer(ModelSerializer):
"name",
"is_active",
"last_login",
"date_joined",
"is_superuser",
"groups",
"groups_obj",
@ -242,6 +243,7 @@ class UserSerializer(ModelSerializer):
]
extra_kwargs = {
"name": {"allow_blank": True},
"date_joined": {"read_only": True},
"password_change_date": {"read_only": True},
}

View File

@ -0,0 +1,19 @@
# Generated by Django 5.0.13 on 2025-04-07 14:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0043_alter_group_options"),
]
operations = [
migrations.AddField(
model_name="usersourceconnection",
name="new_identifier",
field=models.TextField(default=""),
preserve_default=False,
),
]

View File

@ -0,0 +1,30 @@
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("authentik_core", "0044_usersourceconnection_new_identifier"),
("authentik_sources_kerberos", "0003_migrate_userkerberossourceconnection_identifier"),
("authentik_sources_oauth", "0009_migrate_useroauthsourceconnection_identifier"),
("authentik_sources_plex", "0005_migrate_userplexsourceconnection_identifier"),
("authentik_sources_saml", "0019_migrate_usersamlsourceconnection_identifier"),
]
operations = [
migrations.RenameField(
model_name="usersourceconnection",
old_name="new_identifier",
new_name="identifier",
),
migrations.AddIndex(
model_name="usersourceconnection",
index=models.Index(fields=["identifier"], name="authentik_c_identif_59226f_idx"),
),
migrations.AddIndex(
model_name="usersourceconnection",
index=models.Index(
fields=["source", "identifier"], name="authentik_c_source__649e04_idx"
),
),
]

View File

@ -824,6 +824,7 @@ class UserSourceConnection(SerializerModel, CreatedUpdatedModel):
user = models.ForeignKey(User, on_delete=models.CASCADE)
source = models.ForeignKey(Source, on_delete=models.CASCADE)
identifier = models.TextField()
objects = InheritanceManager()
@ -837,6 +838,10 @@ class UserSourceConnection(SerializerModel, CreatedUpdatedModel):
class Meta:
unique_together = (("user", "source"),)
indexes = (
models.Index(fields=("identifier",)),
models.Index(fields=("source", "identifier")),
)
class GroupSourceConnection(SerializerModel, CreatedUpdatedModel):

View File

@ -36,7 +36,6 @@ from authentik.flows.planner import (
)
from authentik.flows.stage import StageView
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET
from authentik.lib.utils.urls import is_url_absolute
from authentik.lib.views import bad_request_message
from authentik.policies.denied import AccessDeniedResponse
from authentik.policies.utils import delete_none_values
@ -210,8 +209,6 @@ class SourceFlowManager:
final_redirect = self.request.session.get(SESSION_KEY_GET, {}).get(
NEXT_ARG_NAME, "authentik_core:if-user"
)
if not is_url_absolute(final_redirect):
final_redirect = "authentik_core:if-user"
flow_context.update(
{
# Since we authenticate the user by their token, they have no backend set

View File

@ -13,7 +13,11 @@ from authentik.core.api.devices import AdminDeviceViewSet, DeviceViewSet
from authentik.core.api.groups import GroupViewSet
from authentik.core.api.property_mappings import PropertyMappingViewSet
from authentik.core.api.providers import ProviderViewSet
from authentik.core.api.sources import SourceViewSet, UserSourceConnectionViewSet
from authentik.core.api.sources import (
GroupSourceConnectionViewSet,
SourceViewSet,
UserSourceConnectionViewSet,
)
from authentik.core.api.tokens import TokenViewSet
from authentik.core.api.transactional_applications import TransactionalApplicationView
from authentik.core.api.users import UserViewSet
@ -81,6 +85,7 @@ api_urlpatterns = [
("core/tokens", TokenViewSet),
("sources/all", SourceViewSet),
("sources/user_connections/all", UserSourceConnectionViewSet),
("sources/group_connections/all", GroupSourceConnectionViewSet),
("providers/all", ProviderViewSet),
("propertymappings/all", PropertyMappingViewSet),
("authenticators/all", DeviceViewSet, "device"),

View File

@ -28,8 +28,8 @@ def pytest_report_header(*_, **__):
def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None:
current_id = int(environ.get("CI_RUN_ID", 0)) - 1
total_ids = int(environ.get("CI_TOTAL_RUNS", 0))
current_id = int(environ.get("CI_RUN_ID", "0")) - 1
total_ids = int(environ.get("CI_TOTAL_RUNS", "0"))
if total_ids:
num_tests = len(items)

View File

@ -1,13 +1,11 @@
"""Kerberos Source Serializer"""
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.sources import (
GroupSourceConnectionSerializer,
GroupSourceConnectionViewSet,
UserSourceConnectionSerializer,
UserSourceConnectionViewSet,
)
from authentik.core.api.used_by import UsedByMixin
from authentik.sources.kerberos.models import (
GroupKerberosSourceConnection,
UserKerberosSourceConnection,
@ -15,33 +13,20 @@ from authentik.sources.kerberos.models import (
class UserKerberosSourceConnectionSerializer(UserSourceConnectionSerializer):
"""Kerberos Source Serializer"""
class Meta:
class Meta(UserSourceConnectionSerializer.Meta):
model = UserKerberosSourceConnection
fields = UserSourceConnectionSerializer.Meta.fields + ["identifier"]
class UserKerberosSourceConnectionViewSet(UsedByMixin, ModelViewSet):
"""Source Viewset"""
class UserKerberosSourceConnectionViewSet(UserSourceConnectionViewSet, ModelViewSet):
queryset = UserKerberosSourceConnection.objects.all()
serializer_class = UserKerberosSourceConnectionSerializer
filterset_fields = ["source__slug"]
search_fields = ["source__slug"]
ordering = ["source__slug"]
owner_field = "user"
class GroupKerberosSourceConnectionSerializer(GroupSourceConnectionSerializer):
"""OAuth Group-Source connection Serializer"""
class Meta(GroupSourceConnectionSerializer.Meta):
model = GroupKerberosSourceConnection
class GroupKerberosSourceConnectionViewSet(GroupSourceConnectionViewSet):
"""Group-source connection Viewset"""
class GroupKerberosSourceConnectionViewSet(GroupSourceConnectionViewSet, ModelViewSet):
queryset = GroupKerberosSourceConnection.objects.all()
serializer_class = GroupKerberosSourceConnectionSerializer

View File

@ -0,0 +1,28 @@
from django.db import migrations
def migrate_identifier(apps, schema_editor):
db_alias = schema_editor.connection.alias
UserKerberosSourceConnection = apps.get_model(
"authentik_sources_kerberos", "UserKerberosSourceConnection"
)
for connection in UserKerberosSourceConnection.objects.using(db_alias).all():
connection.new_identifier = connection.identifier
connection.save(using=db_alias)
class Migration(migrations.Migration):
dependencies = [
("authentik_sources_kerberos", "0002_kerberossource_kadmin_type"),
("authentik_core", "0044_usersourceconnection_new_identifier"),
]
operations = [
migrations.RunPython(code=migrate_identifier, reverse_code=migrations.RunPython.noop),
migrations.RemoveField(
model_name="userkerberossourceconnection",
name="identifier",
),
]

View File

@ -372,8 +372,6 @@ class KerberosSourcePropertyMapping(PropertyMapping):
class UserKerberosSourceConnection(UserSourceConnection):
"""Connection to configured Kerberos Sources."""
identifier = models.TextField()
@property
def serializer(self) -> type[Serializer]:
from authentik.sources.kerberos.api.source_connection import (

View File

@ -99,6 +99,7 @@ class LDAPSourceSerializer(SourceSerializer):
"sync_groups",
"sync_parent_group",
"connectivity",
"lookup_groups_from_user",
]
extra_kwargs = {"bind_password": {"write_only": True}}
@ -134,6 +135,7 @@ class LDAPSourceViewSet(UsedByMixin, ModelViewSet):
"sync_parent_group",
"user_property_mappings",
"group_property_mappings",
"lookup_groups_from_user",
]
search_fields = ["name", "slug"]
ordering = ["name"]

View File

@ -0,0 +1,24 @@
# Generated by Django 5.0.13 on 2025-03-26 17:06
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
(
"authentik_sources_ldap",
"0006_rename_ldappropertymapping_ldapsourcepropertymapping_and_more",
),
]
operations = [
migrations.AddField(
model_name="ldapsource",
name="lookup_groups_from_user",
field=models.BooleanField(
default=False,
help_text="Lookup group membership based on a user attribute instead of a group attribute. This allows nested group resolution on systems like FreeIPA and Active Directory",
),
),
]

View File

@ -123,6 +123,14 @@ class LDAPSource(Source):
Group, blank=True, null=True, default=None, on_delete=models.SET_DEFAULT
)
lookup_groups_from_user = models.BooleanField(
default=False,
help_text=_(
"Lookup group membership based on a user attribute instead of a group attribute. "
"This allows nested group resolution on systems like FreeIPA and Active Directory"
),
)
@property
def component(self) -> str:
return "ak-source-ldap-form"

View File

@ -28,15 +28,17 @@ class MembershipLDAPSynchronizer(BaseLDAPSynchronizer):
if not self._source.sync_groups:
self.message("Group syncing is disabled for this Source")
return iter(())
# If we are looking up groups from users, we don't need to fetch the group membership field
attributes = [self._source.object_uniqueness_field, LDAP_DISTINGUISHED_NAME]
if not self._source.lookup_groups_from_user:
attributes.append(self._source.group_membership_field)
return self.search_paginator(
search_base=self.base_dn_groups,
search_filter=self._source.group_object_filter,
search_scope=SUBTREE,
attributes=[
self._source.group_membership_field,
self._source.object_uniqueness_field,
LDAP_DISTINGUISHED_NAME,
],
attributes=attributes,
**kwargs,
)
@ -47,9 +49,24 @@ class MembershipLDAPSynchronizer(BaseLDAPSynchronizer):
return -1
membership_count = 0
for group in page_data:
if "attributes" not in group:
continue
members = group.get("attributes", {}).get(self._source.group_membership_field, [])
if self._source.lookup_groups_from_user:
group_dn = group.get("dn", {})
group_filter = f"({self._source.group_membership_field}={group_dn})"
group_members = self._source.connection().extend.standard.paged_search(
search_base=self.base_dn_users,
search_filter=group_filter,
search_scope=SUBTREE,
attributes=[self._source.object_uniqueness_field],
)
members = []
for group_member in group_members:
group_member_dn = group_member.get("dn", {})
members.append(group_member_dn)
else:
if "attributes" not in group:
continue
members = group.get("attributes", {}).get(self._source.group_membership_field, [])
ak_group = self.get_group(group)
if not ak_group:
continue
@ -68,7 +85,7 @@ class MembershipLDAPSynchronizer(BaseLDAPSynchronizer):
"ak_groups__in": [ak_group],
}
)
)
).distinct()
membership_count += 1
membership_count += users.count()
ak_group.users.set(users)

View File

@ -96,6 +96,26 @@ def mock_freeipa_connection(password: str) -> Connection:
"objectClass": "posixAccount",
},
)
# User with groups in memberOf attribute
connection.strategy.add_entry(
"cn=user4,ou=users,dc=goauthentik,dc=io",
{
"name": "user4_sn",
"uid": "user4_sn",
"objectClass": "person",
"memberOf": [
"cn=reverse-lookup-group,ou=groups,dc=goauthentik,dc=io",
],
},
)
connection.strategy.add_entry(
"cn=reverse-lookup-group,ou=groups,dc=goauthentik,dc=io",
{
"cn": "reverse-lookup-group",
"uid": "reverse-lookup-group",
"objectClass": "groupOfNames",
},
)
# Locked out user
connection.strategy.add_entry(
"cn=user-nsaccountlock,ou=users,dc=goauthentik,dc=io",

View File

@ -162,6 +162,43 @@ class LDAPSyncTests(TestCase):
self.assertFalse(User.objects.filter(username="user1_sn").exists())
self.assertFalse(User.objects.get(username="user-nsaccountlock").is_active)
def test_sync_groups_freeipa_memberOf(self):
"""Test group sync when membership is derived from memberOf user attribute"""
self.source.object_uniqueness_field = "uid"
self.source.group_object_filter = "(objectClass=groupOfNames)"
self.source.lookup_groups_from_user = True
self.source.group_membership_field = "memberOf"
self.source.user_property_mappings.set(
LDAPSourcePropertyMapping.objects.filter(
Q(managed__startswith="goauthentik.io/sources/ldap/default")
| Q(managed__startswith="goauthentik.io/sources/ldap/openldap")
)
)
self.source.group_property_mappings.set(
LDAPSourcePropertyMapping.objects.filter(
managed="goauthentik.io/sources/ldap/openldap-cn"
)
)
connection = MagicMock(return_value=mock_freeipa_connection(LDAP_PASSWORD))
with patch("authentik.sources.ldap.models.LDAPSource.connection", connection):
user_sync = UserLDAPSynchronizer(self.source)
user_sync.sync_full()
group_sync = GroupLDAPSynchronizer(self.source)
group_sync.sync_full()
membership_sync = MembershipLDAPSynchronizer(self.source)
membership_sync.sync_full()
self.assertTrue(
User.objects.filter(username="user4_sn").exists(), "User does not exist"
)
# Test if membership mapping based on memberOf works.
memberof_group = Group.objects.filter(name="reverse-lookup-group")
self.assertTrue(memberof_group.exists(), "Group does not exist")
self.assertTrue(
memberof_group.first().users.filter(username="user4_sn").exists(),
"User not a member of the group",
)
def test_sync_groups_ad(self):
"""Test group sync"""
self.source.user_property_mappings.set(

View File

@ -1,5 +1,3 @@
"""OAuth Source Serializer"""
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.sources import (
@ -12,11 +10,9 @@ from authentik.sources.oauth.models import GroupOAuthSourceConnection, UserOAuth
class UserOAuthSourceConnectionSerializer(UserSourceConnectionSerializer):
"""OAuth Source Serializer"""
class Meta(UserSourceConnectionSerializer.Meta):
model = UserOAuthSourceConnection
fields = UserSourceConnectionSerializer.Meta.fields + ["identifier", "access_token"]
fields = UserSourceConnectionSerializer.Meta.fields + ["access_token"]
extra_kwargs = {
**UserSourceConnectionSerializer.Meta.extra_kwargs,
"access_token": {"write_only": True},
@ -24,21 +20,15 @@ class UserOAuthSourceConnectionSerializer(UserSourceConnectionSerializer):
class UserOAuthSourceConnectionViewSet(UserSourceConnectionViewSet, ModelViewSet):
"""Source Viewset"""
queryset = UserOAuthSourceConnection.objects.all()
serializer_class = UserOAuthSourceConnectionSerializer
class GroupOAuthSourceConnectionSerializer(GroupSourceConnectionSerializer):
"""OAuth Group-Source connection Serializer"""
class Meta(GroupSourceConnectionSerializer.Meta):
model = GroupOAuthSourceConnection
class GroupOAuthSourceConnectionViewSet(GroupSourceConnectionViewSet, ModelViewSet):
"""Group-source connection Viewset"""
queryset = GroupOAuthSourceConnection.objects.all()
serializer_class = GroupOAuthSourceConnectionSerializer

View File

@ -0,0 +1,28 @@
from django.db import migrations
def migrate_identifier(apps, schema_editor):
db_alias = schema_editor.connection.alias
UserOAuthSourceConnection = apps.get_model(
"authentik_sources_oauth", "UserOAuthSourceConnection"
)
for connection in UserOAuthSourceConnection.objects.using(db_alias).all():
connection.new_identifier = connection.identifier
connection.save(using=db_alias)
class Migration(migrations.Migration):
dependencies = [
("authentik_sources_oauth", "0008_groupoauthsourceconnection_and_more"),
("authentik_core", "0044_usersourceconnection_new_identifier"),
]
operations = [
migrations.RunPython(code=migrate_identifier, reverse_code=migrations.RunPython.noop),
migrations.RemoveField(
model_name="useroauthsourceconnection",
name="identifier",
),
]

View File

@ -286,7 +286,6 @@ class OAuthSourcePropertyMapping(PropertyMapping):
class UserOAuthSourceConnection(UserSourceConnection):
"""Authorized remote OAuth provider."""
identifier = models.CharField(max_length=255)
access_token = models.TextField(blank=True, null=True, default=None)
@property

View File

@ -1,5 +1,3 @@
"""Plex Source connection Serializer"""
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.sources import (
@ -12,14 +10,9 @@ from authentik.sources.plex.models import GroupPlexSourceConnection, UserPlexSou
class UserPlexSourceConnectionSerializer(UserSourceConnectionSerializer):
"""Plex Source connection Serializer"""
class Meta(UserSourceConnectionSerializer.Meta):
model = UserPlexSourceConnection
fields = UserSourceConnectionSerializer.Meta.fields + [
"identifier",
"plex_token",
]
fields = UserSourceConnectionSerializer.Meta.fields + ["plex_token"]
extra_kwargs = {
**UserSourceConnectionSerializer.Meta.extra_kwargs,
"plex_token": {"write_only": True},
@ -27,21 +20,15 @@ class UserPlexSourceConnectionSerializer(UserSourceConnectionSerializer):
class UserPlexSourceConnectionViewSet(UserSourceConnectionViewSet, ModelViewSet):
"""Plex Source connection Serializer"""
queryset = UserPlexSourceConnection.objects.all()
serializer_class = UserPlexSourceConnectionSerializer
class GroupPlexSourceConnectionSerializer(GroupSourceConnectionSerializer):
"""Plex Group-Source connection Serializer"""
class Meta(GroupSourceConnectionSerializer.Meta):
model = GroupPlexSourceConnection
class GroupPlexSourceConnectionViewSet(GroupSourceConnectionViewSet, ModelViewSet):
"""Group-source connection Viewset"""
queryset = GroupPlexSourceConnection.objects.all()
serializer_class = GroupPlexSourceConnectionSerializer

View File

@ -0,0 +1,29 @@
from django.db import migrations
def migrate_identifier(apps, schema_editor):
db_alias = schema_editor.connection.alias
UserPlexSourceConnection = apps.get_model("authentik_sources_plex", "UserPlexSourceConnection")
for connection in UserPlexSourceConnection.objects.using(db_alias).all():
connection.new_identifier = connection.identifier
connection.save(using=db_alias)
class Migration(migrations.Migration):
dependencies = [
(
"authentik_sources_plex",
"0004_groupplexsourceconnection_plexsourcepropertymapping_and_more",
),
("authentik_core", "0044_usersourceconnection_new_identifier"),
]
operations = [
migrations.RunPython(code=migrate_identifier, reverse_code=migrations.RunPython.noop),
migrations.RemoveField(
model_name="userplexsourceconnection",
name="identifier",
),
]

View File

@ -141,7 +141,6 @@ class UserPlexSourceConnection(UserSourceConnection):
"""Connect user and plex source"""
plex_token = models.TextField()
identifier = models.TextField()
@property
def serializer(self) -> type[Serializer]:

View File

@ -1,5 +1,3 @@
"""SAML Source Serializer"""
from rest_framework.viewsets import ModelViewSet
from authentik.core.api.sources import (
@ -12,29 +10,20 @@ from authentik.sources.saml.models import GroupSAMLSourceConnection, UserSAMLSou
class UserSAMLSourceConnectionSerializer(UserSourceConnectionSerializer):
"""SAML Source Serializer"""
class Meta(UserSourceConnectionSerializer.Meta):
model = UserSAMLSourceConnection
fields = UserSourceConnectionSerializer.Meta.fields + ["identifier"]
class UserSAMLSourceConnectionViewSet(UserSourceConnectionViewSet, ModelViewSet):
"""Source Viewset"""
queryset = UserSAMLSourceConnection.objects.all()
serializer_class = UserSAMLSourceConnectionSerializer
class GroupSAMLSourceConnectionSerializer(GroupSourceConnectionSerializer):
"""OAuth Group-Source connection Serializer"""
class Meta(GroupSourceConnectionSerializer.Meta):
model = GroupSAMLSourceConnection
class GroupSAMLSourceConnectionViewSet(GroupSourceConnectionViewSet):
"""Group-source connection Viewset"""
class GroupSAMLSourceConnectionViewSet(GroupSourceConnectionViewSet, ModelViewSet):
queryset = GroupSAMLSourceConnection.objects.all()
serializer_class = GroupSAMLSourceConnectionSerializer

View File

@ -0,0 +1,26 @@
from django.db import migrations
def migrate_identifier(apps, schema_editor):
db_alias = schema_editor.connection.alias
UserSAMLSourceConnection = apps.get_model("authentik_sources_saml", "UserSAMLSourceConnection")
for connection in UserSAMLSourceConnection.objects.using(db_alias).all():
connection.new_identifier = connection.identifier
connection.save(using=db_alias)
class Migration(migrations.Migration):
dependencies = [
("authentik_sources_saml", "0018_alter_samlsource_slo_url_alter_samlsource_sso_url"),
("authentik_core", "0044_usersourceconnection_new_identifier"),
]
operations = [
migrations.RunPython(code=migrate_identifier, reverse_code=migrations.RunPython.noop),
migrations.RemoveField(
model_name="usersamlsourceconnection",
name="identifier",
),
]

View File

@ -318,8 +318,6 @@ class SAMLSourcePropertyMapping(PropertyMapping):
class UserSAMLSourceConnection(UserSourceConnection):
"""Connection to configured SAML Sources."""
identifier = models.TextField()
@property
def serializer(self) -> Serializer:
from authentik.sources.saml.api.source_connection import UserSAMLSourceConnectionSerializer

View File

@ -33,7 +33,6 @@ from authentik.flows.planner import (
)
from authentik.flows.stage import ChallengeStageView
from authentik.flows.views.executor import NEXT_ARG_NAME, SESSION_KEY_GET, SESSION_KEY_PLAN
from authentik.lib.utils.urls import is_url_absolute
from authentik.lib.views import bad_request_message
from authentik.providers.saml.utils.encoding import nice64
from authentik.sources.saml.exceptions import MissingSAMLResponse, UnsupportedNameIDFormat
@ -74,8 +73,6 @@ class InitiateView(View):
final_redirect = self.request.session.get(SESSION_KEY_GET, {}).get(
NEXT_ARG_NAME, "authentik_core:if-user"
)
if not is_url_absolute(final_redirect):
final_redirect = "authentik_core:if-user"
kwargs.update(
{
PLAN_CONTEXT_SSO: True,

View File

@ -104,6 +104,13 @@ def send_mail(
# can't be converted to json)
message_object.attach(logo_data())
if (
message_object.to
and isinstance(message_object.to[0], str)
and "=?utf-8?" in message_object.to[0]
):
message_object.to = [message_object.to[0].split("<")[-1].replace(">", "")]
LOGGER.debug("Sending mail", to=message_object.to)
backend.send_messages([message_object])
Event.new(

View File

@ -97,6 +97,37 @@ class TestEmailStageSending(FlowTestCase):
self.assertEqual(mail.outbox[0].subject, "authentik")
self.assertEqual(mail.outbox[0].to, [f"Test User Many Words <{long_user.email}>"])
def test_utf8_name(self):
"""Test with pending user"""
plan = FlowPlan(flow_pk=self.flow.pk.hex, bindings=[self.binding], markers=[StageMarker()])
utf8_user = create_test_user()
utf8_user.name = "Cirilo ЉМНЊ el cirilico И̂ӢЙӤ "
utf8_user.email = "cyrillic@authentik.local"
utf8_user.save()
plan.context[PLAN_CONTEXT_PENDING_USER] = utf8_user
session = self.client.session
session[SESSION_KEY_PLAN] = plan
session.save()
Event.objects.filter(action=EventAction.EMAIL_SENT).delete()
url = reverse("authentik_api:flow-executor", kwargs={"flow_slug": self.flow.slug})
with patch(
"authentik.stages.email.models.EmailStage.backend_class",
PropertyMock(return_value=EmailBackend),
):
response = self.client.post(url)
self.assertEqual(response.status_code, 200)
self.assertStageResponse(
response,
self.flow,
response_errors={
"non_field_errors": [{"string": "email-sent", "code": "email-sent"}]
},
)
self.assertEqual(len(mail.outbox), 1)
self.assertEqual(mail.outbox[0].subject, "authentik")
self.assertEqual(mail.outbox[0].to, [f"{utf8_user.email}"])
def test_pending_fake_user(self):
"""Test with pending (fake) user"""
self.flow.designation = FlowDesignation.RECOVERY

View File

@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema",
"$id": "https://goauthentik.io/blueprints/schema.json",
"type": "object",
"title": "authentik 2025.2.3 Blueprint schema",
"title": "authentik 2025.2.4 Blueprint schema",
"required": [
"version",
"entries"
@ -7885,6 +7885,11 @@
"type": "string",
"format": "uuid",
"title": "Sync parent group"
},
"lookup_groups_from_user": {
"type": "boolean",
"title": "Lookup groups from user",
"description": "Lookup group membership based on a user attribute instead of a group attribute. This allows nested group resolution on systems like FreeIPA and Active Directory"
}
},
"required": []
@ -8231,7 +8236,6 @@
},
"identifier": {
"type": "string",
"maxLength": 255,
"minLength": 1,
"title": "Identifier"
},

View File

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

14
go.mod
View File

@ -1,9 +1,10 @@
module goauthentik.io
go 1.24.0
require (
beryju.io/ldap v0.1.0
github.com/coreos/go-oidc/v3 v3.13.0
github.com/coreos/go-oidc/v3 v3.14.1
github.com/getsentry/sentry-go v0.31.1
github.com/go-http-utils/etag v0.0.0-20161124023236-513ea8f21eb1
github.com/go-ldap/ldap/v3 v3.4.10
@ -19,17 +20,17 @@ require (
github.com/mitchellh/mapstructure v1.5.0
github.com/nmcclain/asn1-ber v0.0.0-20170104154839-2661553a0484
github.com/pires/go-proxyproto v0.8.0
github.com/prometheus/client_golang v1.21.1
github.com/prometheus/client_golang v1.22.0
github.com/redis/go-redis/v9 v9.7.3
github.com/sethvargo/go-envconfig v1.1.1
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.9.1
github.com/stretchr/testify v1.10.0
github.com/wwt/guac v1.3.2
goauthentik.io/api/v3 v3.2025023.2
goauthentik.io/api/v3 v3.2025024.1
golang.org/x/exp v0.0.0-20230210204819-062eb4c674ab
golang.org/x/oauth2 v0.28.0
golang.org/x/sync v0.12.0
golang.org/x/oauth2 v0.29.0
golang.org/x/sync v0.13.0
gopkg.in/yaml.v2 v2.4.0
layeh.com/radius v0.0.0-20210819152912-ad72663a72ab
)
@ -59,7 +60,6 @@ require (
github.com/go-openapi/validate v0.24.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/oklog/ulid v1.3.1 // indirect
@ -76,6 +76,6 @@ require (
golang.org/x/crypto v0.36.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/text v0.23.0 // indirect
google.golang.org/protobuf v1.36.1 // indirect
google.golang.org/protobuf v1.36.5 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

31
go.sum
View File

@ -55,8 +55,8 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/go-oidc/v3 v3.13.0 h1:M66zd0pcc5VxvBNM4pB331Wrsanby+QomQYjN8HamW8=
github.com/coreos/go-oidc/v3 v3.13.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk=
github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@ -148,8 +148,9 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@ -207,8 +208,8 @@ github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFF
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
@ -239,8 +240,8 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_golang v1.21.1 h1:DOvXXTqVzvkIewV/CDPFdejpMCGeMcbGCQ8YOmu+Ibk=
github.com/prometheus/client_golang v1.21.1/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg=
github.com/prometheus/client_golang v1.22.0 h1:rb93p9lokFEsctTys46VnV1kLCDpVZ0a/Y92Vm0Zc6Q=
github.com/prometheus/client_golang v1.22.0/go.mod h1:R7ljNsLXhuQXYZYtw6GAE9AZg8Y7vEW5scdCXrWRXC0=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
@ -299,8 +300,8 @@ go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
goauthentik.io/api/v3 v3.2025023.2 h1:4XHlnykN5jQH78liQ4cp2Jf8eigvQImIJp+A+bsq1nA=
goauthentik.io/api/v3 v3.2025023.2/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
goauthentik.io/api/v3 v3.2025024.1 h1:wYmpbNW1XptrjS5dlnZj8CrCs+JUGEVJYStrFdWL9aA=
goauthentik.io/api/v3 v3.2025024.1/go.mod h1:zz+mEZg8rY/7eEjkMGWJ2DnGqk+zqxuybGCGrR2O4Kw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
@ -395,8 +396,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/oauth2 v0.29.0 h1:WdYw2tdTK1S8olAzWHdgeqfy+Mtm9XNhv/xJsY65d98=
golang.org/x/oauth2 v0.29.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -411,8 +412,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610=
golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -599,8 +600,8 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=

View File

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

View File

@ -9,7 +9,7 @@
"version": "0.0.0",
"license": "MIT",
"devDependencies": {
"aws-cdk": "^2.1006.0",
"aws-cdk": "^2.1007.0",
"cross-env": "^7.0.3"
},
"engines": {
@ -17,9 +17,9 @@
}
},
"node_modules/aws-cdk": {
"version": "2.1006.0",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1006.0.tgz",
"integrity": "sha512-6qYnCt4mBN+3i/5F+FC2yMETkDHY/IL7gt3EuqKVPcaAO4jU7oXfVSlR60CYRkZWL4fnAurUV14RkJuJyVG/IA==",
"version": "2.1007.0",
"resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1007.0.tgz",
"integrity": "sha512-/UOYOTGWUm+pP9qxg03tID5tL6euC+pb+xo0RBue+xhnUWwj/Bbsw6DbqbpOPMrNzTUxmM723/uMEQmM6S26dw==",
"dev": true,
"license": "Apache-2.0",
"bin": {

View File

@ -10,7 +10,7 @@
"node": ">=20"
},
"devDependencies": {
"aws-cdk": "^2.1006.0",
"aws-cdk": "^2.1007.0",
"cross-env": "^7.0.3"
}
}

View File

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

View File

@ -6,23 +6,23 @@
# Translators:
# Dario Rigolin, 2022
# aoor9, 2023
# Matteo Piccina <altermatte@gmail.com>, 2024
# Enrico Campani, 2024
# Marco Vitale, 2024
# Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2024
# Nicola Mersi, 2024
# tmassimi, 2024
# Marc Schmitt, 2024
# albanobattistella <albanobattistella@gmail.com>, 2024
# Matteo Piccina <altermatte@gmail.com>, 2025
# Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-02-14 14:49+0000\n"
"POT-Creation-Date: 2025-03-31 00:10+0000\n"
"PO-Revision-Date: 2022-09-26 16:47+0000\n"
"Last-Translator: albanobattistella <albanobattistella@gmail.com>, 2024\n"
"Last-Translator: Kowalski Dragon (kowalski7cc) <kowalski.7cc@gmail.com>, 2025\n"
"Language-Team: Italian (https://app.transifex.com/authentik/teams/119923/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -130,6 +130,10 @@ msgstr "L'utente non ha accesso all'applicazione."
msgid "Extra description not available"
msgstr "Descrizione extra non disponibile"
#: authentik/core/api/groups.py
msgid "Cannot set group as parent of itself."
msgstr "Impossibile impostare il gruppo come padre di se stesso."
#: authentik/core/api/providers.py
msgid ""
"When not set all providers are returned. When set to true, only backchannel "
@ -177,6 +181,14 @@ msgstr "Aggiungi utente al gruppo"
msgid "Remove user from group"
msgstr "Rimuovi l'utente dal gruppo"
#: authentik/core/models.py
msgid "Enable superuser status"
msgstr "Abilita stato di superutente"
#: authentik/core/models.py
msgid "Disable superuser status"
msgstr "Disabilita stato di superutente"
#: authentik/core/models.py
msgid "User's display name."
msgstr "Nome visualizzato dell'utente."
@ -260,11 +272,11 @@ msgstr "Applicazioni"
#: authentik/core/models.py
msgid "Application Entitlement"
msgstr ""
msgstr "Entitlement Applicazione"
#: authentik/core/models.py
msgid "Application Entitlements"
msgstr ""
msgstr "Entitlements Applicazione"
#: authentik/core/models.py
msgid "Use the source-specific identifier"
@ -551,62 +563,6 @@ msgstr "Mappatura Microsoft Entra Provider"
msgid "Microsoft Entra Provider Mappings"
msgstr "Mappature Microsoft Entra Provider"
#: authentik/enterprise/providers/rac/models.py
#: authentik/stages/user_login/models.py
msgid ""
"Determines how long a session lasts. Default of 0 means that the sessions "
"lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
msgstr ""
"Determina quanto può durare una sessione. Se impostato a 0, la sessione "
"durerà fino alla chiusura del browser. (Formato: "
"hours=-1;minutes=-2;seconds=-3)"
#: authentik/enterprise/providers/rac/models.py
msgid "When set to true, connection tokens will be deleted upon disconnect."
msgstr ""
"Se impostato su vero, i token di connessione verranno eliminati alla "
"disconnessione."
#: authentik/enterprise/providers/rac/models.py
msgid "RAC Provider"
msgstr "Fornitore di controllo dell'accesso remoto"
#: authentik/enterprise/providers/rac/models.py
msgid "RAC Providers"
msgstr "Fornitori di controllo dell'accesso remoto"
#: authentik/enterprise/providers/rac/models.py
msgid "RAC Endpoint"
msgstr "Endpoint RAC"
#: authentik/enterprise/providers/rac/models.py
msgid "RAC Endpoints"
msgstr "Endpoints RAC"
#: authentik/enterprise/providers/rac/models.py
msgid "RAC Provider Property Mapping"
msgstr "Mappatura delle proprietà del provider RAC"
#: authentik/enterprise/providers/rac/models.py
msgid "RAC Provider Property Mappings"
msgstr "Mappature proprietà del provider RAC"
#: authentik/enterprise/providers/rac/models.py
msgid "RAC Connection token"
msgstr "RAC Connection token"
#: authentik/enterprise/providers/rac/models.py
msgid "RAC Connection tokens"
msgstr "RAC Connection tokens"
#: authentik/enterprise/providers/rac/views.py
msgid "Maximum connection limit reached."
msgstr "Limite massimo di connessioni raggiunto."
#: authentik/enterprise/providers/rac/views.py
msgid "(You are already connected in another tab/window)"
msgstr "(Sei già connesso in un'altra scheda/finestra)"
#: authentik/enterprise/providers/ssf/models.py
#: authentik/providers/oauth2/models.py
msgid "Signing Key"
@ -614,39 +570,39 @@ msgstr "Chiave di firma"
#: authentik/enterprise/providers/ssf/models.py
msgid "Key used to sign the SSF Events."
msgstr ""
msgstr "Chiave utilizzata per firmare gli eventi SSF."
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Provider"
msgstr ""
msgstr "Fornitore Shared Signals Framework"
#: authentik/enterprise/providers/ssf/models.py
msgid "Shared Signals Framework Providers"
msgstr ""
msgstr "Fornitori Shared Signals Framework"
#: authentik/enterprise/providers/ssf/models.py
msgid "Add stream to SSF provider"
msgstr ""
msgstr "Aggiungi Stream al provider SSF"
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream"
msgstr ""
msgstr "SSF Stream"
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Streams"
msgstr ""
msgstr "SSF Streams"
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Event"
msgstr ""
msgstr "Evento di Stream SSF"
#: authentik/enterprise/providers/ssf/models.py
msgid "SSF Stream Events"
msgstr ""
msgstr "Eventi di Stream SSF"
#: authentik/enterprise/providers/ssf/tasks.py
msgid "Failed to send request"
msgstr ""
msgstr "Impossibile inviare la richiesta"
#: authentik/enterprise/stages/authenticator_endpoint_gdtc/models.py
msgid "Endpoint Authenticator Google Device Trust Connector Stage"
@ -712,9 +668,26 @@ msgid "Slack Webhook (Slack/Discord)"
msgstr "Slack Webhook (Slack/Discord)"
#: authentik/events/models.py
#: authentik/stages/authenticator_validate/models.py
msgid "Email"
msgstr "Email"
#: authentik/events/models.py
msgid ""
"Customize the body of the request. Mapping should return data that is JSON-"
"serializable."
msgstr ""
"Personalizza il corpo della richiesta. Il mapping dovrebbe restituire dati "
"serializzabili in JSON."
#: authentik/events/models.py
msgid ""
"Configure additional headers to be sent. Mapping should return a dictionary "
"of key-value pairs"
msgstr ""
"Configurare le intestazioni aggiuntive da inviare. Il mapping dovrebbe "
"restituire un dizionario di coppie chiave-valore."
#: authentik/events/models.py
msgid ""
"Only send notification once, for example when sending a webhook into a chat "
@ -944,7 +917,7 @@ msgstr ""
#: authentik/flows/models.py
msgid "Evaluate policies when the Stage is presented to the user."
msgstr ""
msgstr "Valutare i criteri quando la fase viene presentata all'utente."
#: authentik/flows/models.py
msgid ""
@ -986,6 +959,14 @@ msgstr "Tokens del flusso"
msgid "Invalid next URL"
msgstr "URL successivo non valido"
#: authentik/lib/sync/outgoing/models.py
msgid ""
"When enabled, provider will not modify or create objects in the remote "
"system."
msgstr ""
"Quando abilitato, il provider non modificherà o creerà oggetti nel sistema "
"remoto."
#: authentik/lib/sync/outgoing/tasks.py
msgid "Starting full provider sync"
msgstr "Avvio della sincronizzazione completa del provider"
@ -1000,6 +981,10 @@ msgstr "Sincronizzando pagina {page} degli utenti"
msgid "Syncing page {page} of groups"
msgstr "Sincronizzando pagina {page} dei gruppi"
#: authentik/lib/sync/outgoing/tasks.py
msgid "Dropping mutating request due to dry run"
msgstr "Richiesta di mutazione ignorata a causa della prova di funzionamento"
#: authentik/lib/sync/outgoing/tasks.py
#, python-brace-format
msgid "Stopping sync due to error: {error}"
@ -1212,6 +1197,14 @@ msgstr "GeoIP: indirizzo IP del client non trovato nel database della città."
msgid "Client IP is not in an allowed country."
msgstr "L'IP del client non si trova in un paese consentito."
#: authentik/policies/geoip/models.py
msgid "Distance from previous authentication is larger than threshold."
msgstr "La distanza dall'autenticazione precedente è maggiore della soglia."
#: authentik/policies/geoip/models.py
msgid "Distance is further than possible."
msgstr "La distanza è maggiore del possibile."
#: authentik/policies/geoip/models.py
msgid "GeoIP Policy"
msgstr "Criterio GeoIP"
@ -1344,6 +1337,22 @@ msgstr "Punteggio di reputazione"
msgid "Reputation Scores"
msgstr "Punteggi di reputazione"
#: authentik/policies/templates/policies/buffer.html
msgid "Waiting for authentication..."
msgstr "In attesa di autenticazione..."
#: authentik/policies/templates/policies/buffer.html
msgid ""
"You're already authenticating in another tab. This page will refresh once "
"authentication is completed."
msgstr ""
"Ti stai già autenticando in un'altra scheda. Questa pagina si aggiornerà una"
" volta completata l'autenticazione."
#: authentik/policies/templates/policies/buffer.html
msgid "Authenticate in this tab"
msgstr "Autenticati in questa scheda"
#: authentik/policies/templates/policies/denied.html
msgid "Permission denied"
msgstr "Permesso negato"
@ -1531,6 +1540,14 @@ msgstr "RS256 (Crittografia Asimmetrica)"
msgid "ES256 (Asymmetric Encryption)"
msgstr "ES256 (Crittografia Asimmetrica)"
#: authentik/providers/oauth2/models.py
msgid "ES384 (Asymmetric Encryption)"
msgstr "ES384 (Crittografia Asimmetrica)"
#: authentik/providers/oauth2/models.py
msgid "ES512 (Asymmetric Encryption)"
msgstr "ES512 (Crittografia Asimmetrica)"
#: authentik/providers/oauth2/models.py
msgid "Scope used by the client"
msgstr "Scope usato dall'utente"
@ -1814,6 +1831,61 @@ msgstr "Provider Proxy"
msgid "Proxy Providers"
msgstr "Providers Proxy"
#: authentik/providers/rac/models.py authentik/stages/user_login/models.py
msgid ""
"Determines how long a session lasts. Default of 0 means that the sessions "
"lasts until the browser is closed. (Format: hours=-1;minutes=-2;seconds=-3)"
msgstr ""
"Determina quanto può durare una sessione. Se impostato a 0, la sessione "
"durerà fino alla chiusura del browser. (Formato: "
"hours=-1;minutes=-2;seconds=-3)"
#: authentik/providers/rac/models.py
msgid "When set to true, connection tokens will be deleted upon disconnect."
msgstr ""
"Se impostato su vero, i token di connessione verranno eliminati alla "
"disconnessione."
#: authentik/providers/rac/models.py
msgid "RAC Provider"
msgstr "Fornitore di controllo dell'accesso remoto"
#: authentik/providers/rac/models.py
msgid "RAC Providers"
msgstr "Fornitori di controllo dell'accesso remoto"
#: authentik/providers/rac/models.py
msgid "RAC Endpoint"
msgstr "Endpoint RAC"
#: authentik/providers/rac/models.py
msgid "RAC Endpoints"
msgstr "Endpoints RAC"
#: authentik/providers/rac/models.py
msgid "RAC Provider Property Mapping"
msgstr "Mappatura delle proprietà del provider RAC"
#: authentik/providers/rac/models.py
msgid "RAC Provider Property Mappings"
msgstr "Mappature proprietà del provider RAC"
#: authentik/providers/rac/models.py
msgid "RAC Connection token"
msgstr "RAC Connection token"
#: authentik/providers/rac/models.py
msgid "RAC Connection tokens"
msgstr "RAC Connection tokens"
#: authentik/providers/rac/views.py
msgid "Maximum connection limit reached."
msgstr "Limite massimo di connessioni raggiunto."
#: authentik/providers/rac/views.py
msgid "(You are already connected in another tab/window)"
msgstr "(Sei già connesso in un'altra scheda/finestra)"
#: authentik/providers/radius/models.py
msgid "Shared secret between clients and server to hash packets."
msgstr "Segreto condiviso tra client e server per hashare i pacchetti."
@ -1901,6 +1973,20 @@ msgstr ""
"Configura il modo in cui verrà creato il valore NameID. Se lasciato vuoto, "
"verrà considerato il NameIDPolicy della richiesta in arrivo"
#: authentik/providers/saml/models.py
msgid "AuthnContextClassRef Property Mapping"
msgstr "Mapping delle proprietà AuthnContextClassRef"
#: authentik/providers/saml/models.py
msgid ""
"Configure how the AuthnContextClassRef value will be created. When left "
"empty, the AuthnContextClassRef will be set based on which authentication "
"methods the user used to authenticate."
msgstr ""
"Configura come verrà creato il valore AuthnContextClassRef. Se lasciato "
"vuoto, AuthnContextClassRef verrà impostato in base ai metodi di "
"autenticazione utilizzati dall'utente."
#: authentik/providers/saml/models.py
msgid ""
"Assertion valid not before current time + this value (Format: "
@ -2042,6 +2128,18 @@ msgstr "Provider SAML dai Metadati"
msgid "SAML Providers from Metadata"
msgstr "Providers SAML dai Metadati"
#: authentik/providers/scim/models.py
msgid "Default"
msgstr "Predefinito"
#: authentik/providers/scim/models.py
msgid "AWS"
msgstr "AWS"
#: authentik/providers/scim/models.py
msgid "Slack"
msgstr "Slack"
#: authentik/providers/scim/models.py
msgid "Base URL to SCIM requests, usually ends in /v2"
msgstr "URL di base per le richieste SCIM, di solito termina con /v2"
@ -2050,6 +2148,16 @@ msgstr "URL di base per le richieste SCIM, di solito termina con /v2"
msgid "Authentication token"
msgstr "Token di autenticazione"
#: authentik/providers/scim/models.py
msgid "SCIM Compatibility Mode"
msgstr "SCIM Modalità di Compatibilità"
#: authentik/providers/scim/models.py
msgid "Alter authentik behavior for vendor-specific SCIM implementations."
msgstr ""
"Modifica il comportamento di autenticazione per le implementazioni SCIM "
"specifiche del fornitore."
#: authentik/providers/scim/models.py
msgid "SCIM Provider"
msgstr "Privider SCIM"
@ -2125,7 +2233,7 @@ msgstr ""
#: authentik/sources/kerberos/models.py
msgid "KAdmin server type"
msgstr ""
msgstr "Tipo server KAdmin"
#: authentik/sources/kerberos/models.py
msgid "Sync users from Kerberos into authentik"
@ -2730,6 +2838,117 @@ msgstr "Dispositivo Duo"
msgid "Duo Devices"
msgstr "Dispositivi Duo"
#: authentik/stages/authenticator_email/models.py
msgid "Email OTP"
msgstr "Email OTP"
#: authentik/stages/authenticator_email/models.py
#: authentik/stages/email/models.py
msgid ""
"When enabled, global Email connection settings will be used and connection "
"settings below will be ignored."
msgstr ""
"Se abilitato, verranno utilizzate le impostazioni di connessione e-mail "
"globali e le impostazioni di connessione riportate di seguito verranno "
"ignorate."
#: authentik/stages/authenticator_email/models.py
#: authentik/stages/email/models.py
msgid "Time the token sent is valid (Format: hours=3,minutes=17,seconds=300)."
msgstr ""
"Tempo di validità del token inviato (formato: "
"hours=3,minutes=17,seconds=300)."
#: authentik/stages/authenticator_email/models.py
msgid "Email Authenticator Setup Stage"
msgstr "Fase di configurazione dell'autenticatore email"
#: authentik/stages/authenticator_email/models.py
msgid "Email Authenticator Setup Stages"
msgstr "Fasi di configurazione dell'autenticatore email"
#: authentik/stages/authenticator_email/models.py
#: authentik/stages/authenticator_email/stage.py
#: authentik/stages/email/stage.py
msgid "Exception occurred while rendering E-mail template"
msgstr ""
"Eccezione verificatasi durante la visualizzazione del modello di posta "
"elettronica"
#: authentik/stages/authenticator_email/models.py
msgid "Email Device"
msgstr "Dispositivo email"
#: authentik/stages/authenticator_email/models.py
msgid "Email Devices"
msgstr "Dispositivi email"
#: authentik/stages/authenticator_email/stage.py
#: authentik/stages/authenticator_sms/stage.py
#: authentik/stages/authenticator_totp/stage.py
msgid "Code does not match"
msgstr "Il codice non corrisponde"
#: authentik/stages/authenticator_email/stage.py
msgid "Invalid email"
msgstr "Email non valida"
#: authentik/stages/authenticator_email/templates/email/email_otp.html
#: authentik/stages/email/templates/email/password_reset.html
#, python-format
msgid ""
"\n"
" Hi %(username)s,\n"
" "
msgstr ""
"\n"
" Ciao %(username)s,\n"
" "
#: authentik/stages/authenticator_email/templates/email/email_otp.html
msgid ""
"\n"
" Email MFA code.\n"
" "
msgstr ""
"\n"
" Codice MFA via e-mail.\n"
" "
#: authentik/stages/authenticator_email/templates/email/email_otp.html
#, python-format
msgid ""
"\n"
" If you did not request this code, please ignore this email. The code above is valid for %(expires)s.\n"
" "
msgstr ""
"\n"
" Se non hai richiesto questo codice, ignora questa email. Il codice sopra riportato è valido per %(expires)s.\n"
" "
#: authentik/stages/authenticator_email/templates/email/email_otp.txt
#: authentik/stages/email/templates/email/password_reset.txt
#, python-format
msgid "Hi %(username)s,"
msgstr "Ciao %(username)s,"
#: authentik/stages/authenticator_email/templates/email/email_otp.txt
msgid ""
"\n"
"Email MFA code\n"
msgstr ""
"\n"
"Codice e-mail MFA\n"
#: authentik/stages/authenticator_email/templates/email/email_otp.txt
#, python-format
msgid ""
"\n"
"If you did not request this code, please ignore this email. The code above is valid for %(expires)s.\n"
msgstr ""
"\n"
"Se non hai richiesto questo codice, ignora questa email. Il codice sopra riportato è valido per %(expires)s.\n"
#: authentik/stages/authenticator_sms/models.py
msgid ""
"When enabled, the Phone number is only used during enrollment to verify the "
@ -2768,11 +2987,6 @@ msgstr "Dispositivo SMS"
msgid "SMS Devices"
msgstr "Dispositivi SMS"
#: authentik/stages/authenticator_sms/stage.py
#: authentik/stages/authenticator_totp/stage.py
msgid "Code does not match"
msgstr "Il codice non corrisponde"
#: authentik/stages/authenticator_sms/stage.py
msgid "Invalid phone number"
msgstr "Numero di telefono non valido"
@ -3013,23 +3227,10 @@ msgstr "Ripristino password"
msgid "Account Confirmation"
msgstr "Conferma dell'account"
#: authentik/stages/email/models.py
msgid ""
"When enabled, global Email connection settings will be used and connection "
"settings below will be ignored."
msgstr ""
"Se abilitato, verranno utilizzate le impostazioni di connessione e-mail "
"globali e le impostazioni di connessione riportate di seguito verranno "
"ignorate."
#: authentik/stages/email/models.py
msgid "Activate users upon completion of stage."
msgstr "Attiva gli utenti al completamento della fase."
#: authentik/stages/email/models.py
msgid "Time in minutes the token sent is valid."
msgstr "Tempo in minuti in cui il token inviato è valido."
#: authentik/stages/email/models.py
msgid "Email Stage"
msgstr "Fase email"
@ -3038,12 +3239,6 @@ msgstr "Fase email"
msgid "Email Stages"
msgstr "Fasi Email"
#: authentik/stages/email/stage.py
msgid "Exception occurred while rendering E-mail template"
msgstr ""
"Eccezione verificatasi durante la visualizzazione del modello di posta "
"elettronica"
#: authentik/stages/email/stage.py
msgid "Successfully verified Email."
msgstr "Email verificato con successo."
@ -3127,17 +3322,6 @@ msgstr ""
"\n"
"Questa email è stata inviata dal trasporto delle notifiche %(name)s.\n"
#: authentik/stages/email/templates/email/password_reset.html
#, python-format
msgid ""
"\n"
" Hi %(username)s,\n"
" "
msgstr ""
"\n"
" Ciao %(username)s,\n"
" "
#: authentik/stages/email/templates/email/password_reset.html
msgid ""
"\n"
@ -3158,11 +3342,6 @@ msgstr ""
" Se non hai richiesto una modifica della password, ignora questa e-mail. Il link sopra è valido per %(expires)s.\n"
" "
#: authentik/stages/email/templates/email/password_reset.txt
#, python-format
msgid "Hi %(username)s,"
msgstr "Ciao %(username)s,"
#: authentik/stages/email/templates/email/password_reset.txt
msgid ""
"\n"
@ -3492,6 +3671,7 @@ msgstr ""
#: authentik/stages/redirect/api.py
msgid "Target Flow should be present when mode is Flow."
msgstr ""
"Il flusso target dovrebbe essere presente quando la modalità è Flusso."
#: authentik/stages/redirect/models.py
msgid "Redirect Stage"

Binary file not shown.

View File

@ -1,5 +1,5 @@
{
"name": "@goauthentik/authentik",
"version": "2025.2.3",
"version": "2025.2.4",
"private": true
}

View File

@ -0,0 +1,11 @@
/**
* @file TypeScript type definitions for eslint-plugin-react-hooks
*/
declare module "eslint-plugin-react-hooks" {
import { ESLint } from "eslint";
// We have to do this because ESLint aliases the namespace and class simultaneously.
type PluginInstance = ESLint.Plugin;
const Plugin: PluginInstance;
export default Plugin;
}

View File

@ -0,0 +1,11 @@
/**
* @file TypeScript type definitions for eslint-plugin-react
*/
declare module "eslint-plugin-react" {
import { ESLint } from "eslint";
// We have to do this because ESLint aliases the namespace and class simultaneously.
type PluginInstance = ESLint.Plugin;
const Plugin: PluginInstance;
export default Plugin;
}

View File

@ -0,0 +1,18 @@
The MIT License (MIT)
Copyright (c) 2025 Authentik Security, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,5 @@
# `@goauthentik/eslint-config`
This package contains the ESLint configuration used by authentik.
While it is possible to use this configuration outside of our projects,
you may find that it is not as useful as other popular configurations.

View File

@ -0,0 +1,72 @@
import eslint from "@eslint/js";
import { javaScriptConfig } from "@goauthentik/eslint-config/javascript-config";
import { reactConfig } from "@goauthentik/eslint-config/react-config";
import { typescriptConfig } from "@goauthentik/eslint-config/typescript-config";
import * as litconf from "eslint-plugin-lit";
import * as wcconf from "eslint-plugin-wc";
import tseslint from "typescript-eslint";
// @ts-check
/**
* @typedef ESLintPackageConfigOptions Options for creating package ESLint configuration.
* @property {string[]} [ignorePatterns] Override ignore patterns for ESLint.
*/
/**
* @type {string[]} Default Ignore patterns for ESLint.
*/
export const DefaultIgnorePatterns = [
// ---
"**/*.md",
"**/out",
"**/dist",
"**/.wireit",
"website/build/**",
"website/.docusaurus/**",
"**/node_modules",
"**/coverage",
"**/storybook-static",
"**/locale-codes.ts",
"**/src/locales",
"**/gen-ts-api",
];
/**
* Given a preferred package name, creates a ESLint configuration object.
*
* @param {ESLintPackageConfigOptions} options The preferred package configuration options.
*
* @returns The ESLint configuration object.
*/
export function createESLintPackageConfig({ ignorePatterns = DefaultIgnorePatterns } = {}) {
return tseslint.config(
{
ignores: ignorePatterns,
},
eslint.configs.recommended,
javaScriptConfig,
wcconf.configs["flat/recommended"],
litconf.configs["flat/recommended"],
...tseslint.configs.recommended,
...typescriptConfig,
...reactConfig,
{
rules: {
"no-console": "off",
},
files: [
// ---
"**/scripts/**/*",
"**/test/**/*",
"**/tests/**/*",
],
},
);
}

View File

@ -0,0 +1,143 @@
// @ts-check
import tseslint from "typescript-eslint";
const MAX_DEPTH = 4;
const MAX_NESTED_CALLBACKS = 4;
const MAX_PARAMS = 5;
/**
* ESLint configuration for JavaScript authentik projects.
*/
export const javaScriptConfig = tseslint.config({
rules: {
// TODO: Clean up before enabling.
"accessor-pairs": "off",
"array-callback-return": "error",
"block-scoped-var": "error",
"consistent-return": ["error", { treatUndefinedAsUnspecified: false }],
"consistent-this": ["error", "that"],
"curly": "off",
"dot-notation": [
"error",
{
allowKeywords: true,
},
],
"eqeqeq": "error",
"func-names": ["error", "as-needed"],
"guard-for-in": "error",
"max-depth": ["error", MAX_DEPTH],
"max-nested-callbacks": ["error", MAX_NESTED_CALLBACKS],
"max-params": ["error", MAX_PARAMS],
// TODO: Clean up before enabling.
// "new-cap": "error",
"no-alert": "error",
"no-array-constructor": "error",
"no-bitwise": [
"error",
{
allow: ["~"],
int32Hint: true,
},
],
"no-caller": "error",
"no-case-declarations": "error",
"no-class-assign": "error",
"no-cond-assign": "error",
"no-const-assign": "error",
"no-constant-condition": "error",
"no-control-regex": "error",
"no-debugger": "error",
"no-delete-var": "error",
"no-div-regex": "error",
"no-dupe-args": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-else-return": "error",
"no-empty": "error",
"no-empty-character-class": "error",
"no-empty-function": ["error", { allow: ["constructors"] }],
"no-labels": "error",
"no-eq-null": "error",
"no-eval": "error",
"no-ex-assign": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-boolean-cast": "error",
"no-extra-label": "error",
"no-fallthrough": "error",
"no-func-assign": "error",
"no-implied-eval": "error",
"no-implicit-coercion": "error",
"no-implicit-globals": "error",
"no-inner-declarations": ["error", "functions"],
"no-invalid-regexp": "error",
"no-irregular-whitespace": "error",
"no-iterator": "error",
"no-label-var": "error",
"no-lone-blocks": "error",
"no-lonely-if": "error",
"no-loop-func": "error",
"no-multi-str": "error",
// TODO: Clean up before enabling.
"no-negated-condition": "off",
"no-new": "error",
"no-new-func": "error",
"no-new-wrappers": "error",
"no-obj-calls": "error",
"no-octal": "error",
"no-octal-escape": "error",
"no-param-reassign": ["error", { props: false }],
"no-proto": "error",
"no-redeclare": "error",
"no-regex-spaces": "error",
"no-restricted-syntax": ["error", "WithStatement"],
"no-script-url": "error",
"no-self-assign": "error",
"no-self-compare": "error",
"no-sequences": "error",
// TODO: Clean up before enabling.
// "no-shadow": "error",
"no-shadow-restricted-names": "error",
"no-sparse-arrays": "error",
"no-this-before-super": "error",
"no-throw-literal": "error",
"no-trailing-spaces": "off", // Handled by Prettier.
"no-undef": "off",
"no-undef-init": "off",
"no-unexpected-multiline": "error",
"no-useless-constructor": "error",
"no-unmodified-loop-condition": "error",
"no-unneeded-ternary": "error",
"no-unreachable": "error",
"no-unused-expressions": "error",
"no-unused-labels": "error",
"no-use-before-define": "error",
"no-useless-call": "error",
"no-dupe-class-members": "error",
"no-var": "error",
"no-void": "error",
"no-with": "error",
"prefer-arrow-callback": "error",
"prefer-const": "error",
"prefer-rest-params": "error",
"prefer-spread": "error",
"prefer-template": "error",
"radix": "error",
"require-yield": "error",
"strict": ["error", "global"],
"use-isnan": "error",
"valid-typeof": "error",
"vars-on-top": "error",
"yoda": ["error", "never"],
"no-console": ["error", { allow: ["debug", "warn", "error"] }],
// SonarJS is not yet compatible with ESLint 9. Commenting these out
// until it is.
// "sonarjs/cognitive-complexity": ["off", MAX_COGNITIVE_COMPLEXITY],
// "sonarjs/no-duplicate-string": "off",
// "sonarjs/no-nested-template-literals": "off",
},
});
export default javaScriptConfig;

View File

@ -0,0 +1,53 @@
{
"name": "@goauthentik/eslint-config",
"version": "1.0.0",
"description": "authentik's ESLint config",
"license": "MIT",
"type": "module",
"exports": {
"./package.json": "./package.json",
".": {
"import": "./index.js",
"types": "./out/index.d.ts"
},
"./react-config": {
"import": "./react-config.js",
"types": "./out/react-config.d.ts"
},
"./javascript-config": {
"import": "./javascript-config.js",
"types": "./out/javascript-config.d.ts"
},
"./typescript-config": {
"import": "./typescript-config.js",
"types": "./out/typescript-config.d.ts"
}
},
"dependencies": {
"eslint": "^9.23.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-react": "^7.37.4",
"eslint-plugin-react-hooks": "^5.2.0"
},
"devDependencies": {
"@goauthentik/tsconfig": "1.0.0",
"@types/eslint": "^9.6.1",
"typescript": "^5.8.2",
"typescript-eslint": "^8.29.0"
},
"peerDependencies": {
"typescript": "^5.8.2",
"typescript-eslint": "^8.29.0"
},
"optionalDependencies": {
"react": "^18.3.1"
},
"engines": {
"node": ">=20.11"
},
"types": "./out/index.d.ts",
"prettier": "@goauthentik/prettier-config",
"publishConfig": {
"access": "public"
}
}

34
packages/eslint-config/react-config.js vendored Normal file
View File

@ -0,0 +1,34 @@
import reactPlugin from "eslint-plugin-react";
import hooksPlugin from "eslint-plugin-react-hooks";
import tseslint from "typescript-eslint";
/**
* ESLint configuration for React authentik projects.
*/
export const reactConfig = tseslint.config({
settings: {
react: {
version: "detect",
},
},
plugins: {
"react": reactPlugin,
"react-hooks": hooksPlugin,
},
rules: {
"react-hooks/rules-of-hooks": "error",
"react-hooks/exhaustive-deps": "warn",
"react/jsx-uses-react": 0,
"react/display-name": "off",
"react/jsx-curly-brace-presence": "error",
"react/jsx-no-leaked-render": "error",
"react/prop-types": "off",
"react/react-in-jsx-scope": "off",
},
});
export default reactConfig;

View File

@ -0,0 +1,8 @@
{
"extends": "@goauthentik/tsconfig",
"compilerOptions": {
"baseUrl": ".",
"checkJs": true,
"emitDeclarationOnly": true
}
}

View File

@ -0,0 +1,35 @@
// @ts-check
import tseslint from "typescript-eslint";
/**
* ESLint configuration for TypeScript authentik projects.
*/
export const typescriptConfig = tseslint.config({
rules: {
"@typescript-eslint/ban-ts-comment": [
"error",
{
"ts-expect-error": "allow-with-description",
"ts-ignore": true,
"ts-nocheck": "allow-with-description",
"ts-check": false,
"minimumDescriptionLength": 5,
},
],
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": "error",
"no-invalid-this": "off",
"no-unused-vars": "off",
"@typescript-eslint/no-namespace": "off",
"@typescript-eslint/no-unused-vars": [
"warn",
{
argsIgnorePattern: "^_",
varsIgnorePattern: "^_",
caughtErrorsIgnorePattern: "^_",
},
],
},
});
export default typescriptConfig;

View File

@ -0,0 +1,18 @@
The MIT License (MIT)
Copyright (c) 2025 Authentik Security, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,5 @@
# `@goauthentik/monorepo`
This package contains utility scripts common to all TypeScript and JavaScript packages in the
`@goauthentik` monorepo.

View File

@ -0,0 +1,17 @@
/**
* @file Constants for JavaScript and TypeScript files.
*
*/
/**
* The current Node.js environment, defaulting to "development" when not set.
*
* Note, this should only be used during the build process.
*
* If you need to check the environment at runtime, use `process.env.NODE_ENV` to
* ensure that module tree-shaking works correctly.
*
*/
export const NodeEnvironment = /** @type {'development' | 'production'} */ (
process.env.NODE_ENV || "development"
);

View File

@ -0,0 +1,4 @@
export * from "./paths.js";
export * from "./constants.js";
export * from "./version.js";
export * from "./scripting.js";

View File

@ -0,0 +1,19 @@
{
"name": "@goauthentik/monorepo",
"version": "1.0.0",
"description": "Utilities for the authentik monorepo.",
"private": true,
"license": "MIT",
"type": "module",
"exports": {
"./package.json": "./package.json",
".": {
"import": "./index.js",
"types": "./out/index.d.ts"
}
},
"types": "./out/index.d.ts",
"engines": {
"node": ">=20.11"
}
}

View File

@ -0,0 +1,30 @@
import { createRequire } from "node:module";
import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
/**
* @typedef {'~authentik'} MonoRepoRoot
*/
/**
* The root of the authentik monorepo.
*/
export const MonoRepoRoot = /** @type {MonoRepoRoot} */ (resolve(__dirname, "..", ".."));
const require = createRequire(import.meta.url);
/**
* Resolve a package name to its location in the monorepo to the single node_modules directory.
* @param {string} packageName
* @returns {string} The resolved path to the package.
* @throws {Error} If the package cannot be resolved.
*/
export function resolvePackage(packageName) {
const packageJSONPath = require.resolve(join(packageName, "package.json"), {
paths: [MonoRepoRoot],
});
return dirname(packageJSONPath);
}

View File

@ -0,0 +1,40 @@
import { createRequire } from "node:module";
import * as path from "node:path";
import * as process from "node:process";
import { fileURLToPath } from "node:url";
/**
* Predicate to determine if a module was run directly, i.e. not imported.
*
* @param {ImportMeta} meta The `import.meta` object of the module.
*
* @return {boolean} Whether the module was run directly.
*/
export function isMain(meta) {
// Are we not in a module context?
if (!meta) return false;
const relativeScriptPath = process.argv[1];
if (!relativeScriptPath) return false;
const require = createRequire(meta.url);
const absoluteScriptPath = require.resolve(relativeScriptPath);
const modulePath = fileURLToPath(meta.url);
const scriptExtension = path.extname(absoluteScriptPath);
if (scriptExtension) {
return modulePath === absoluteScriptPath;
}
const moduleExtension = path.extname(modulePath);
if (moduleExtension) {
return absoluteScriptPath === modulePath.slice(0, -moduleExtension.length);
}
// If both are without extension, compare them directly.
return modulePath === absoluteScriptPath;
}

View File

View File

@ -0,0 +1,9 @@
{
"extends": "@goauthentik/tsconfig",
"compilerOptions": {
"resolveJsonModule": true,
"baseUrl": ".",
"checkJs": true,
"emitDeclarationOnly": true
}
}

View File

@ -0,0 +1,45 @@
import { execSync } from "node:child_process";
import PackageJSON from "../../package.json" with { type: "json" };
import { MonoRepoRoot } from "./paths.js";
/**
* The current version of authentik in SemVer format.
*
*/
export const AuthentikVersion = /**@type {`${number}.${number}.${number}`} */ (PackageJSON.version);
/**
* Reads the last commit hash from the current git repository.
*/
export function readGitBuildHash() {
try {
const commit = execSync("git rev-parse HEAD", {
encoding: "utf8",
cwd: MonoRepoRoot,
})
.toString()
.trim();
return commit;
} catch (_error) {
console.debug("Git commit could not be read.");
}
return process.env.GIT_BUILD_HASH || "";
}
/**
* Reads the build identifier for the current environment.
*
* This must match the behavior defined in authentik's server-side `get_full_version` function.
*
* @see {@link "authentik\_\_init\_\_.py"}
*/
export function readBuildIdentifier() {
const { GIT_BUILD_HASH } = process.env;
if (!GIT_BUILD_HASH) return AuthentikVersion;
return [AuthentikVersion, GIT_BUILD_HASH].join("+");
}

View File

@ -0,0 +1,18 @@
The MIT License (MIT)
Copyright (c) 2025 Authentik Security, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,5 @@
# `@goauthentik/prettier-config`
This package contains the Prettier configuration used by authentik.
While it is possible to use this configuration outside of our projects,
you may find that it is not as useful as other popular configurations.

View File

@ -0,0 +1,80 @@
/**
* @file Prettier configuration for authentik.
*
* @import { Config as PrettierConfig } from "prettier";
* @import { PluginConfig as SortPluginConfig } from "@trivago/prettier-plugin-sort-imports";
*
* @typedef {object} PackageJSONPluginConfig
* @property {string[]} [packageSortOrder] Custom ordering array.
*/
/**
* authentik Prettier configuration.
*
* @type {PrettierConfig & SortPluginConfig & PackageJSONPluginConfig}
* @internal
*/
export const AuthentikPrettierConfig = {
arrowParens: "always",
bracketSpacing: true,
embeddedLanguageFormatting: "auto",
htmlWhitespaceSensitivity: "css",
insertPragma: false,
jsxSingleQuote: false,
printWidth: 100,
proseWrap: "preserve",
quoteProps: "consistent",
requirePragma: false,
semi: true,
singleQuote: false,
tabWidth: 4,
trailingComma: "all",
useTabs: false,
vueIndentScriptAndStyle: false,
plugins: ["prettier-plugin-packagejson", "@trivago/prettier-plugin-sort-imports"],
importOrder: ["^(@?)lit(.*)$", "\\.css$", "^@goauthentik/api$", "^[./]"],
importOrderSeparation: true,
importOrderSortSpecifiers: true,
importOrderParserPlugins: ["typescript", "jsx", "classProperties", "decorators-legacy"],
overrides: [
{
files: "schemas/**/*.json",
options: {
tabWidth: 2,
},
},
{
files: "tsconfig.json",
options: {
trailingComma: "none",
},
},
{
files: "package.json",
options: {
packageSortOrder: [
// ---
"name",
"version",
"description",
"license",
"private",
"author",
"authors",
"scripts",
"main",
"type",
"exports",
"imports",
"dependencies",
"devDependencies",
"peerDependencies",
"optionalDependencies",
"wireit",
"resolutions",
"engines",
],
},
},
],
};

View File

@ -0,0 +1,20 @@
import { format } from "prettier";
import { AuthentikPrettierConfig } from "./config.js";
/**
* Format using Prettier.
*
* Defaults to using the TypeScript parser.
*
* @category Formatting
* @param {string} fileContents The contents of the file to format.
*
* @returns {Promise<string>} The formatted file contents.
*/
export function formatWithPrettier(fileContents) {
return format(fileContents, {
...AuthentikPrettierConfig,
parser: "typescript",
});
}

View File

@ -0,0 +1,6 @@
import { AuthentikPrettierConfig } from "./config.js";
export * from "./config.js";
export * from "./format.js";
export default AuthentikPrettierConfig;

View File

@ -0,0 +1,27 @@
{
"name": "@goauthentik/prettier-config",
"version": "1.0.0",
"description": "authentik's Prettier config",
"license": "MIT",
"type": "module",
"exports": {
"./package.json": "./package.json",
".": {
"import": "./index.js",
"types": "./out/index.d.ts"
}
},
"types": "./out/index.d.ts",
"peerDependencies": {
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
"prettier": "^3.5.3",
"prettier-plugin-organize-imports": "^4.1.0",
"prettier-plugin-packagejson": "^2.5.10"
},
"engines": {
"node": ">=20.11"
},
"publishConfig": {
"access": "public"
}
}

View File

@ -0,0 +1,8 @@
{
"extends": "@goauthentik/tsconfig",
"compilerOptions": {
"baseUrl": ".",
"checkJs": true,
"emitDeclarationOnly": true
}
}

View File

@ -0,0 +1,18 @@
The MIT License (MIT)
Copyright (c) 2025 Authentik Security, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,6 @@
# `@goauthentik/tsconfig`
This package contains the TypeScript configuration used by authentik TypeScript projects.
While it is possible to use this configuration outside of our projects,
you may find that it is not as useful as other popular configurations.

View File

@ -0,0 +1,18 @@
{
"name": "@goauthentik/tsconfig",
"version": "1.0.0",
"description": "authentik's s base TypeScript configuration.",
"keywords": [
"tsconfig",
"typescript"
],
"license": "MIT",
"type": "module",
"main": "tsconfig.json",
"engines": {
"node": ">=20.11"
},
"publishConfig": {
"access": "public"
}
}

View File

@ -0,0 +1,29 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"compilerOptions": {
"alwaysStrict": true,
"baseUrl": ".",
"composite": true,
"declaration": true,
"declarationMap": true,
"esModuleInterop": false,
"isolatedModules": true,
"incremental": true,
"jsx": "react-jsx",
"lib": ["ESNext"],
"module": "NodeNext",
"moduleResolution": "NodeNext",
"newLine": "lf",
"noFallthroughCasesInSwitch": true,
"noImplicitOverride": false,
"outDir": "${configDir}/out",
"pretty": true,
"skipDefaultLibCheck": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"noUncheckedIndexedAccess": true,
"target": "ESNext",
"useUnknownInCatchVariables": true
}
}

View File

@ -1,6 +1,6 @@
[project]
name = "authentik"
version = "2025.2.3"
version = "2025.2.4"
description = ""
authors = [{ name = "authentik Team", email = "hello@goauthentik.io" }]
requires-python = "==3.12.*"
@ -52,7 +52,7 @@ dependencies = [
"pydantic-scim",
"pyjwt",
"pyrad",
"python-kadmin-rs ==0.5.3",
"python-kadmin-rs ==0.6.0",
"pyyaml",
"requests-oauthlib",
"scim2-filter-parser",

File diff suppressed because it is too large Load Diff

1314
uv.lock generated

File diff suppressed because it is too large Load Diff

8
web/package-lock.json generated
View File

@ -24,7 +24,7 @@
"@floating-ui/dom": "^1.6.11",
"@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.6.0",
"@goauthentik/api": "^2025.2.3-1743464496",
"@goauthentik/api": "^2025.2.4-1744139776",
"@lit-labs/ssr": "^3.2.2",
"@lit/context": "^1.1.2",
"@lit/localize": "^0.12.2",
@ -1835,9 +1835,9 @@
}
},
"node_modules/@goauthentik/api": {
"version": "2025.2.3-1743464496",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.2.3-1743464496.tgz",
"integrity": "sha512-35+SqFNoBZ+WNpyG2Xv/VKYKIIxjwRmIbgX5WZSpc9IlJVv7yyckUYvLpU2F0hZVUMDnxAUE5bsiNn7K4EQslw=="
"version": "2025.2.4-1744139776",
"resolved": "https://registry.npmjs.org/@goauthentik/api/-/api-2025.2.4-1744139776.tgz",
"integrity": "sha512-4CLjeW19Zc5/WhxOX/welwAI+YvyKp8cR4uBqLCScvyy/fTwB8dH2NnRj4eDv5U+OQpAwdKXZCBY16fWGg0/kg=="
},
"node_modules/@goauthentik/web": {
"resolved": "",

View File

@ -12,7 +12,7 @@
"@floating-ui/dom": "^1.6.11",
"@formatjs/intl-listformat": "^7.5.7",
"@fortawesome/fontawesome-free": "^6.6.0",
"@goauthentik/api": "^2025.2.3-1743464496",
"@goauthentik/api": "^2025.2.4-1744139776",
"@lit-labs/ssr": "^3.2.2",
"@lit/context": "^1.1.2",
"@lit/localize": "^0.12.2",

View File

@ -13,7 +13,6 @@ const MAX_PARAMS = 5;
// const MAX_COGNITIVE_COMPLEXITY = 9;
const rules = {
"no-param-reassign": "error",
"accessor-pairs": "error",
"array-callback-return": "error",
"block-scoped-var": "error",
@ -85,6 +84,7 @@ const rules = {
"no-obj-calls": "error",
"no-octal": "error",
"no-octal-escape": "error",
"no-param-reassign": "error",
"no-proto": "error",
"no-redeclare": "error",
"no-regex-spaces": "error",
@ -134,7 +134,6 @@ const rules = {
// "sonarjs/cognitive-complexity": ["off", MAX_COGNITIVE_COMPLEXITY],
// "sonarjs/no-duplicate-string": "off",
// "sonarjs/no-nested-template-literals": "off",
" @typescript-eslint/no-namespace": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unused-vars": [
"error",

View File

@ -48,7 +48,6 @@ export default [
// "sonarjs/no-duplicate-string": "off",
// "sonarjs/no-nested-template-literals": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/no-unused-vars": [
"error",
{

View File

@ -1,6 +1,6 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { VERSION } from "@goauthentik/common/constants";
import { globalAK } from "@goauthentik/common/global";
import { BrandConfig, ServerConfig } from "@goauthentik/common/global";
import "@goauthentik/elements/EmptyState";
import { WithBrandConfig } from "@goauthentik/elements/Interface/brandProvider";
import { WithLicenseSummary } from "@goauthentik/elements/Interface/licenseSummaryProvider";
@ -33,7 +33,7 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
const status = await new AdminApi(DEFAULT_CONFIG).adminSystemRetrieve();
const version = await new AdminApi(DEFAULT_CONFIG).adminVersionRetrieve();
let build: string | TemplateResult = msg("Release");
if (globalAK().config.capabilities.includes(CapabilitiesEnum.CanDebug)) {
if (ServerConfig.capabilities.includes(CapabilitiesEnum.CanDebug)) {
build = msg("Development");
} else if (version.buildHash !== "") {
build = html`<a
@ -58,8 +58,8 @@ export class AboutModal extends WithLicenseSummary(WithBrandConfig(ModalButton))
}
renderModal() {
let product = globalAK().brand.brandingTitle || DefaultBrand.brandingTitle;
if (this.licenseSummary.status !== LicenseSummaryStatusEnum.Unlicensed) {
let product = BrandConfig.brandingTitle || DefaultBrand.brandingTitle;
if (this.licenseSummary.status != LicenseSummaryStatusEnum.Unlicensed) {
product += ` ${msg("Enterprise")}`;
}
return html`<div

View File

@ -1,4 +1,5 @@
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { parseAPIResponseError, pluckErrorDetail } from "@goauthentik/common/errors/network";
import { MessageLevel } from "@goauthentik/common/messages";
import { AKElement } from "@goauthentik/elements/Base";
import "@goauthentik/elements/PageHeader";
@ -54,10 +55,12 @@ export class DebugPage extends AKElement {
message: "Success",
});
})
.catch((exc) => {
.catch(async (error) => {
const parsedError = await parseAPIResponseError(error);
showMessage({
level: MessageLevel.error,
message: exc,
message: pluckErrorDetail(parsedError),
});
});
}}

View File

@ -1,13 +1,16 @@
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { PFSize } from "@goauthentik/common/enums.js";
import {
APIError,
parseAPIResponseError,
pluckErrorDetail,
} from "@goauthentik/common/errors/network";
import { AggregateCard } from "@goauthentik/elements/cards/AggregateCard";
import { msg } from "@lit/localize";
import { PropertyValues, TemplateResult, html, nothing } from "lit";
import { state } from "lit/decorators.js";
import { ResponseError } from "@goauthentik/api";
export interface AdminStatus {
icon: string;
message?: TemplateResult;
@ -29,7 +32,7 @@ export abstract class AdminStatusCard<T> extends AggregateCard {
// Current error state if any request fails
@state()
protected error?: string;
protected error?: APIError;
// Abstract methods to be implemented by subclasses
abstract getPrimaryValue(): Promise<T>;
@ -59,9 +62,9 @@ export abstract class AdminStatusCard<T> extends AggregateCard {
this.value = value; // Triggers shouldUpdate
this.error = undefined;
})
.catch((err: ResponseError) => {
.catch(async (error: unknown) => {
this.status = undefined;
this.error = err?.response?.statusText ?? msg("Unknown error");
this.error = await parseAPIResponseError(error);
});
}
@ -79,9 +82,9 @@ export abstract class AdminStatusCard<T> extends AggregateCard {
this.status = status;
this.error = undefined;
})
.catch((err: ResponseError) => {
.catch(async (error: unknown) => {
this.status = undefined;
this.error = err?.response?.statusText ?? msg("Unknown error");
this.error = await parseAPIResponseError(error);
});
// Prevent immediate re-render if only value changed
@ -120,8 +123,8 @@ export abstract class AdminStatusCard<T> extends AggregateCard {
*/
private renderError(error: string): TemplateResult {
return html`
<p><i class="fa fa-times"></i>&nbsp;${error}</p>
<p class="subtext">${msg("Failed to fetch")}</p>
<p><i class="fa fa-times"></i>&nbsp;${msg("Failed to fetch")}</p>
<p class="subtext">${error}</p>
`;
}
@ -146,7 +149,7 @@ export abstract class AdminStatusCard<T> extends AggregateCard {
this.status
? this.renderStatus(this.status) // Status available
: this.error
? this.renderError(this.error) // Error state
? this.renderError(pluckErrorDetail(this.error)) // Error state
: this.renderLoading() // Loading state
}
</p>

View File

@ -2,7 +2,7 @@ import { EventGeo, EventUser } from "@goauthentik/admin/events/utils";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EventWithContext } from "@goauthentik/common/events";
import { actionToLabel } from "@goauthentik/common/labels";
import { getRelativeTime } from "@goauthentik/common/utils";
import { formatElapsedTime } from "@goauthentik/common/temporal";
import "@goauthentik/components/ak-event-info";
import "@goauthentik/elements/Tabs";
import "@goauthentik/elements/buttons/Dropdown";
@ -10,6 +10,7 @@ import "@goauthentik/elements/buttons/ModalButton";
import "@goauthentik/elements/buttons/SpinnerButton";
import { PaginatedResponse } from "@goauthentik/elements/table/Table";
import { Table, TableColumn } from "@goauthentik/elements/table/Table";
import { SlottedTemplateResult } from "@goauthentik/elements/types";
import { msg } from "@lit/localize";
import { CSSResult, TemplateResult, css, html } from "lit";
@ -68,12 +69,12 @@ export class RecentEventsCard extends Table<Event> {
</div>`;
}
row(item: EventWithContext): TemplateResult[] {
row(item: EventWithContext): SlottedTemplateResult[] {
return [
html`<div><a href="${`#/events/log/${item.pk}`}">${actionToLabel(item.action)}</a></div>
<small>${item.app}</small>`,
EventUser(item),
html`<div>${getRelativeTime(item.created)}</div>
html`<div>${formatElapsedTime(item.created)}</div>
<small>${item.created.toLocaleString()}</small>`,
html` <div>${item.clientIp || msg("-")}</div>
<small>${EventGeo(item)}</small>`,
@ -81,7 +82,11 @@ export class RecentEventsCard extends Table<Event> {
];
}
renderEmpty(): TemplateResult {
renderEmpty(inner?: SlottedTemplateResult): TemplateResult {
if (this.error) {
return super.renderEmpty(inner);
}
return super.renderEmpty(
html`<ak-empty-state header=${msg("No Events found.")}>
<div slot="body">${msg("No matching events could be found.")}</div>

View File

@ -46,7 +46,7 @@ export class SystemStatusCard extends AdminStatusCard<SystemInfo> {
return;
}
const outpost = outposts.results[0];
outpost.config.authentik_host = window.location.origin;
outpost.config["authentik_host"] = window.location.origin;
await new OutpostsApi(DEFAULT_CONFIG).outpostsInstancesUpdate({
uuid: outpost.pk,
outpostRequest: outpost,

View File

@ -28,18 +28,16 @@ export class WorkersStatusCard extends AdminStatusCard<Worker[]> {
icon: "fa fa-times-circle pf-m-danger",
message: html`${msg("No workers connected. Background tasks will not run.")}`,
});
}
if (value.filter((w) => !w.versionMatching).length > 0) {
} else if (value.filter((w) => !w.versionMatching).length > 0) {
return Promise.resolve<AdminStatus>({
icon: "fa fa-times-circle pf-m-danger",
message: html`${msg("Worker with incorrect version connected.")}`,
});
} else {
return Promise.resolve<AdminStatus>({
icon: "fa fa-check-circle pf-m-success",
});
}
return Promise.resolve<AdminStatus>({
icon: "fa fa-check-circle pf-m-success",
});
}
renderValue() {

View File

@ -127,7 +127,7 @@ export class SyncStatusChart extends AKChart<SummarizedSyncStatus[]> {
msg("LDAP Source"),
),
];
this.centerText = statuses.reduce((total, el) => total + el.total, 0).toString();
this.centerText = statuses.reduce((total, el) => (total += el.total), 0).toString();
return statuses;
}

View File

@ -6,26 +6,26 @@ import { html } from "lit";
import "../AdminSettingsFooterLinks.js";
describe("ak-admin-settings-footer-link", () => {
afterEach(() => {
return browser.execute(() => {
document.body.querySelector("ak-admin-settings-footer-link")?.remove();
if ("_$litPart$" in document.body) {
delete document.body._$litPart$;
afterEach(async () => {
await browser.execute(async () => {
await document.body.querySelector("ak-admin-settings-footer-link")?.remove();
if (document.body["_$litPart$"]) {
// @ts-expect-error expression of type '"_$litPart$"' is added by Lit
await delete document.body["_$litPart$"];
}
});
});
it("should render an empty control", async () => {
render(html`<ak-admin-settings-footer-link name="link"></ak-admin-settings-footer-link>`);
const link = $("ak-admin-settings-footer-link");
const link = await $("ak-admin-settings-footer-link");
await expect(await link.getProperty("isValid")).toStrictEqual(false);
await expect(await link.getProperty("toJson")).toEqual({ name: "", href: "" });
});
it("should not be valid if just a name is filled in", async () => {
render(html`<ak-admin-settings-footer-link name="link"></ak-admin-settings-footer-link>`);
const link = $("ak-admin-settings-footer-link");
const link = await $("ak-admin-settings-footer-link");
await link.$('input[name="name"]').setValue("foo");
await expect(await link.getProperty("isValid")).toStrictEqual(false);
await expect(await link.getProperty("toJson")).toEqual({ name: "foo", href: "" });
@ -33,7 +33,7 @@ describe("ak-admin-settings-footer-link", () => {
it("should be valid if just a URL is filled in", async () => {
render(html`<ak-admin-settings-footer-link name="link"></ak-admin-settings-footer-link>`);
const link = $("ak-admin-settings-footer-link");
const link = await $("ak-admin-settings-footer-link");
await link.$('input[name="href"]').setValue("https://foo.com");
await expect(await link.getProperty("isValid")).toStrictEqual(true);
await expect(await link.getProperty("toJson")).toEqual({
@ -44,7 +44,7 @@ describe("ak-admin-settings-footer-link", () => {
it("should be valid if both are filled in", async () => {
render(html`<ak-admin-settings-footer-link name="link"></ak-admin-settings-footer-link>`);
const link = $("ak-admin-settings-footer-link");
const link = await $("ak-admin-settings-footer-link");
await link.$('input[name="name"]').setValue("foo");
await link.$('input[name="href"]').setValue("https://foo.com");
await expect(await link.getProperty("isValid")).toStrictEqual(true);
@ -56,7 +56,7 @@ describe("ak-admin-settings-footer-link", () => {
it("should not be valid if the URL is not valid", async () => {
render(html`<ak-admin-settings-footer-link name="link"></ak-admin-settings-footer-link>`);
const link = $("ak-admin-settings-footer-link");
const link = await $("ak-admin-settings-footer-link");
await link.$('input[name="name"]').setValue("foo");
await link.$('input[name="href"]').setValue("never://foo.com");
await expect(await link.getProperty("toJson")).toEqual({

View File

@ -79,7 +79,7 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
});
}
if (this.can(CapabilitiesEnum.CanSaveMedia)) {
const icon = this.getFormFiles().metaIcon;
const icon = this.getFormFiles()["metaIcon"];
if (icon || this.clearIcon) {
await new CoreApi(DEFAULT_CONFIG).coreApplicationsSetIconCreate({
slug: app.slug,
@ -117,7 +117,7 @@ export class ApplicationForm extends WithCapabilitiesConfig(ModelForm<Applicatio
if (!(ev instanceof InputEvent) || !ev.target) {
return;
}
this.clearIcon = Boolean((ev.target as HTMLInputElement).checked);
this.clearIcon = !!(ev.target as HTMLInputElement).checked;
}
renderForm(): TemplateResult {

View File

@ -6,7 +6,7 @@ import "@goauthentik/elements/forms/HorizontalFormElement";
import { ModelForm } from "@goauthentik/elements/forms/ModelForm";
import "@goauthentik/elements/forms/Radio";
import "@goauthentik/elements/forms/SearchSelect";
import * as YAML from "yaml";
import YAML from "yaml";
import { msg } from "@lit/localize";
import { CSSResult } from "lit";
@ -31,8 +31,9 @@ export class ApplicationEntitlementForm extends ModelForm<ApplicationEntitlement
getSuccessMessage(): string {
if (this.instance?.pbmUuid) {
return msg("Successfully updated entitlement.");
} else {
return msg("Successfully created entitlement.");
}
return msg("Successfully created entitlement.");
}
static get styles(): CSSResult[] {
@ -48,10 +49,11 @@ export class ApplicationEntitlementForm extends ModelForm<ApplicationEntitlement
pbmUuid: this.instance.pbmUuid || "",
applicationEntitlementRequest: data,
});
} else {
return new CoreApi(DEFAULT_CONFIG).coreApplicationEntitlementsCreate({
applicationEntitlementRequest: data,
});
}
return new CoreApi(DEFAULT_CONFIG).coreApplicationEntitlementsCreate({
applicationEntitlementRequest: data,
});
}
renderForm(): TemplateResult {

View File

@ -1,7 +1,7 @@
import { styles } from "@goauthentik/admin/applications/wizard/ApplicationWizardFormStepStyles.css.js";
import { WizardStep } from "@goauthentik/components/ak-wizard/WizardStep.js";
import {
NavigationUpdate,
NavigationEventInit,
WizardNavigationEvent,
WizardUpdateEvent,
} from "@goauthentik/components/ak-wizard/events";
@ -14,9 +14,9 @@ import { property, query } from "lit/decorators.js";
import { ValidationError } from "@goauthentik/api";
import {
ApplicationTransactionValidationError,
type ApplicationWizardState,
type ApplicationWizardStateUpdate,
ExtendedValidationError,
} from "./types";
export class ApplicationWizardStep extends WizardStep {
@ -48,7 +48,7 @@ export class ApplicationWizardStep extends WizardStep {
}
protected removeErrors(
keyToDelete: keyof ExtendedValidationError,
keyToDelete: keyof ApplicationTransactionValidationError,
): ValidationError | undefined {
if (!this.wizard.errors) {
return undefined;
@ -71,7 +71,7 @@ export class ApplicationWizardStep extends WizardStep {
public handleUpdate(
update?: ApplicationWizardStateUpdate,
destination?: string,
enable?: NavigationUpdate,
enable?: NavigationEventInit,
) {
// Inform ApplicationWizard of content state
if (update) {

View File

@ -15,6 +15,7 @@ import {
ProviderModelEnum,
ProxyMode,
ProxyProvider,
RACProvider,
RadiusProvider,
RedirectURI,
SAMLProvider,
@ -50,8 +51,9 @@ function renderRadiusOverview(rawProvider: OneOfProvider) {
]);
}
function renderRACOverview(_rawProvider: OneOfProvider) {
// const _provider = rawProvider as RACProvider;
function renderRACOverview(rawProvider: OneOfProvider) {
// @ts-expect-error TS6133
const _provider = rawProvider as RACProvider;
}
function formatRedirectUris(uris: RedirectURI[] = []) {

View File

@ -1,13 +1,14 @@
import { policyOptions } from "@goauthentik/admin/applications/PolicyOptions.js";
import { ApplicationWizardStep } from "@goauthentik/admin/applications/wizard/ApplicationWizardStep.js";
import "@goauthentik/admin/applications/wizard/ak-wizard-title.js";
import { isSlug, isURLInput } from "@goauthentik/common/utils.js";
import { isSlug } from "@goauthentik/common/utils.js";
import { camelToSnake } from "@goauthentik/common/utils.js";
import "@goauthentik/components/ak-radio-input";
import "@goauthentik/components/ak-slug-input";
import "@goauthentik/components/ak-switch-input";
import "@goauthentik/components/ak-text-input";
import { type NavigableButton, type WizardButton } from "@goauthentik/components/ak-wizard/types";
import { type KeyUnknown } from "@goauthentik/elements/forms/Form";
import "@goauthentik/elements/forms/FormGroup";
import "@goauthentik/elements/forms/HorizontalFormElement";
@ -20,25 +21,13 @@ import { type ApplicationRequest } from "@goauthentik/api";
import { ApplicationWizardStateUpdate, ValidationRecord } from "../types";
/**
* Plucks the specified keys from an object, trimming their values if they are strings.
*
* @template T - The type of the input object.
* @template K - The keys to be plucked from the input object.
*
* @param {T} input - The input object.
* @param {Array<K>} keys - The keys to be plucked from the input object.
*/
function trimMany<T extends object, K extends keyof T>(input: T, keys: Array<K>): Pick<T, K> {
const result: Partial<T> = {};
const autoTrim = (v: unknown) => (typeof v === "string" ? v.trim() : v);
for (const key of keys) {
const value = input[key];
result[key] = (typeof value === "string" ? value.trim() : value) as T[K];
}
const trimMany = (o: KeyUnknown, vs: string[]) =>
Object.fromEntries(vs.map((v) => [v, autoTrim(o[v])]));
return result as Pick<T, K>;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const isStr = (v: any): v is string => typeof v === "string";
@customElement("ak-application-wizard-application-step")
export class ApplicationWizardApplicationStep extends ApplicationWizardStep {
@ -48,7 +37,7 @@ export class ApplicationWizardApplicationStep extends ApplicationWizardStep {
errors = new Map<string, string>();
@query("form#applicationform")
declare form: HTMLFormElement;
form!: HTMLFormElement;
constructor() {
super();
@ -65,34 +54,27 @@ export class ApplicationWizardApplicationStep extends ApplicationWizardStep {
}
get buttons(): WizardButton[] {
return [
// ---
{ kind: "next", destination: "provider-choice" },
{ kind: "cancel" },
];
return [{ kind: "next", destination: "provider-choice" }, { kind: "cancel" }];
}
get valid() {
this.errors = new Map();
const values = trimMany(this.formValues ?? {}, ["metaLaunchUrl", "name", "slug"]);
const trimmed = trimMany((this.formValues || {}) as Partial<ApplicationRequest>, [
"name",
"slug",
"metaLaunchUrl",
]);
if (!trimmed.name) {
if (values["name"] === "") {
this.errors.set("name", msg("An application name is required"));
}
if (!isURLInput(trimmed.metaLaunchUrl)) {
if (
!(
isStr(values["metaLaunchUrl"]) &&
(values["metaLaunchUrl"] === "" || URL.canParse(values["metaLaunchUrl"]))
)
) {
this.errors.set("metaLaunchUrl", msg("Not a valid URL"));
}
if (!isSlug(trimmed.slug)) {
if (!(isStr(values["slug"]) && values["slug"] !== "" && isSlug(values["slug"]))) {
this.errors.set("slug", msg("Not a valid slug"));
}
return this.errors.size === 0;
}
@ -100,39 +82,27 @@ export class ApplicationWizardApplicationStep extends ApplicationWizardStep {
if (button.kind === "next") {
if (!this.valid) {
this.handleEnabling({
disabled: [
// ---
"provider-choice",
"provider",
"bindings",
"submit",
],
disabled: ["provider-choice", "provider", "bindings", "submit"],
});
return;
}
const app: Partial<ApplicationRequest> = this.formValues as Partial<ApplicationRequest>;
let payload: ApplicationWizardStateUpdate = {
app: this.formValues,
errors: this.removeErrors("app"),
};
if (app.name && (this.wizard.provider?.name ?? "").trim() === "") {
payload = {
...payload,
provider: { name: `Provider for ${app.name}` },
};
}
this.handleUpdate(payload, button.destination, {
enable: "provider-choice",
});
return;
}
super.handleButton(button);
}
@ -211,7 +181,6 @@ export class ApplicationWizardApplicationStep extends ApplicationWizardStep {
if (!(this.wizard.app && this.wizard.errors)) {
throw new Error("Application Step received uninitialized wizard context.");
}
return this.renderForm(
this.wizard.app as ApplicationRequest,
this.wizard.errors?.app ?? {},

View File

@ -45,7 +45,7 @@ export class ApplicationWizardEditBindingStep extends ApplicationWizardStep {
hide = true;
@query("form#bindingform")
declare form: HTMLFormElement;
form!: HTMLFormElement;
@query(".policy-search-select")
searchSelect!: SearchSelectBase<Policy> | SearchSelectBase<Group> | SearchSelectBase<User>;

View File

@ -1,9 +1,10 @@
import "@goauthentik/admin/applications/wizard/ak-wizard-title.js";
import { DEFAULT_CONFIG } from "@goauthentik/common/api/config";
import { EVENT_REFRESH } from "@goauthentik/common/constants";
import { parseAPIError } from "@goauthentik/common/errors";
import { parseAPIResponseError } from "@goauthentik/common/errors/network";
import { WizardNavigationEvent } from "@goauthentik/components/ak-wizard/events.js";
import { type WizardButton } from "@goauthentik/components/ak-wizard/types";
import { showAPIErrorMessage } from "@goauthentik/elements/messages/MessageContainer";
import { CustomEmitterElement } from "@goauthentik/elements/utils/eventEmitter";
import { P, match } from "ts-pattern";
@ -30,10 +31,11 @@ import {
type TransactionApplicationRequest,
type TransactionApplicationResponse,
type TransactionPolicyBindingRequest,
instanceOfValidationError,
} from "@goauthentik/api";
import { ApplicationWizardStep } from "../ApplicationWizardStep.js";
import { ExtendedValidationError, OneOfProvider } from "../types.js";
import { OneOfProvider, isApplicationTransactionValidationError } from "../types.js";
import { providerRenderers } from "./SubmitStepOverviewRenderers.js";
const _submitStates = ["reviewing", "running", "submitted"] as const;
@ -131,39 +133,46 @@ export class ApplicationWizardSubmitStep extends CustomEmitterElement(Applicatio
this.state = "running";
return (
new CoreApi(DEFAULT_CONFIG)
.coreTransactionalApplicationsUpdate({
transactionApplicationRequest: request,
})
.then((_response: TransactionApplicationResponse) => {
this.dispatchCustomEvent(EVENT_REFRESH);
this.state = "submitted";
})
return new CoreApi(DEFAULT_CONFIG)
.coreTransactionalApplicationsUpdate({
transactionApplicationRequest: request,
})
.then((_response: TransactionApplicationResponse) => {
this.dispatchCustomEvent(EVENT_REFRESH);
this.state = "submitted";
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
.catch(async (resolution: any) => {
const errors = (await parseAPIError(
await resolution,
)) as ExtendedValidationError;
.catch(async (error) => {
const parsedError = await parseAPIResponseError(error);
// THIS is a really gross special case; if the user is duplicating the name of
// an existing provider, the error appears on the `app` (!) error object. We
// have to move that to the `provider.name` error field so it shows up in the
// right place.
if (Array.isArray(errors?.app?.provider)) {
const providerError = errors.app.provider;
errors.provider = errors.provider ?? {};
errors.provider.name = providerError;
delete errors.app.provider;
if (Object.keys(errors.app).length === 0) {
delete errors.app;
if (!instanceOfValidationError(parsedError)) {
showAPIErrorMessage(parsedError);
return;
}
if (isApplicationTransactionValidationError(parsedError)) {
// THIS is a really gross special case; if the user is duplicating the name of an existing provider, the error appears on the `app` (!) error object.
// We have to move that to the `provider.name` error field so it shows up in the right place.
if (Array.isArray(parsedError.app?.provider)) {
const providerError = parsedError.app.provider;
parsedError.provider = {
...parsedError.provider,
name: providerError,
};
delete parsedError.app.provider;
if (Object.keys(parsedError.app).length === 0) {
delete parsedError.app;
}
}
this.handleUpdate({ errors });
this.state = "reviewing";
})
);
}
this.handleUpdate({ errors: parsedError });
this.state = "reviewing";
});
}
override handleButton(button: WizardButton) {
@ -225,22 +234,20 @@ export class ApplicationWizardSubmitStep extends CustomEmitterElement(Applicatio
}
renderError() {
if (Object.keys(this.wizard.errors).length === 0) {
return nothing;
}
const { errors } = this.wizard;
if (Object.keys(errors).length === 0) return nothing;
const navTo = (step: string) => () => this.dispatchEvent(new WizardNavigationEvent(step));
const errors = this.wizard.errors;
return html` <hr class="pf-c-divider" />
${match(errors as ExtendedValidationError)
${match(errors)
.with(
{ app: P.nonNullable },
() =>
html`<p>${msg("There was an error in the application.")}</p>
<p>
<a @click=${navTo("application")}
>${msg("Review the application.")}</a
>
<a @click=${WizardNavigationEvent.toListener(this, "application")}>
${msg("Review the application.")}
</a>
</p>`,
)
.with(
@ -248,13 +255,20 @@ export class ApplicationWizardSubmitStep extends CustomEmitterElement(Applicatio
() =>
html`<p>${msg("There was an error in the provider.")}</p>
<p>
<a @click=${navTo("provider")}>${msg("Review the provider.")}</a>
<a @click=${WizardNavigationEvent.toListener(this, "provider")}
>${msg("Review the provider.")}</a
>
</p>`,
)
.with(
{ detail: P.nonNullable },
() =>
`<p>${msg("There was an error. Please go back and review the application.")}: ${errors.detail}</p>`,
html`<p>
${msg(
"There was an error. Please go back and review the application.",
)}:
${errors.detail}
</p>`,
)
.with(
{
@ -264,7 +278,7 @@ export class ApplicationWizardSubmitStep extends CustomEmitterElement(Applicatio
html`<p>${msg("There was an error:")}:</p>
<ul>
${(errors.nonFieldErrors ?? []).map(
(e: string) => html`<li>${e}</li>`,
(reason) => html`<li>${reason}</li>`,
)}
</ul>
<p>${msg("Please go back and review the application.")}</p>`,

View File

@ -9,7 +9,7 @@ import { customElement, state } from "lit/decorators.js";
import { OAuth2ProviderRequest, SourcesApi } from "@goauthentik/api";
import { type OAuth2Provider, type PaginatedOAuthSourceList } from "@goauthentik/api";
import { ExtendedValidationError } from "../../types.js";
import { ApplicationTransactionValidationError } from "../../types.js";
import { ApplicationWizardProviderForm } from "./ApplicationWizardProviderForm.js";
@customElement("ak-application-wizard-provider-for-oauth")
@ -34,7 +34,7 @@ export class ApplicationWizardOauth2ProviderForm extends ApplicationWizardProvid
});
}
renderForm(provider: OAuth2Provider, errors: ExtendedValidationError) {
renderForm(provider: OAuth2Provider, errors: ApplicationTransactionValidationError) {
const showClientSecretCallback = (show: boolean) => {
this.showClientSecret = show;
};

View File

@ -22,7 +22,7 @@ export class ApplicationWizardProviderSamlForm extends ApplicationWizardProvider
const setHasSigningKp = (ev: InputEvent) => {
const target = ev.target as AkCryptoCertificateSearch;
if (!target) return;
this.hasSigningKp = Boolean(target.selectedKeypair);
this.hasSigningKp = !!target.selectedKeypair;
};
return html` <ak-wizard-title>${this.label}</ak-wizard-title>

View File

@ -25,16 +25,30 @@ export type OneOfProvider =
export type ValidationRecord = { [key: string]: string[] };
// TODO: Elf, extend this type and apply it to every object in the wizard. Then run
// the type-checker again.
export type ExtendedValidationError = ValidationError & {
/**
* An error that occurs during the creation or modification of an application.
*
* @todo (Elf) Extend this type to include all possible errors that can occur during the creation or modification of an application.
*/
export interface ApplicationTransactionValidationError extends ValidationError {
app?: ValidationRecord;
provider?: ValidationRecord;
bindings?: ValidationRecord;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
detail?: any;
};
detail?: unknown;
}
/**
* Type-guard to determine if an API response is shaped like an {@linkcode ApplicationTransactionValidationError}.
*/
export function isApplicationTransactionValidationError(
error: ValidationError,
): error is ApplicationTransactionValidationError {
if ("app" in error) return true;
if ("provider" in error) return true;
if ("bindings" in error) return true;
return false;
}
// We use the PolicyBinding instead of the PolicyBindingRequest here, because that gives us a slot
// in which to preserve the retrieved policy, group, or user object from the SearchSelect used to
@ -49,7 +63,7 @@ export interface ApplicationWizardState {
proxyMode: ProxyMode;
bindings: PolicyBinding[];
currentBinding: number;
errors: ExtendedValidationError;
errors: ValidationError | ApplicationTransactionValidationError;
}
export interface ApplicationWizardStateUpdate {

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